Skip to content

Commit 31793da

Browse files
committed
feat(account): add delete confirmation dialog and improve notification center UI
- Add confirmation dialog before deleting read notifications - Implement delete in progress UI blocking - Improve app bar actions by disabling buttons when deleting - Refactor UI using BlocBuilder for better state management
1 parent fa96137 commit 31793da

File tree

1 file changed

+147
-128
lines changed

1 file changed

+147
-128
lines changed

lib/account/view/in_app_notification_center_page.dart

Lines changed: 147 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -52,140 +52,159 @@ class _InAppNotificationCenterPageState
5252
Widget build(BuildContext context) {
5353
final l10n = AppLocalizationsX(context).l10n;
5454

55-
return Scaffold(
56-
appBar: AppBar(
57-
title: Text(l10n.notificationCenterPageTitle),
58-
actions: [
59-
BlocBuilder<
60-
InAppNotificationCenterBloc,
61-
InAppNotificationCenterState
62-
>(
63-
builder: (context, state) {
64-
final hasUnread = state.notifications.any((n) => !n.isRead);
65-
return IconButton(
66-
onPressed: hasUnread
67-
? () {
68-
context.read<InAppNotificationCenterBloc>().add(
69-
const InAppNotificationCenterMarkAllAsRead(),
70-
);
71-
}
72-
: null,
73-
icon: const Icon(Icons.done_all),
74-
tooltip: l10n.notificationCenterMarkAllAsReadButton,
75-
);
76-
},
77-
),
78-
BlocBuilder<
79-
InAppNotificationCenterBloc,
80-
InAppNotificationCenterState
81-
>(
82-
builder: (context, state) {
83-
return IconButton(
84-
tooltip: l10n.deleteReadNotificationsButtonTooltip,
85-
icon: const Icon(Icons.delete_sweep_outlined),
86-
onPressed: state.hasReadItemsInCurrentTab
87-
? () async {
88-
final confirmed = await showDialog<bool>(
89-
context: context,
90-
builder: (context) => AlertDialog(
91-
title: Text(l10n.deleteConfirmationDialogTitle),
92-
content: Text(
93-
l10n.deleteReadNotificationsDialogContent,
94-
),
95-
actions: [
96-
TextButton(
97-
onPressed: () => Navigator.pop(context, false),
98-
child: Text(l10n.cancelButtonLabel),
99-
),
100-
TextButton(
101-
onPressed: () => Navigator.pop(context, true),
102-
child: Text(l10n.deleteButtonLabel),
55+
return BlocBuilder<
56+
InAppNotificationCenterBloc,
57+
InAppNotificationCenterState
58+
>(
59+
builder: (context, state) {
60+
final isDeleting =
61+
state.status == InAppNotificationCenterStatus.deleting;
62+
63+
return WillPopScope(
64+
onWillPop: () async => !isDeleting,
65+
child: Stack(
66+
children: [
67+
Scaffold(
68+
appBar: AppBar(
69+
title: Text(l10n.notificationCenterPageTitle),
70+
actions: [
71+
IconButton(
72+
onPressed:
73+
!isDeleting &&
74+
state.notifications.any((n) => !n.isRead)
75+
? () {
76+
context.read<InAppNotificationCenterBloc>().add(
77+
const InAppNotificationCenterMarkAllAsRead(),
78+
);
79+
}
80+
: null,
81+
icon: const Icon(Icons.done_all),
82+
tooltip: l10n.notificationCenterMarkAllAsReadButton,
83+
),
84+
IconButton(
85+
tooltip: l10n.deleteReadNotificationsButtonTooltip,
86+
icon: const Icon(Icons.delete_sweep_outlined),
87+
onPressed: !isDeleting && state.hasReadItemsInCurrentTab
88+
? () async {
89+
final confirmed = await showDialog<bool>(
90+
context: context,
91+
builder: (context) => AlertDialog(
92+
title: Text(
93+
l10n.deleteConfirmationDialogTitle,
94+
),
95+
content: Text(
96+
l10n.deleteReadNotificationsDialogContent,
97+
),
98+
actions: [
99+
TextButton(
100+
onPressed: () =>
101+
Navigator.pop(context, false),
102+
child: Text(l10n.cancelButtonLabel),
103+
),
104+
TextButton(
105+
onPressed: () =>
106+
Navigator.pop(context, true),
107+
child: Text(l10n.deleteButtonLabel),
108+
),
109+
],
110+
),
111+
);
112+
if (confirmed == true && context.mounted) {
113+
context.read<InAppNotificationCenterBloc>().add(
114+
const InAppNotificationCenterReadItemsDeleted(),
115+
);
116+
}
117+
}
118+
: null,
119+
),
120+
],
121+
bottom: TabBar(
122+
controller: _tabController,
123+
tabs: [
124+
Tab(text: l10n.notificationCenterTabBreakingNews),
125+
Tab(text: l10n.notificationCenterTabDigests),
126+
],
127+
),
128+
),
129+
body:
130+
BlocConsumer<
131+
InAppNotificationCenterBloc,
132+
InAppNotificationCenterState
133+
>(
134+
listener: (context, state) {
135+
if (state.status ==
136+
InAppNotificationCenterStatus.failure &&
137+
state.error != null) {
138+
ScaffoldMessenger.of(context)
139+
..hideCurrentSnackBar()
140+
..showSnackBar(
141+
SnackBar(
142+
content: Text(state.error!.message),
143+
backgroundColor: Theme.of(
144+
context,
145+
).colorScheme.error,
103146
),
104-
],
105-
),
106-
);
107-
if (confirmed == true && context.mounted) {
108-
context.read<InAppNotificationCenterBloc>().add(
109-
const InAppNotificationCenterReadItemsDeleted(),
147+
);
148+
}
149+
},
150+
builder: (context, state) {
151+
if (state.status ==
152+
InAppNotificationCenterStatus.loading &&
153+
state.breakingNewsNotifications.isEmpty &&
154+
state.digestNotifications.isEmpty) {
155+
return LoadingStateWidget(
156+
icon: Icons.notifications_none_outlined,
157+
headline: l10n.notificationCenterLoadingHeadline,
158+
subheadline:
159+
l10n.notificationCenterLoadingSubheadline,
110160
);
111161
}
112-
}
113-
: null,
114-
);
115-
},
116-
),
117-
],
118-
bottom: TabBar(
119-
controller: _tabController,
120-
tabs: [
121-
Tab(text: l10n.notificationCenterTabBreakingNews),
122-
Tab(text: l10n.notificationCenterTabDigests),
123-
],
124-
),
125-
),
126-
body:
127-
BlocConsumer<
128-
InAppNotificationCenterBloc,
129-
InAppNotificationCenterState
130-
>(
131-
listener: (context, state) {
132-
if (state.status == InAppNotificationCenterStatus.failure &&
133-
state.error != null) {
134-
ScaffoldMessenger.of(context)
135-
..hideCurrentSnackBar()
136-
..showSnackBar(
137-
SnackBar(
138-
content: Text(state.error!.message),
139-
backgroundColor: Theme.of(context).colorScheme.error,
140-
),
141-
);
142-
}
143-
},
144-
builder: (context, state) {
145-
if (state.status == InAppNotificationCenterStatus.loading &&
146-
state.breakingNewsNotifications.isEmpty &&
147-
state.digestNotifications.isEmpty) {
148-
return LoadingStateWidget(
149-
icon: Icons.notifications_none_outlined,
150-
headline: l10n.notificationCenterLoadingHeadline,
151-
subheadline: l10n.notificationCenterLoadingSubheadline,
152-
);
153-
}
154162

155-
if (state.status == InAppNotificationCenterStatus.failure &&
156-
state.breakingNewsNotifications.isEmpty &&
157-
state.digestNotifications.isEmpty) {
158-
return FailureStateWidget(
159-
exception:
160-
state.error ??
161-
OperationFailedException(
162-
l10n.notificationCenterFailureHeadline,
163-
),
164-
onRetry: () {
165-
context.read<InAppNotificationCenterBloc>().add(
166-
const InAppNotificationCenterSubscriptionRequested(),
167-
);
168-
},
169-
);
170-
}
163+
if (state.status ==
164+
InAppNotificationCenterStatus.failure &&
165+
state.breakingNewsNotifications.isEmpty &&
166+
state.digestNotifications.isEmpty) {
167+
return FailureStateWidget(
168+
exception:
169+
state.error ??
170+
OperationFailedException(
171+
l10n.notificationCenterFailureHeadline,
172+
),
173+
onRetry: () {
174+
context.read<InAppNotificationCenterBloc>().add(
175+
const InAppNotificationCenterSubscriptionRequested(),
176+
);
177+
},
178+
);
179+
}
171180

172-
return TabBarView(
173-
controller: _tabController,
174-
children: [
175-
_NotificationList(
176-
status: state.status,
177-
notifications: state.breakingNewsNotifications,
178-
hasMore: state.breakingNewsHasMore,
179-
),
180-
_NotificationList(
181-
status: state.status,
182-
notifications: state.digestNotifications,
183-
hasMore: state.digestHasMore,
184-
),
185-
],
186-
);
187-
},
181+
return TabBarView(
182+
controller: _tabController,
183+
children: [
184+
_NotificationList(
185+
status: state.status,
186+
notifications: state.breakingNewsNotifications,
187+
hasMore: state.breakingNewsHasMore,
188+
),
189+
_NotificationList(
190+
status: state.status,
191+
notifications: state.digestNotifications,
192+
hasMore: state.digestHasMore,
193+
),
194+
],
195+
);
196+
},
197+
),
198+
),
199+
if (isDeleting)
200+
Container(
201+
color: Colors.black.withOpacity(0.5),
202+
child: const Center(child: CircularProgressIndicator()),
203+
),
204+
],
188205
),
206+
);
207+
},
189208
);
190209
}
191210
}

0 commit comments

Comments
 (0)