From 851d6e31af6f9affce458f335f04783bd8fe5946 Mon Sep 17 00:00:00 2001 From: Abynox Date: Mon, 27 Jan 2025 19:49:08 +0100 Subject: [PATCH 1/2] Added theme selector --- lib/main.dart | 55 ++++++++++++++++++++-------- lib/screens/tokens.dart | 43 ++++++++++++++++++++-- lib/services/alarm_list_manager.dart | 9 ++++- 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8819adb..0d73e52 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -32,7 +32,7 @@ Future requestPermissions() async{ } } -void initNotification() async { +void initNotification(AlarmListManager manager) async { FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project @@ -49,16 +49,15 @@ void initNotification() async { macOS: initializationSettingsDarwin, linux: initializationSettingsLinux); await flutterLocalNotificationsPlugin.initialize(initializationSettings, - onDidReceiveNotificationResponse: onDidReceiveNotificationResponse); + onDidReceiveNotificationResponse: (NotificationResponse response) { + onDidReceiveNotificationResponse(response, manager); + }); flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>()?.requestNotificationsPermission(); } -void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) async { - - AlarmListManager manager = AlarmListManager(); - await manager.loadAllFromStorage(); +void onDidReceiveNotificationResponse(NotificationResponse notificationResponse, AlarmListManager manager) async { print("Notification received"); if(notificationResponse.id != null) { print("Notification id owo: ${notificationResponse.id}"); @@ -82,7 +81,9 @@ void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) void main() async { WidgetsFlutterBinding.ensureInitialized(); - initNotification(); + AlarmListManager manager = AlarmListManager(); + await manager.loadAllFromStorage(); + initNotification(manager); if(isAndroid()) { await AndroidAlarmManager.initialize(); await requestPermissions(); @@ -93,10 +94,10 @@ void main() async { @pragma('vm:entry-point') void alarmCallback(int id) async { - AlarmListManager manager = AlarmListManager(); - initNotification(); await manager.loadAllFromStorage(); + + initNotification(manager); manager.getAlarms().forEach((element) { print("Checking alarm"); if(element.active && id ==element.id) { @@ -105,10 +106,32 @@ void alarmCallback(int id) async { }); } -class MyApp extends StatelessWidget { +class MyApp extends StatefulWidget { + final int? alarmId; + const MyApp(this.alarmId, {super.key}); + + @override + State createState() => MyAppState(); + +} + +class MyAppState extends State { int? alarmId; - MyApp(this.alarmId); + ThemeMode themeMode = AlarmListManager.getInstance().settings.theme; + + @override + void initState() { + super.initState(); + alarmId = widget.alarmId; + } + void setThemeMode(ThemeMode themeMode) { + AlarmListManager.getInstance().settings.theme = themeMode; + AlarmListManager.getInstance().saveSettings(); + setState(() { + this.themeMode = themeMode; + }); + } // This widget is the root of your application. @override @@ -119,15 +142,15 @@ class MyApp extends StatelessWidget { return DynamicColorBuilder(builder: (lightColorScheme, darkColorScheme) { return MaterialApp( title: 'ShockAlarm', - theme: ThemeData( + theme: lightColorScheme != null ? ThemeData( useMaterial3: true, colorScheme: lightColorScheme, - ), - darkTheme: ThemeData( + ): ThemeData.light(), + darkTheme: darkColorScheme != null ? ThemeData( useMaterial3: true, colorScheme: darkColorScheme, - ), - themeMode: ThemeMode.system, + ): ThemeData.dark(), + themeMode: themeMode, home: ScreenSelector(manager: manager) ); }); diff --git a/lib/screens/tokens.dart b/lib/screens/tokens.dart index f7efbcd..7161a6e 100644 --- a/lib/screens/tokens.dart +++ b/lib/screens/tokens.dart @@ -2,10 +2,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:shock_alarm_app/components/shock_disclamer.dart'; +import 'package:shock_alarm_app/main.dart'; import 'package:shock_alarm_app/services/alarm_list_manager.dart'; import 'package:url_launcher/url_launcher.dart'; import '../components/token_item.dart'; -import '../main.dart'; import 'shares.dart'; class TokenScreen extends StatefulWidget { @@ -56,9 +56,9 @@ class TokenScreenState extends State { content: SingleChildScrollView(child: Column( children: [ - DefaultTextStyle(style: TextStyle(), child: SelectableText.rich(TextSpan(children: [ + DefaultTextStyle(style: Theme.of(context).textTheme.bodyMedium!, child: SelectableText.rich(TextSpan(children: [ TextSpan(text: "As you are using a browser, you must use a token to sign in. To get one visit "), - TextSpan(text: "https://next.openshock.app/settings/api-tokens", recognizer: recognizer, style: TextStyle(decoration: TextDecoration.underline), mouseCursor: SystemMouseCursors.click), + TextSpan(text: "https://next.openshock.app/settings/api-tokens", recognizer: recognizer, style: TextStyle(color: Theme.of(context).hintColor, decoration: TextDecoration.underline), mouseCursor: SystemMouseCursors.click), TextSpan(text: " and generate a token with all permissions. Then paste it here.") ] @@ -224,7 +224,42 @@ class TokenScreenState extends State { showLoginPopup(); } }, child: Text("Log in to OpenShock", style: TextStyle(fontSize: t.textTheme.titleMedium!.fontSize)),), - + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Theme"), + SegmentedButton( + segments: [ + ButtonSegment(value: 0, label: Icon(Icons.devices)), + ButtonSegment(value: 1, label: Icon(Icons.sunny)), + ButtonSegment(value: 2, label: Icon(Icons.nightlight)), + ], + selected: { + switch(context.findAncestorStateOfType()?.themeMode){ + null => throw UnimplementedError(), // should never be null ig + ThemeMode.system => 0, + ThemeMode.light => 1, + ThemeMode.dark => 2, + } + }, + onSelectionChanged: (Set newSelection) { + if(newSelection.isNotEmpty) { + switch(newSelection.first) { + case 0: + context.findAncestorStateOfType()?.setThemeMode(ThemeMode.system); + break; + case 1: + context.findAncestorStateOfType()?.setThemeMode(ThemeMode.light); + break; + case 2: + context.findAncestorStateOfType()?.setThemeMode(ThemeMode.dark); + break; + } + } + }, + ) + ], + ), // Actual options Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/services/alarm_list_manager.dart b/lib/services/alarm_list_manager.dart index 9e39d39..165a2b9 100644 --- a/lib/services/alarm_list_manager.dart +++ b/lib/services/alarm_list_manager.dart @@ -26,6 +26,8 @@ class Settings { int maxAlarmLengthSeconds = 60; + ThemeMode theme = ThemeMode.system; + Settings(); @@ -46,6 +48,8 @@ class Settings { useHttpShocking = json["useHttpShocking"]; if(json["useGroupedShockerSelection"] != null) useGroupedShockerSelection = json["useGroupedShockerSelection"]; + if(json["theme"] != null) + theme = json["theme"] == 0 ? ThemeMode.system : json["theme"] == 1 ? ThemeMode.light : ThemeMode.dark; } Map toJson() { @@ -57,7 +61,8 @@ class Settings { "disableHubFiltering": disableHubFiltering, "allowTokenEditing": allowTokenEditing, "useHttpShocking": useHttpShocking, - "useGroupedShockerSelection": useGroupedShockerSelection + "useGroupedShockerSelection": useGroupedShockerSelection, + "theme": theme == ThemeMode.system ? 0: theme == ThemeMode.light ? 1 : 2 }; } } @@ -149,7 +154,7 @@ class AlarmListManager { void saveSettings() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString("settings", jsonEncode(settings)); - reloadAllMethod!(); + reloadAllMethod?.call(); } void rescheduleAlarms() async { From 076b9f9e11944a096be751e1f7141a160b51be38 Mon Sep 17 00:00:00 2001 From: Abynox Date: Mon, 27 Jan 2025 19:58:32 +0100 Subject: [PATCH 2/2] Removed cursed code xD --- lib/services/alarm_list_manager.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/services/alarm_list_manager.dart b/lib/services/alarm_list_manager.dart index 165a2b9..e6b04c5 100644 --- a/lib/services/alarm_list_manager.dart +++ b/lib/services/alarm_list_manager.dart @@ -49,7 +49,7 @@ class Settings { if(json["useGroupedShockerSelection"] != null) useGroupedShockerSelection = json["useGroupedShockerSelection"]; if(json["theme"] != null) - theme = json["theme"] == 0 ? ThemeMode.system : json["theme"] == 1 ? ThemeMode.light : ThemeMode.dark; + theme = ThemeMode.values[json["theme"]]; } Map toJson() { @@ -62,7 +62,7 @@ class Settings { "allowTokenEditing": allowTokenEditing, "useHttpShocking": useHttpShocking, "useGroupedShockerSelection": useGroupedShockerSelection, - "theme": theme == ThemeMode.system ? 0: theme == ThemeMode.light ? 1 : 2 + "theme": theme.index }; } }