diff --git a/lib/main.dart b/lib/main.dart index d03b902..ef86464 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -128,7 +128,7 @@ class _ContactsPlusPlusState extends State { textTheme: _typography.white, colorScheme: darkDynamic ?? ColorScheme.fromSeed(seedColor: Colors.purple, brightness: Brightness.dark), ), - themeMode: ThemeMode.dark, + themeMode: ThemeMode.values[widget.settingsClient.currentSettings.themeMode.valueOrDefault], home: Builder( // Builder is necessary here since we need a context which has access to the ClientHolder builder: (context) { showUpdateDialogOnFirstBuild(context); diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 89519c5..97484d7 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:contacts_plus_plus/models/friend.dart'; import 'package:contacts_plus_plus/models/sem_ver.dart'; +import 'package:flutter/material.dart'; import 'package:uuid/uuid.dart'; class SettingsEntry { @@ -38,15 +39,18 @@ class Settings { final SettingsEntry lastOnlineStatus; final SettingsEntry lastDismissedVersion; final SettingsEntry machineId; + final SettingsEntry themeMode; Settings({ SettingsEntry? notificationsDenied, SettingsEntry? lastOnlineStatus, + SettingsEntry? themeMode, SettingsEntry? lastDismissedVersion, SettingsEntry? machineId }) : notificationsDenied = notificationsDenied ?? const SettingsEntry(deflt: false), lastOnlineStatus = lastOnlineStatus ?? SettingsEntry(deflt: OnlineStatus.online.index), + themeMode = themeMode ?? SettingsEntry(deflt: ThemeMode.dark.index), lastDismissedVersion = lastDismissedVersion ?? SettingsEntry(deflt: SemVer.zero().toString()), machineId = machineId ?? SettingsEntry(deflt: const Uuid().v4()); @@ -54,6 +58,7 @@ class Settings { return Settings( notificationsDenied: retrieveEntryOrNull(map["notificationsDenied"]), lastOnlineStatus: retrieveEntryOrNull(map["lastOnlineStatus"]), + themeMode: retrieveEntryOrNull(map["themeMode"]), lastDismissedVersion: retrieveEntryOrNull(map["lastDismissedVersion"]), machineId: retrieveEntryOrNull(map["machineId"]), ); @@ -72,6 +77,7 @@ class Settings { return { "notificationsDenied": notificationsDenied.toMap(), "lastOnlineStatus": lastOnlineStatus.toMap(), + "themeMode": themeMode.toMap(), "lastDismissedVersion": lastDismissedVersion.toMap(), "machineId": machineId.toMap(), }; @@ -82,12 +88,14 @@ class Settings { Settings copyWith({ bool? notificationsDenied, int? lastOnlineStatus, + int? themeMode, String? lastDismissedVersion, String? machineId, }) { return Settings( notificationsDenied: this.notificationsDenied.passThrough(notificationsDenied), lastOnlineStatus: this.lastOnlineStatus.passThrough(lastOnlineStatus), + themeMode: this.themeMode.passThrough(themeMode), lastDismissedVersion: this.lastDismissedVersion.passThrough(lastDismissedVersion), machineId: this.machineId.passThrough(machineId), ); diff --git a/lib/widgets/settings_page.dart b/lib/widgets/settings_page.dart index 0d9128f..8a07882 100644 --- a/lib/widgets/settings_page.dart +++ b/lib/widgets/settings_page.dart @@ -1,5 +1,7 @@ import 'package:contacts_plus_plus/client_holder.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_phoenix/flutter_phoenix.dart'; +import 'package:intl/intl.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -27,6 +29,31 @@ class SettingsPage extends StatelessWidget { initialState: !sClient.currentSettings.notificationsDenied.valueOrDefault, onChanged: (value) async => await sClient.changeSettings(sClient.currentSettings.copyWith(notificationsDenied: !value)), ), + const ListSectionHeader(name: "Appearance"), + ListTile( + trailing: StatefulBuilder( + builder: (context, setState) { + return DropdownButton( + items: ThemeMode.values.map((mode) => DropdownMenuItem( + value: mode, + child: Text("${toBeginningOfSentenceCase(mode.name)}",), + )).toList(), + value: ThemeMode.values[sClient.currentSettings.themeMode.valueOrDefault], + onChanged: (ThemeMode? value) async { + final currentSetting = sClient.currentSettings.themeMode.value; + if (currentSetting != value?.index) { + await sClient.changeSettings(sClient.currentSettings.copyWith(themeMode: value?.index)); + if (context.mounted) { + Phoenix.rebirth(context); + } + } + setState(() {}); + }, + ); + } + ), + title: const Text("Theme Mode"), + ), const ListSectionHeader(name: "Other"), ListTile( trailing: const Icon(Icons.logout),