Offline Support
This commit is contained in:
@@ -57,9 +57,12 @@ class _AnnouncementCommentsSectionState
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Failed to post comment: $e')),
|
||||
);
|
||||
if (isOfflineSaveError(e)) {
|
||||
_controller.clear();
|
||||
showSuccessSnackBar(context, 'Comment saved offline — will sync when connected.');
|
||||
} else {
|
||||
showErrorSnackBar(context, 'Failed to post comment: $e');
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _sending = false);
|
||||
|
||||
@@ -14,6 +14,7 @@ import '../../widgets/app_page_header.dart';
|
||||
import '../../widgets/m3_card.dart';
|
||||
import '../../widgets/profile_avatar.dart';
|
||||
import '../../widgets/responsive_body.dart';
|
||||
import '../../widgets/sync_pending_badge.dart';
|
||||
import 'announcement_comments_section.dart';
|
||||
import 'create_announcement_dialog.dart';
|
||||
|
||||
@@ -317,6 +318,14 @@ class _AnnouncementCardState extends ConsumerState<_AnnouncementCard> {
|
||||
ref.watch(announcementCommentsProvider(widget.announcement.id));
|
||||
final commentCount = commentsAsync.valueOrNull?.length ?? 0;
|
||||
|
||||
// Pending-sync state
|
||||
final pendingNew = ref
|
||||
.watch(offlinePendingAnnouncementsProvider)
|
||||
.any((a) => a.id == widget.announcement.id);
|
||||
final pendingUpdates = ref.watch(offlinePendingAnnouncementUpdatesProvider);
|
||||
final isAnnouncementPending =
|
||||
pendingNew || pendingUpdates.containsKey(widget.announcement.id);
|
||||
|
||||
// Rebuild UI when cooldown is active.
|
||||
if (_inCooldown) {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
@@ -428,9 +437,21 @@ class _AnnouncementCardState extends ConsumerState<_AnnouncementCard> {
|
||||
// Title + Body
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
|
||||
child: Text(
|
||||
widget.announcement.title,
|
||||
style: tt.titleMedium?.copyWith(fontWeight: FontWeight.w600),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.announcement.title,
|
||||
style: tt.titleMedium
|
||||
?.copyWith(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
if (isAnnouncementPending) ...[
|
||||
const SizedBox(width: 8),
|
||||
SyncPendingBadge(isPending: true, compact: true),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
|
||||
@@ -269,7 +269,14 @@ class _CreateAnnouncementContentState
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) showErrorSnackBar(context, 'Failed to save: $e');
|
||||
if (mounted) {
|
||||
if (isOfflineSaveError(e)) {
|
||||
Navigator.of(context).pop();
|
||||
showSuccessSnackBarGlobal('Announcement saved offline — will sync when connected.');
|
||||
} else {
|
||||
showErrorSnackBar(context, 'Failed to save: $e');
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _submitting = false);
|
||||
}
|
||||
@@ -537,7 +544,14 @@ class _BannerSettingsContentState
|
||||
if (mounted) Navigator.of(context).pop();
|
||||
showSuccessSnackBarGlobal('Banner settings saved.');
|
||||
} catch (e) {
|
||||
if (mounted) showErrorSnackBar(context, 'Failed to save: $e');
|
||||
if (mounted) {
|
||||
if (isOfflineSaveError(e)) {
|
||||
Navigator.of(context).pop();
|
||||
showSuccessSnackBarGlobal('Banner settings saved offline — will sync when connected.');
|
||||
} else {
|
||||
showErrorSnackBar(context, 'Failed to save: $e');
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _submitting = false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user