♻️ Refactored all ScaffoldMessager to use unifined snackbar API

This commit is contained in:
2025-11-22 18:42:12 +08:00
parent f50a19f573
commit 5deb910fa4
13 changed files with 36 additions and 111 deletions

View File

@@ -1340,5 +1340,6 @@
"orCreateWith": "Or\ncreate with", "orCreateWith": "Or\ncreate with",
"unindexedFiles": "Unindexed files", "unindexedFiles": "Unindexed files",
"folder": "Folder", "folder": "Folder",
"clearCompleted": "Clear Completed" "clearCompleted": "Clear Completed",
"contentCantEmpty": "Content cannot be empty"
} }

View File

@@ -384,9 +384,7 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
icon: const Icon(Symbols.content_copy, size: 16), icon: const Icon(Symbols.content_copy, size: 16),
onPressed: () { onPressed: () {
Clipboard.setData(ClipboardData(text: value)); Clipboard.setData(ClipboardData(text: value));
ScaffoldMessenger.of(context).showSnackBar( showSnackBar('copiedToClipboard'.tr());
SnackBar(content: Text('copiedToClipboard'.tr())),
);
}, },
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
constraints: const BoxConstraints(), constraints: const BoxConstraints(),

View File

@@ -5,6 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/poll.dart'; import 'package:island/models/poll.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/screens/poll/poll_editor.dart'; import 'package:island/screens/poll/poll_editor.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/poll/poll_feedback.dart'; import 'package:island/widgets/poll/poll_feedback.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
@@ -234,19 +235,9 @@ class _CreatorPollItem extends HookConsumerWidget {
'/sphere/polls/${pollWithStats.id}', '/sphere/polls/${pollWithStats.id}',
); );
ref.invalidate(pollListNotifierProvider(pubName)); ref.invalidate(pollListNotifierProvider(pubName));
if (context.mounted) { showSnackBar('Poll deleted successfully');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Poll deleted successfully'),
),
);
}
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to delete poll')),
);
}
} }
} }
}, },

View File

@@ -7,6 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/publication_site.dart'; import 'package:island/models/publication_site.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/screens/creators/sites/site_edit.dart'; import 'package:island/screens/creators/sites/site_edit.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/app_scaffold.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -224,21 +225,9 @@ class _CreatorSiteItem extends HookConsumerWidget {
final client = ref.read(apiClientProvider); final client = ref.read(apiClientProvider);
await client.delete('/zone/sites/${site.id}'); await client.delete('/zone/sites/${site.id}');
ref.invalidate(siteListNotifierProvider(pubName)); ref.invalidate(siteListNotifierProvider(pubName));
if (context.mounted) { showSnackBar('Site deleted successfully');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Site deleted successfully'),
),
);
}
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Failed to delete site'),
),
);
}
} }
} }
}, },

View File

@@ -29,14 +29,11 @@ void showSnackBar(String message, {SnackBarAction? action}) {
), ),
), ),
), ),
curve: Curves.easeInOut,
snackBarPosition: SnackBarPosition.bottom, snackBarPosition: SnackBarPosition.bottom,
); );
} }
void clearSnackBar(BuildContext context) {
ScaffoldMessenger.of(context).clearSnackBars();
}
OverlayEntry? _loadingOverlay; OverlayEntry? _loadingOverlay;
GlobalKey<_FadeOverlayState> _loadingOverlayKey = GlobalKey(); GlobalKey<_FadeOverlayState> _loadingOverlayKey = GlobalKey();

View File

@@ -166,7 +166,6 @@ class MarkdownTextContent extends HookConsumerWidget {
label: 'copyToClipboard'.tr(), label: 'copyToClipboard'.tr(),
onPressed: () { onPressed: () {
Clipboard.setData(ClipboardData(text: href)); Clipboard.setData(ClipboardData(text: href));
clearSnackBar(context);
}, },
), ),
); );

View File

