From d932f59f25d3c7b3e833f7b7a4016de7de952b6c Mon Sep 17 00:00:00 2001 From: Thomas SharedInbox Date: Thu, 14 May 2026 20:37:06 +0200 Subject: [PATCH] fix(ui): show all SnackBars for 5 seconds instead of Flutter default 4s Closes #17 Co-Authored-By: Claude Sonnet 4.6 --- lib/ui/screens/account_list_screen.dart | 5 ++++- lib/ui/screens/compose_screen.dart | 21 ++++++++++++++++++--- lib/ui/screens/crash_screen.dart | 13 +++++++++++-- lib/ui/screens/email_detail_screen.dart | 2 ++ lib/ui/screens/email_list_screen.dart | 13 +++++++++++-- lib/ui/screens/sieve_scripts_screen.dart | 14 ++++++++++++-- lib/ui/screens/undo_log_screen.dart | 7 ++++++- lib/ui/widgets/undo_shell.dart | 1 + 8 files changed, 65 insertions(+), 11 deletions(-) diff --git a/lib/ui/screens/account_list_screen.dart b/lib/ui/screens/account_list_screen.dart index 9aaaf18..288c534 100644 --- a/lib/ui/screens/account_list_screen.dart +++ b/lib/ui/screens/account_list_screen.dart @@ -181,7 +181,10 @@ class _AccountTile extends ConsumerWidget { ); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Starting sync verification...')), + const SnackBar( + duration: Duration(seconds: 5), + content: Text('Starting sync verification...'), + ), ); } break; diff --git a/lib/ui/screens/compose_screen.dart b/lib/ui/screens/compose_screen.dart index 6a99df9..df762c4 100644 --- a/lib/ui/screens/compose_screen.dart +++ b/lib/ui/screens/compose_screen.dart @@ -192,7 +192,12 @@ class _ComposeScreenState extends ConsumerState { if (!mounted) return; ScaffoldMessenger.of( context, - ).showSnackBar(SnackBar(content: Text('Failed to open file: $e'))); + ).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text('Failed to open file: $e'), + ), + ); } finally { if (mounted) setState(() => _opening = false); } @@ -206,7 +211,12 @@ class _ComposeScreenState extends ConsumerState { if (_accountId == null) { ScaffoldMessenger.of( context, - ).showSnackBar(const SnackBar(content: Text('Select an account first'))); + ).showSnackBar( + const SnackBar( + duration: Duration(seconds: 5), + content: Text('Select an account first'), + ), + ); return; } setState(() => _sending = true); @@ -243,7 +253,12 @@ class _ComposeScreenState extends ConsumerState { if (!mounted) return; ScaffoldMessenger.of( context, - ).showSnackBar(SnackBar(content: Text('Send failed: $e'))); + ).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text('Send failed: $e'), + ), + ); } finally { if (mounted) setState(() => _sending = false); } diff --git a/lib/ui/screens/crash_screen.dart b/lib/ui/screens/crash_screen.dart index c511479..67acc3b 100644 --- a/lib/ui/screens/crash_screen.dart +++ b/lib/ui/screens/crash_screen.dart @@ -78,7 +78,10 @@ class CrashScreen extends StatelessWidget { await Clipboard.setData(ClipboardData(text: data)); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Copied to clipboard')), + const SnackBar( + duration: Duration(seconds: 5), + content: Text('Copied to clipboard'), + ), ); } }, @@ -105,6 +108,7 @@ class CrashScreen extends StatelessWidget { if (!launched && context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( + duration: Duration(seconds: 5), content: Text('Could not open browser.'), ), ); @@ -113,7 +117,12 @@ class CrashScreen extends StatelessWidget { if (context.mounted) { ScaffoldMessenger.of( context, - ).showSnackBar(SnackBar(content: Text('Error: $e'))); + ).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text('Error: $e'), + ), + ); } } }, diff --git a/lib/ui/screens/email_detail_screen.dart b/lib/ui/screens/email_detail_screen.dart index 63a26ca..0bcbd63 100644 --- a/lib/ui/screens/email_detail_screen.dart +++ b/lib/ui/screens/email_detail_screen.dart @@ -417,6 +417,7 @@ class _EmailDetailScreenState extends ConsumerState { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( + duration: const Duration(seconds: 5), content: Text( 'Snoozed until ${DateFormat('MMM d, HH:mm').format(until)}', ), @@ -430,6 +431,7 @@ class _EmailDetailScreenState extends ConsumerState { if (body.headers.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( + duration: Duration(seconds: 5), content: Text('No headers available. Try re-syncing the email.'), ), ); diff --git a/lib/ui/screens/email_list_screen.dart b/lib/ui/screens/email_list_screen.dart index 1b19993..b18b795 100644 --- a/lib/ui/screens/email_list_screen.dart +++ b/lib/ui/screens/email_list_screen.dart @@ -290,7 +290,10 @@ class _EmailListScreenState extends ConsumerState { } catch (e) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Sync failed: $e')), + SnackBar( + duration: const Duration(seconds: 5), + content: Text('Sync failed: $e'), + ), ); } }, @@ -421,7 +424,12 @@ class _EmailListScreenState extends ConsumerState { if (mailbox == null) { ScaffoldMessenger.of( context, - ).showSnackBar(SnackBar(content: Text(notFoundMessage))); + ).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text(notFoundMessage), + ), + ); return; } final repo = ref.read(emailRepositoryProvider); @@ -579,6 +587,7 @@ class _EmailListScreenState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( + duration: const Duration(seconds: 5), content: Text( 'Snoozed ${ids.length} email${ids.length == 1 ? '' : 's'} until ${DateFormat('MMM d, HH:mm').format(until)}', ), diff --git a/lib/ui/screens/sieve_scripts_screen.dart b/lib/ui/screens/sieve_scripts_screen.dart index b6815ab..6809545 100644 --- a/lib/ui/screens/sieve_scripts_screen.dart +++ b/lib/ui/screens/sieve_scripts_screen.dart @@ -61,7 +61,12 @@ class _SieveScriptsScreenState extends ConsumerState { if (mounted) { ScaffoldMessenger.of( context, - ).showSnackBar(SnackBar(content: Text('Failed to activate: $e'))); + ).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text('Failed to activate: $e'), + ), + ); } } } @@ -94,7 +99,12 @@ class _SieveScriptsScreenState extends ConsumerState { if (mounted) { ScaffoldMessenger.of( context, - ).showSnackBar(SnackBar(content: Text('Failed to delete: $e'))); + ).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text('Failed to delete: $e'), + ), + ); } } } diff --git a/lib/ui/screens/undo_log_screen.dart b/lib/ui/screens/undo_log_screen.dart index 789e893..9a36d9c 100644 --- a/lib/ui/screens/undo_log_screen.dart +++ b/lib/ui/screens/undo_log_screen.dart @@ -86,7 +86,12 @@ class _UndoActionTile extends ConsumerWidget { if (context.mounted) { ScaffoldMessenger.of( context, - ).showSnackBar(const SnackBar(content: Text('Action undone.'))); + ).showSnackBar( + const SnackBar( + duration: Duration(seconds: 5), + content: Text('Action undone.'), + ), + ); } }, child: const Text('Undo'), diff --git a/lib/ui/widgets/undo_shell.dart b/lib/ui/widgets/undo_shell.dart index 78f1ac3..2042927 100644 --- a/lib/ui/widgets/undo_shell.dart +++ b/lib/ui/widgets/undo_shell.dart @@ -29,6 +29,7 @@ class UndoShell extends ConsumerWidget { scaffoldMessenger.clearSnackBars(); scaffoldMessenger.showSnackBar( SnackBar( + duration: const Duration(seconds: 5), content: Text( action.type == UndoType.delete ? '${action.emailIds.length} email(s) moved to Trash'