diff --git a/auth/lib/l10n/arb/app_en.arb b/auth/lib/l10n/arb/app_en.arb index 24b298e3d..f6c8c7cc7 100644 --- a/auth/lib/l10n/arb/app_en.arb +++ b/auth/lib/l10n/arb/app_en.arb @@ -434,5 +434,7 @@ "create": "Create", "editTag": "Edit Tag", "deleteTagTitle": "Delete tag?", - "deleteTagMessage": "Are you sure you want to delete this tag? This action is irreversible." + "deleteTagMessage": "Are you sure you want to delete this tag? This action is irreversible.", + "somethingWentWrongUpdateApp": "Something went wrong, please update the app", + "updateNotAvailable": "Update not available" } \ No newline at end of file diff --git a/auth/lib/models/code.dart b/auth/lib/models/code.dart index cdb4eb8be..9f6461ee4 100644 --- a/auth/lib/models/code.dart +++ b/auth/lib/models/code.dart @@ -243,8 +243,7 @@ class Code { other.secret == secret && other.counter == counter && other.type == type && - other.rawData == rawData && - other.display == display; + other.rawData == rawData; } @override @@ -256,8 +255,7 @@ class Code { secret.hashCode ^ type.hashCode ^ counter.hashCode ^ - rawData.hashCode ^ - display.hashCode; + rawData.hashCode; } } diff --git a/auth/lib/ui/code_error_widget.dart b/auth/lib/ui/code_error_widget.dart new file mode 100644 index 000000000..797fd74a1 --- /dev/null +++ b/auth/lib/ui/code_error_widget.dart @@ -0,0 +1,117 @@ +import 'package:ente_auth/ente_theme_data.dart'; +import 'package:ente_auth/l10n/l10n.dart'; +import 'package:ente_auth/services/update_service.dart'; +import 'package:ente_auth/ui/common/gradient_button.dart'; +import 'package:ente_auth/ui/linear_progress_widget.dart'; +import 'package:ente_auth/ui/settings/app_update_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +class CodeErrorWidget extends StatelessWidget { + const CodeErrorWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + height: 132, + width: double.infinity, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.codeCardBackgroundColor, + borderRadius: BorderRadius.circular(8), + ), + margin: const EdgeInsets.only( + left: 16, + right: 16, + bottom: 8, + top: 8, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 3, + child: LinearProgressWidget( + color: Color(0xFFF53434), + fractionOfStorage: 1, + ), + ), + const SizedBox(height: 24), + Row( + children: [ + const SizedBox(width: 8), + const Align( + alignment: Alignment.center, + child: Icon( + Icons.info, + size: 18, + color: Color(0xFFF53434), + ), + ), + const SizedBox(width: 8), + Text( + context.l10n.error, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Color(0xFFF53434), + ), + ), + ], + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + context.l10n.somethingWentWrongUpdateApp, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ), + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + width: 76, + height: 28, + child: GradientButton( + text: context.l10n.update, + fontSize: 10, + onTap: () async { + try { + await UpdateService.instance.shouldUpdate(); + assert( + UpdateService.instance.getLatestVersionInfo() != null, + ); + await showDialog( + context: context, + builder: (BuildContext context) { + return AppUpdateDialog( + UpdateService.instance.getLatestVersionInfo(), + ); + }, + barrierColor: Colors.black.withOpacity(0.85), + ); + } catch (e) { + await Fluttertoast.showToast( + msg: context.l10n.updateNotAvailable, + ); + } + }, + borderWidth: 0.6, + borderRadius: 6, + ), + ), + const SizedBox(width: 6), + ], + ), + ], + ), + ), + ); + } +} diff --git a/auth/lib/ui/common/gradient_button.dart b/auth/lib/ui/common/gradient_button.dart index f3a672d84..b420d59e3 100644 --- a/auth/lib/ui/common/gradient_button.dart +++ b/auth/lib/ui/common/gradient_button.dart @@ -13,12 +13,19 @@ class GradientButton extends StatefulWidget { // padding between the text and icon final double paddingValue; + final double fontSize; + final double borderRadius; + final double borderWidth; + const GradientButton({ super.key, this.onTap, this.text = '', this.iconData, this.paddingValue = 0.0, + this.fontSize = 18, + this.borderRadius = 4, + this.borderWidth = 1, }); @override @@ -34,11 +41,11 @@ class _GradientButtonState extends State { if (widget.iconData == null) { buttonContent = Text( widget.text, - style: const TextStyle( + style: TextStyle( color: Colors.white, fontWeight: FontWeight.w600, fontFamily: 'Inter-SemiBold', - fontSize: 18, + fontSize: widget.fontSize, ), ); } else { @@ -54,11 +61,11 @@ class _GradientButtonState extends State { const Padding(padding: EdgeInsets.symmetric(horizontal: 6)), Text( widget.text, - style: const TextStyle( + style: TextStyle( color: Colors.white, fontWeight: FontWeight.w600, fontFamily: 'Inter-SemiBold', - fontSize: 18, + fontSize: widget.fontSize, ), ), ], @@ -80,7 +87,7 @@ class _GradientButtonState extends State { isTapped = false; }); }, - borderRadius: BorderRadius.circular(16), + borderRadius: BorderRadius.circular(widget.borderRadius), onTap: widget.onTap as void Function()?, child: Stack( children: [ @@ -122,9 +129,9 @@ class _GradientButtonState extends State { ], ), backgroundBlendMode: isTapped ? null : BlendMode.overlay, - border: const GradientBoxBorder( - width: 1, - gradient: LinearGradient( + border: GradientBoxBorder( + width: widget.borderWidth, + gradient: const LinearGradient( colors: [ Color(0xFFB37FEB), Color(0xFF22075E), @@ -133,7 +140,7 @@ class _GradientButtonState extends State { end: Alignment.bottomRight, ), ), - borderRadius: BorderRadius.circular(4), + borderRadius: BorderRadius.circular(widget.borderRadius), ), child: Center(child: buttonContent), ), diff --git a/auth/lib/ui/home_page.dart b/auth/lib/ui/home_page.dart index a51ea9792..2f48b4f6f 100644 --- a/auth/lib/ui/home_page.dart +++ b/auth/lib/ui/home_page.dart @@ -16,6 +16,7 @@ import 'package:ente_auth/services/preference_service.dart'; import 'package:ente_auth/services/user_service.dart'; import 'package:ente_auth/store/code_store.dart'; import 'package:ente_auth/ui/account/logout_dialog.dart'; +import 'package:ente_auth/ui/code_error_widget.dart'; import 'package:ente_auth/ui/code_widget.dart'; import 'package:ente_auth/ui/common/loading_widget.dart'; import 'package:ente_auth/ui/home/coach_mark_widget.dart'; @@ -335,19 +336,11 @@ class _HomePageState extends State { crossAxisCount: (MediaQuery.sizeOf(context).width ~/ 400) .clamp(1, double.infinity) .toInt(), + padding: const EdgeInsets.only(bottom: 80), itemBuilder: ((context, index) { try { if (_filteredCodes[index].error != null) { - return Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - l10n.sorryUnableToGenCode( - _filteredCodes[index].code?.issuer ?? "", - ), - ), - ), - ); + return const CodeErrorWidget(); } return ClipRect( child: CodeWidget( @@ -381,6 +374,7 @@ class _HomePageState extends State { (MediaQuery.sizeOf(context).width ~/ 400) .clamp(1, double.infinity) .toInt(), + padding: const EdgeInsets.only(bottom: 80), itemBuilder: ((context, index) { final codeState = _filteredCodes[index]; if (codeState.code != null) { @@ -393,14 +387,7 @@ class _HomePageState extends State { "code widget error", codeState.error, ); - return Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - l10n.sorryUnableToGenCode(""), - ), - ), - ); + return const CodeErrorWidget(); } }), itemCount: _filteredCodes.length,