From c550437aa516be1013df58c6d257886994966ad5 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Thu, 3 Feb 2022 21:17:08 -0500 Subject: [PATCH] settings pane headers, and notification settings options --- lib/settings.dart | 80 +++++++++++++++++++++++ lib/views/globalsettingsview.dart | 105 +++++++++++++++++++++--------- 2 files changed, 155 insertions(+), 30 deletions(-) diff --git a/lib/settings.dart b/lib/settings.dart index 8bfaa3f9..ab1cca53 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -22,6 +22,17 @@ enum DualpaneMode { CopyPortrait, } +enum NotificationPolicy { + None, + OptIn, + OptOut, +} + +enum NotificationContent { + SimpleEvent, + ContactInfo, +} + /// Settings govern the *Globally* relevant settings like Locale, Theme and Experiments. /// We also provide access to the version information here as it is also accessed from the /// Settings Pane. @@ -29,12 +40,16 @@ class Settings extends ChangeNotifier { Locale locale; late PackageInfo packageInfo; OpaqueThemeType theme; + // explicitly set experiments to false until told otherwise... bool experimentsEnabled = false; HashMap experiments = HashMap.identity(); DualpaneMode _uiColumnModePortrait = DualpaneMode.Single; DualpaneMode _uiColumnModeLandscape = DualpaneMode.CopyPortrait; + NotificationPolicy _notificationPolicy = NotificationPolicy.OptOut; + NotificationContent _notificationContent = NotificationContent.SimpleEvent; + bool blockUnknownConnections = false; bool streamerMode = false; String _downloadPath = ""; @@ -94,6 +109,9 @@ class Settings extends ChangeNotifier { _uiColumnModePortrait = uiColumnModeFromString(settings["UIColumnModePortrait"]); _uiColumnModeLandscape = uiColumnModeFromString(settings["UIColumnModeLandscape"]); + _notificationPolicy = notificationPolicyFromString(settings["NotificationPolicy"]); + _notificationContent = notificationContentFromString(settings["NotificationContent"]); + // auto-download folder _downloadPath = settings["DownloadPath"] ?? ""; @@ -173,17 +191,33 @@ class Settings extends ChangeNotifier { } DualpaneMode get uiColumnModePortrait => _uiColumnModePortrait; + set uiColumnModePortrait(DualpaneMode newval) { this._uiColumnModePortrait = newval; notifyListeners(); } DualpaneMode get uiColumnModeLandscape => _uiColumnModeLandscape; + set uiColumnModeLandscape(DualpaneMode newval) { this._uiColumnModeLandscape = newval; notifyListeners(); } + NotificationPolicy get notificationPolicy => _notificationPolicy; + + set notificationPolicy(NotificationPolicy newpol) { + this._notificationPolicy = newpol; + notifyListeners(); + } + + NotificationContent get notificationContent => _notificationContent; + + set notificationContent(NotificationContent newcon) { + this._notificationContent = newcon; + notifyListeners(); + } + List uiColumns(bool isLandscape) { var m = (!isLandscape || uiColumnModeLandscape == DualpaneMode.CopyPortrait) ? uiColumnModePortrait : uiColumnModeLandscape; switch (m) { @@ -238,6 +272,43 @@ class Settings extends ChangeNotifier { } } + static NotificationPolicy notificationPolicyFromString(String? np) { + switch (np) { + case "None": + return NotificationPolicy.None; + case "OptIn": + return NotificationPolicy.OptIn; + case "OptOut": + return NotificationPolicy.OptOut; + } + return NotificationPolicy.OptOut; + } + + static NotificationContent notificationContentFromString(String? nc) { + switch (nc) { + case "SimpleEvent": + return NotificationContent.SimpleEvent; + case "ContactInfo": + return NotificationContent.ContactInfo; + } + return NotificationContent.SimpleEvent; + } + + static String notificationPolicyToString(NotificationPolicy np, BuildContext context) { + switch (np) { + case NotificationPolicy.None: return "None"; + case NotificationPolicy.OptIn: return "OptIn"; + case NotificationPolicy.OptOut: return "OptOut"; + } + } + + static String notificationContentToString(NotificationContent nc, BuildContext context) { + switch (nc) { + case NotificationContent.SimpleEvent: return "SimpleEvent"; + case NotificationContent.ContactInfo: return "ContactInfo"; + } + } + // checks experiment settings and file extension for image previews // (ignores file size; if the user manually accepts the file, assume it's okay to preview) bool shouldPreview(String path) { @@ -247,18 +318,21 @@ class Settings extends ChangeNotifier { } String get downloadPath => _downloadPath; + set downloadPath(String newval) { _downloadPath = newval; notifyListeners(); } bool get allowAdvancedTorConfig => _allowAdvancedTorConfig; + set allowAdvancedTorConfig(bool torConfig) { _allowAdvancedTorConfig = torConfig; notifyListeners(); } bool get useTorCache => _useTorCache; + set useTorCache(bool useTorCache) { _useTorCache = useTorCache; notifyListeners(); @@ -266,18 +340,21 @@ class Settings extends ChangeNotifier { // Settings / Gettings for setting the custom tor config.. String get torConfig => _customTorConfig; + set torConfig(String torConfig) { _customTorConfig = torConfig; notifyListeners(); } int get socksPort => _socksPort; + set socksPort(int newSocksPort) { _socksPort = newSocksPort; notifyListeners(); } int get controlPort => _controlPort; + set controlPort(int controlPort) { _controlPort = controlPort; notifyListeners(); @@ -285,6 +362,7 @@ class Settings extends ChangeNotifier { // Setters / Getters for toggling whether the app should use a custom tor config bool get useCustomTorConfig => _useCustomTorConfig; + set useCustomTorConfig(bool useCustomTorConfig) { _useCustomTorConfig = useCustomTorConfig; notifyListeners(); @@ -302,6 +380,8 @@ class Settings extends ChangeNotifier { "ThemeMode": theme.mode, "PreviousPid": -1, "BlockUnknownConnections": blockUnknownConnections, + "NotificationPolicy": _notificationPolicy.toString(), + "NotificationContent": _notificationContent.toString(), "StreamerMode": streamerMode, "ExperimentsEnabled": this.experimentsEnabled, "Experiments": experiments, diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index 71eea58c..368ab329 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -53,11 +53,13 @@ class _GlobalSettingsViewState extends State { isAlwaysShown: true, child: SingleChildScrollView( clipBehavior: Clip.antiAlias, + padding: EdgeInsets.all(20), child: ConstrainedBox( constraints: BoxConstraints( minHeight: viewportConstraints.maxHeight, ), child: Column(children: [ + Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text("Apperance", style: TextStyle(fontWeight: FontWeight.bold))]), ListTile( title: Text(AppLocalizations.of(context)!.settingLanguage, style: TextStyle(color: settings.current().mainTextColor)), leading: Icon(CwtchIcons.change_language, color: settings.current().mainTextColor), @@ -135,24 +137,76 @@ class _GlobalSettingsViewState extends State { style: TextStyle(color: settings.current().mainTextColor), ), leading: Icon(Icons.table_chart, color: settings.current().mainTextColor), - trailing: Container( - width: MediaQuery.of(context).size.width / 4, - child: DropdownButton( - isExpanded: true, - value: settings.uiColumnModeLandscape.toString(), - onChanged: (String? newValue) { - settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!); - saveSettings(context); - }, - items: Settings.uiColumnModeOptions(true).map>((DualpaneMode value) { - return DropdownMenuItem( - value: value.toString(), - child: Text( - Settings.uiColumnModeToString(value, context), - overflow: TextOverflow.ellipsis, - ), - ); - }).toList()))), + trailing: DropdownButton( + value: settings.uiColumnModeLandscape.toString(), + onChanged: (String? newValue) { + settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!); + saveSettings(context); + }, + items: Settings.uiColumnModeOptions(true).map>((DualpaneMode value) { + return DropdownMenuItem( + value: value.toString(), + child: Text( + Settings.uiColumnModeToString(value, context), + overflow: TextOverflow.ellipsis, + ), + ); + }).toList())), + SwitchListTile( + title: Text(AppLocalizations.of(context)!.streamerModeLabel, style: TextStyle(color: settings.current().mainTextColor)), + subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode), + value: settings.streamerMode, + onChanged: (bool value) { + settings.setStreamerMode(value); + // Save Settings... + saveSettings(context); + }, + activeTrackColor: settings.theme.defaultButtonColor, + inactiveTrackColor: settings.theme.defaultButtonDisabledColor, + secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor), + ), + SizedBox( + height: 40, + ), + Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text("Behaviour", style: TextStyle(fontWeight: FontWeight.bold))]), + ListTile( + title: Text(/*AppLocalizations.of(context)!.themeColorLabel*/ "Notification Policy"), + trailing: DropdownButton( + value: settings.notificationPolicy, + onChanged: (NotificationPolicy? newValue) { + settings.notificationPolicy = newValue!; + saveSettings(context); + }, + items: NotificationPolicy.values.map>((NotificationPolicy value) { + return DropdownMenuItem( + value: value, + child: Text( + Settings.notificationPolicyToString(value, context), + overflow: TextOverflow.ellipsis, + ), + ); + }).toList()), + leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor), + ), + ListTile( + title: Text(/*AppLocalizations.of(context)!.themeColorLabel*/ "Notification Content"), + trailing: DropdownButton( + value: settings.notificationContent, + onChanged: (NotificationContent? newValue) { + settings.notificationContent = newValue!; + saveSettings(context); + }, + items: NotificationContent.values.map>((NotificationContent value) { + return DropdownMenuItem( + value: value, + child: Text( + Settings.notificationContentToString(value, context), + overflow: TextOverflow.ellipsis, + ), + ); + }).toList()), + leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor), + ), SwitchListTile( title: Text(AppLocalizations.of(context)!.blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor)), subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections), @@ -171,19 +225,10 @@ class _GlobalSettingsViewState extends State { inactiveTrackColor: settings.theme.defaultButtonDisabledColor, secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor), ), - SwitchListTile( - title: Text(AppLocalizations.of(context)!.streamerModeLabel, style: TextStyle(color: settings.current().mainTextColor)), - subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode), - value: settings.streamerMode, - onChanged: (bool value) { - settings.setStreamerMode(value); - // Save Settings... - saveSettings(context); - }, - activeTrackColor: settings.theme.defaultButtonColor, - inactiveTrackColor: settings.theme.defaultButtonDisabledColor, - secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor), + SizedBox( + height: 40, ), + Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text("Experiments", style: TextStyle(fontWeight: FontWeight.bold))]), SwitchListTile( title: Text(AppLocalizations.of(context)!.experimentsEnabled, style: TextStyle(color: settings.current().mainTextColor)), subtitle: Text(AppLocalizations.of(context)!.descriptionExperiments),