Skip to content

Commit b8912dc

Browse files
committed
feat(notifications): settings part one
1 parent 761d9bd commit b8912dc

File tree

3 files changed

+199
-0
lines changed

3 files changed

+199
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/*
2+
* This file is part of BoxBox (https://github.com/BrightDV/BoxBox).
3+
*
4+
* BoxBox is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* BoxBox is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with BoxBox. If not, see <http://www.gnu.org/licenses/>.
16+
*
17+
* Copyright (c) 2022-2025, BrightDV
18+
*/
19+
20+
import 'package:awesome_notifications/awesome_notifications.dart';
21+
import 'package:flutter/material.dart';
22+
import 'package:hive_flutter/hive_flutter.dart';
23+
import 'package:workmanager/workmanager.dart';
24+
25+
class NotificationsSettingsScreen extends StatefulWidget {
26+
const NotificationsSettingsScreen({super.key});
27+
28+
@override
29+
State<NotificationsSettingsScreen> createState() =>
30+
_NotificationsSettingsScreenState();
31+
}
32+
33+
class _NotificationsSettingsScreenState
34+
extends State<NotificationsSettingsScreen> {
35+
@override
36+
Widget build(BuildContext context) {
37+
bool notificationsEnabled = Hive.box('settings')
38+
.get('notificationsEnabled', defaultValue: false) as bool;
39+
bool sessionNotificationsEnabled = Hive.box('settings')
40+
.get('sessionNotificationsEnabled', defaultValue: false) as bool;
41+
bool newsNotificationsEnabled = Hive.box('settings')
42+
.get('newsNotificationsEnabled', defaultValue: false) as bool;
43+
int refreshInterval =
44+
Hive.box('settings').get('refreshInterval', defaultValue: 6) as int;
45+
Map durations = {
46+
2: '2 hours',
47+
6: '6 hours',
48+
12: '12 hours',
49+
24: '24 hours',
50+
};
51+
52+
return Scaffold(
53+
appBar: AppBar(
54+
title: Text('Notifications'),
55+
backgroundColor: Theme.of(context).colorScheme.onPrimary,
56+
),
57+
body: Column(
58+
children: [
59+
SwitchListTile(
60+
title: Text(
61+
'Enable notifications',
62+
),
63+
value: notificationsEnabled,
64+
onChanged: (bool value) async {
65+
if (value) {
66+
bool isAllowed =
67+
await AwesomeNotifications().isNotificationAllowed();
68+
if (!isAllowed) {
69+
bool isAllowedAfterRequest = await AwesomeNotifications()
70+
.requestPermissionToSendNotifications();
71+
if (isAllowedAfterRequest) {
72+
notificationsEnabled = value;
73+
Hive.box('settings').put('notificationsEnabled', value);
74+
}
75+
} else {
76+
notificationsEnabled = value;
77+
Hive.box('settings').put('notificationsEnabled', value);
78+
}
79+
} else {
80+
await Workmanager().cancelAll();
81+
await AwesomeNotifications().cancelAll();
82+
notificationsEnabled = value;
83+
Hive.box('settings').put('notificationsEnabled', value);
84+
}
85+
setState(() {});
86+
},
87+
),
88+
SwitchListTile(
89+
title: Text(
90+
'Articles notifications',
91+
),
92+
value: newsNotificationsEnabled,
93+
onChanged: notificationsEnabled
94+
? (bool value) async {
95+
if (value) {
96+
await Workmanager().registerPeriodicTask(
97+
'newsLoader',
98+
"Load news in background",
99+
existingWorkPolicy: ExistingWorkPolicy.replace,
100+
frequency: const Duration(seconds: 30),
101+
initialDelay: const Duration(hours: 2),
102+
);
103+
} else {
104+
Workmanager().cancelAll();
105+
}
106+
setState(
107+
() {
108+
newsNotificationsEnabled = value;
109+
Hive.box('settings')
110+
.put('newsNotificationsEnabled', value);
111+
},
112+
);
113+
}
114+
: null,
115+
),
116+
ListTile(
117+
title: Text(
118+
'Refresh interval',
119+
style: TextStyle(),
120+
),
121+
enabled: notificationsEnabled && newsNotificationsEnabled,
122+
//onTap: () {},
123+
trailing: DropdownButton(
124+
value: refreshInterval,
125+
onChanged: notificationsEnabled && newsNotificationsEnabled
126+
? (int? newValue) {
127+
if (newValue != null) {
128+
setState(
129+
() {
130+
refreshInterval = newValue;
131+
Hive.box('settings')
132+
.put('refreshInterval', newValue);
133+
},
134+
);
135+
}
136+
}
137+
: null,
138+
items: <int>[
139+
2,
140+
6,
141+
12,
142+
24,
143+
].map<DropdownMenuItem<int>>(
144+
(int value) {
145+
return DropdownMenuItem<int>(
146+
value: value,
147+
child: Text(
148+
durations[value],
149+
style: TextStyle(
150+
fontSize: 12,
151+
),
152+
),
153+
);
154+
},
155+
).toList(),
156+
),
157+
),
158+
SwitchListTile(
159+
title: Text(
160+
'Sessions notifications',
161+
),
162+
subtitle: Text(
163+
'You need to go to the schedule screen in order to initialize notifications for the next Grand-Prix.',
164+
),
165+
value: sessionNotificationsEnabled,
166+
onChanged: notificationsEnabled
167+
? (bool value) async {
168+
if (!value) {
169+
AwesomeNotifications().cancelAll();
170+
}
171+
setState(
172+
() {
173+
sessionNotificationsEnabled = value;
174+
Hive.box('settings').put(
175+
'sessionNotificationsEnabled',
176+
value,
177+
);
178+
},
179+
);
180+
}
181+
: null,
182+
),
183+
],
184+
),
185+
);
186+
}
187+
}

lib/Screens/Settings/settings.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
5959
leading: Icon(Icons.play_arrow_outlined),
6060
onTap: () => context.pushNamed('player-settings'),
6161
),
62+
ListTile(
63+
title: Text('Notifications'),
64+
leading: Icon(Icons.notifications_outlined),
65+
onTap: () => context.pushNamed('notifications-settings'),
66+
),
6267
ListTile(
6368
title: Text(AppLocalizations.of(context)!.other),
6469
leading: Icon(Icons.miscellaneous_services_outlined),

lib/config/router.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import 'package:boxbox/Screens/MixedNews/mixed_news.dart';
2424
import 'package:boxbox/Screens/Settings/appearance.dart';
2525
import 'package:boxbox/Screens/Settings/custom_home_feed.dart';
2626
import 'package:boxbox/Screens/Settings/mixed_news.dart';
27+
import 'package:boxbox/Screens/Settings/notifications.dart';
2728
import 'package:boxbox/Screens/Settings/other.dart';
2829
import 'package:boxbox/Screens/Settings/player.dart';
2930
import 'package:boxbox/Screens/Settings/server.dart';
@@ -175,6 +176,12 @@ class RouterLocalConfig {
175176
path: 'player',
176177
builder: (context, state) => const PlayerSettingsScreen(),
177178
),
179+
GoRoute(
180+
name: 'notifications-settings',
181+
path: 'notifications',
182+
builder: (context, state) =>
183+
const NotificationsSettingsScreen(),
184+
),
178185
GoRoute(
179186
name: 'other-settings',
180187
path: 'other',

0 commit comments

Comments
 (0)