@@ -6,6 +6,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart'; import 'package:island/models/post.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/sheet.dart'; import 'package:island/widgets/content/sheet.dart';
import 'package:island/widgets/post/compose_shared.dart'; import 'package:island/widgets/post/compose_shared.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
@@ -56,9 +57,7 @@ class ComposeEmbedSheet extends HookConsumerWidget {
void saveEmbedView() { void saveEmbedView() {
final uri = uriController.text.trim(); final uri = uriController.text.trim();
if (uri.isEmpty) { if (uri.isEmpty) {
ScaffoldMessenger.of( showSnackBar('embedUriRequired'.tr());
context,
).showSnackBar(SnackBar(content: Text('embedUriRequired'.tr())));
return; return;
} }

View File

@@ -751,12 +751,7 @@ class ComposeLogic {
return post; return post;
} catch (err) { } catch (err) {
// Show error message if context is mounted showErrorAlert(err);
if (context.mounted) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Error: $err')));
}
rethrow; rethrow;
} finally { } finally {
state.submitting.value = false; state.submitting.value = false;

View File

@@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_code_editor/flutter_code_editor.dart'; import 'package:flutter_code_editor/flutter_code_editor.dart';
import 'package:flutter_highlight/themes/monokai-sublime.dart'; import 'package:flutter_highlight/themes/monokai-sublime.dart';
@@ -59,17 +60,9 @@ class FileItem extends HookConsumerWidget {
filePath, filePath,
); );
if (context.mounted) { showSnackBar('Downloaded to $filePath');
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Downloaded to $filePath')));
}
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Failed to download file: $e')));
}
} }
} }
@@ -248,9 +241,7 @@ class FileEditorSheet extends HookConsumerWidget {
final saveFile = useCallback(() async { final saveFile = useCallback(() async {
if (codeController.text.trim().isEmpty) { if (codeController.text.trim().isEmpty) {
ScaffoldMessenger.of(context).showSnackBar( showSnackBar('contentCantEmpty'.tr());
const SnackBar(content: Text('Content cannot be empty')),
);
return; return;
} }
@@ -263,17 +254,11 @@ class FileEditorSheet extends HookConsumerWidget {
.updateFileContent(file.relativePath, codeController.text); .updateFileContent(file.relativePath, codeController.text);
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( showSnackBar('File saved successfully');
const SnackBar(content: Text('File saved successfully')),
);
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Failed to save file: $e')));
}
} finally { } finally {
isSaving.value = false; isSaving.value = false;
} }

View File

@@ -5,6 +5,7 @@ import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/publication_site.dart'; import 'package:island/models/publication_site.dart';
import 'package:island/pods/site_files.dart'; import 'package:island/pods/site_files.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/sheet.dart'; import 'package:island/widgets/content/sheet.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
@@ -121,9 +122,7 @@ class FileUploadDialog extends HookConsumerWidget {
(state) => state['status'] == 'completed', (state) => state['status'] == 'completed',
)) { )) {
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( showSnackBar('All files uploaded successfully');
const SnackBar(content: Text('All files uploaded successfully')),
);
onUploadComplete(); onUploadComplete();
Navigator.of(context).pop(); Navigator.of(context).pop();
} }

View File

@@ -4,6 +4,7 @@ import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/publication_site.dart'; import 'package:island/models/publication_site.dart';
import 'package:island/pods/site_pages.dart'; import 'package:island/pods/site_pages.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/sheet.dart'; import 'package:island/widgets/content/sheet.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
@@ -127,23 +128,15 @@ class PageForm extends HookConsumerWidget {
} }
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( showSnackBar(
SnackBar( page == null
content: Text( ? 'Page created successfully'
page == null : 'Page updated successfully',
? 'Page created successfully'
: 'Page updated successfully',
),
),
); );
Navigator.pop(context); Navigator.pop(context);
} }
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to save page: ${e.toString()}')),
);
}
} finally { } finally {
isLoading.value = false; isLoading.value = false;
} }
@@ -185,17 +178,11 @@ class PageForm extends HookConsumerWidget {
await pagesNotifier.deletePage(page!.id); await pagesNotifier.deletePage(page!.id);
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( showSnackBar('Page deleted successfully');
const SnackBar(content: Text('Page deleted successfully')),
);
Navigator.pop(context); Navigator.pop(context);
} }
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Failed to delete page')),
);
}
} finally { } finally {
isLoading.value = false; isLoading.value = false;
} }

View File

@@ -6,6 +6,7 @@ import 'package:island/models/publication_site.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/screens/creators/sites/site_detail.dart'; import 'package:island/screens/creators/sites/site_detail.dart';
import 'package:island/screens/creators/sites/site_edit.dart'; import 'package:island/screens/creators/sites/site_edit.dart';
import 'package:island/widgets/alert.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
@@ -85,18 +86,11 @@ class SiteActionMenu extends HookConsumerWidget {
final client = ref.read(apiClientProvider); final client = ref.read(apiClientProvider);
await client.delete('/zone/sites/${site.id}'); await client.delete('/zone/sites/${site.id}');
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( showSnackBar('Site deleted successfully');
const SnackBar(content: Text('Site deleted successfully')),
);
// Navigate back to list
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
} catch (e) { } catch (e) {
if (context.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Failed to delete site')),
);
}
} }
} }
break; break;

View File

@@ -3,6 +3,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/wallet.dart'; import 'package:island/models/wallet.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/pods/userinfo.dart'; import 'package:island/pods/userinfo.dart';
import 'package:island/widgets/alert.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@@ -244,20 +245,10 @@ class FundEnvelopeWidget extends HookConsumerWidget {
if (dialogContext.mounted) { if (dialogContext.mounted) {
Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop();
ScaffoldMessenger.of(dialogContext).showSnackBar( showSnackBar('Fund claimed successfully!');
SnackBar(content: Text('Fund claimed successfully!'.tr())),
);
} }
} catch (e) { } catch (e) {
if (dialogContext.mounted) { showErrorAlert(e);
ScaffoldMessenger.of(dialogContext).showSnackBar(
SnackBar(
content: Text('Failed to claim fund: $e'),
backgroundColor:
Theme.of(dialogContext).colorScheme.error,
),
);
}
} }
}, },
), ),