diff --git a/CHANGELOG.md b/CHANGELOG.md index 8130831b0..46f5e0286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. - Info: option to set date from other item - Info: improved DNG tags display - warn and optionally set metadata date before moving undated items +- Settings: display refresh rate hint ### Changed diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index cd3294c9b..4025064bd 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -177,6 +177,9 @@ "accessibilityAnimationsRemove": "Prevent screen effects", "accessibilityAnimationsKeep": "Keep screen effects", + "displayRefreshRatePreferHighest": "Prefer highest rate", + "displayRefreshRatePreferLowest": "Prefer lowest rate", + "themeBrightnessLight": "Light", "themeBrightnessDark": "Dark", "themeBrightnessBlack": "Black", @@ -703,6 +706,8 @@ "settingsSectionDisplay": "Display", "settingsThemeBrightness": "Theme", "settingsThemeColorful": "Colorful", + "settingsDisplayRefreshRateModeTile": "Display refresh rate", + "settingsDisplayRefreshRateModeTitle": "Display Refresh Rate", "settingsSectionLanguage": "Language & Formats", "settingsLanguage": "Language", diff --git a/lib/model/settings/defaults.dart b/lib/model/settings/defaults.dart index 04802a572..21d5baddd 100644 --- a/lib/model/settings/defaults.dart +++ b/lib/model/settings/defaults.dart @@ -16,6 +16,7 @@ class SettingsDefaults { static const canUseAnalysisService = true; static const isInstalledAppAccessAllowed = false; static const isErrorReportingAllowed = false; + static const displayRefreshRateMode = DisplayRefreshRateMode.auto; static const themeBrightness = AvesThemeBrightness.system; static const themeColorMode = AvesThemeColorMode.polychrome; static const tileLayout = TileLayout.grid; diff --git a/lib/model/settings/enums/display_refresh_rate_mode.dart b/lib/model/settings/enums/display_refresh_rate_mode.dart new file mode 100644 index 000000000..d650d5337 --- /dev/null +++ b/lib/model/settings/enums/display_refresh_rate_mode.dart @@ -0,0 +1,33 @@ +import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_displaymode/flutter_displaymode.dart'; + +import 'enums.dart'; + +extension ExtraDisplayRefreshRateMode on DisplayRefreshRateMode { + String getName(BuildContext context) { + switch (this) { + case DisplayRefreshRateMode.auto: + return context.l10n.settingsSystemDefault; + case DisplayRefreshRateMode.highest: + return context.l10n.displayRefreshRatePreferHighest; + case DisplayRefreshRateMode.lowest: + return context.l10n.displayRefreshRatePreferLowest; + } + } + + void apply() { + debugPrint('Apply display refresh rate: $name'); + switch (this) { + case DisplayRefreshRateMode.auto: + FlutterDisplayMode.setPreferredMode(DisplayMode.auto); + break; + case DisplayRefreshRateMode.highest: + FlutterDisplayMode.setHighRefreshRate(); + break; + case DisplayRefreshRateMode.lowest: + FlutterDisplayMode.setLowRefreshRate(); + break; + } + } +} diff --git a/lib/model/settings/enums/enums.dart b/lib/model/settings/enums/enums.dart index b0709fdf3..461541d2c 100644 --- a/lib/model/settings/enums/enums.dart +++ b/lib/model/settings/enums/enums.dart @@ -19,6 +19,8 @@ enum HomePageSetting { collection, albums } enum KeepScreenOn { never, viewerOnly, always } +enum DisplayRefreshRateMode { auto, highest, lowest } + enum UnitSystem { metric, imperial } enum VideoLoopMode { never, shortOnly, always } diff --git a/lib/model/settings/enums/theme_brightness.dart b/lib/model/settings/enums/theme_brightness.dart index effdeefc4..5edf515ae 100644 --- a/lib/model/settings/enums/theme_brightness.dart +++ b/lib/model/settings/enums/theme_brightness.dart @@ -1,7 +1,7 @@ +import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; import 'enums.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; extension ExtraAvesThemeBrightness on AvesThemeBrightness { String getName(BuildContext context) { @@ -16,6 +16,7 @@ extension ExtraAvesThemeBrightness on AvesThemeBrightness { return context.l10n.themeBrightnessBlack; } } + ThemeMode get appThemeMode { switch (this) { case AvesThemeBrightness.system: diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 33b75103f..e35066bfd 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -41,6 +41,7 @@ class Settings extends ChangeNotifier { static const isInstalledAppAccessAllowedKey = 'is_installed_app_access_allowed'; static const isErrorReportingAllowedKey = 'is_crashlytics_enabled'; static const localeKey = 'locale'; + static const displayRefreshRateModeKey = 'display_refresh_rate_mode'; static const themeBrightnessKey = 'theme_brightness'; static const themeColorModeKey = 'theme_color_mode'; static const catalogTimeZoneKey = 'catalog_time_zone'; @@ -245,6 +246,10 @@ class Settings extends ChangeNotifier { return _appliedLocale!; } + DisplayRefreshRateMode get displayRefreshRateMode => getEnumOrDefault(displayRefreshRateModeKey, SettingsDefaults.displayRefreshRateMode, DisplayRefreshRateMode.values); + + set displayRefreshRateMode(DisplayRefreshRateMode newValue) => setAndNotify(displayRefreshRateModeKey, newValue.toString()); + AvesThemeBrightness get themeBrightness => getEnumOrDefault(themeBrightnessKey, SettingsDefaults.themeBrightness, AvesThemeBrightness.values); set themeBrightness(AvesThemeBrightness newValue) => setAndNotify(themeBrightnessKey, newValue.toString()); @@ -709,6 +714,7 @@ class Settings extends ChangeNotifier { } break; case localeKey: + case displayRefreshRateModeKey: case themeBrightnessKey: case themeColorModeKey: case keepScreenOnKey: diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart index 9d8266c28..8cdfa25cc 100644 --- a/lib/utils/constants.dart +++ b/lib/utils/constants.dart @@ -111,6 +111,11 @@ class Constants { license: 'MIT', sourceUrl: 'https://github.com/deckerst/fijkplayer', ), + Dependency( + name: 'Flutter Display Mode', + license: 'MIT', + sourceUrl: 'https://github.com/ajinasokan/flutter_displaymode', + ), Dependency( name: 'Google API Availability', license: 'MIT', diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index fb17893f5..46adbc61a 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -6,6 +6,7 @@ import 'package:aves/app_mode.dart'; import 'package:aves/l10n/l10n.dart'; import 'package:aves/model/device.dart'; import 'package:aves/model/settings/enums/accessibility_animations.dart'; +import 'package:aves/model/settings/enums/display_refresh_rate_mode.dart'; import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/enums/screen_on.dart'; import 'package:aves/model/settings/enums/theme_brightness.dart'; @@ -242,9 +243,8 @@ class _AvesAppState extends State with WidgetsBindingObserver { } } - void applyKeepScreenOn() { - settings.keepScreenOn.apply(); - } + void applyDisplayRefreshRateMode() => settings.displayRefreshRateMode.apply(); + void applyKeepScreenOn() => settings.keepScreenOn.apply(); void applyIsRotationLocked() { if (!settings.isRotationLocked) { @@ -253,9 +253,11 @@ class _AvesAppState extends State with WidgetsBindingObserver { } settings.updateStream.where((event) => event.key == Settings.isInstalledAppAccessAllowedKey).listen((_) => applyIsInstalledAppAccessAllowed()); + settings.updateStream.where((event) => event.key == Settings.displayRefreshRateModeKey).listen((_) => applyDisplayRefreshRateMode()); settings.updateStream.where((event) => event.key == Settings.keepScreenOnKey).listen((_) => applyKeepScreenOn()); settings.updateStream.where((event) => event.key == Settings.platformAccelerometerRotationKey).listen((_) => applyIsRotationLocked()); + applyDisplayRefreshRateMode(); applyKeepScreenOn(); applyIsRotationLocked(); } diff --git a/lib/widgets/settings/display/display.dart b/lib/widgets/settings/display/display.dart index 87203a87c..1880d34ce 100644 --- a/lib/widgets/settings/display/display.dart +++ b/lib/widgets/settings/display/display.dart @@ -1,3 +1,4 @@ +import 'package:aves/model/settings/enums/display_refresh_rate_mode.dart'; import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/enums/theme_brightness.dart'; import 'package:aves/model/settings/settings.dart'; @@ -42,6 +43,14 @@ class DisplaySection extends StatelessWidget { onChanged: (v) => settings.themeColorMode = v ? AvesThemeColorMode.polychrome : AvesThemeColorMode.monochrome, title: context.l10n.settingsThemeColorful, ), + SettingsSelectionListTile( + values: DisplayRefreshRateMode.values, + getName: (context, v) => v.getName(context), + selector: (context, s) => s.displayRefreshRateMode, + onSelection: (v) => settings.displayRefreshRateMode = v, + tileTitle: context.l10n.settingsDisplayRefreshRateModeTile, + dialogTitle: context.l10n.settingsDisplayRefreshRateModeTitle, + ), ], ); } diff --git a/pubspec.lock b/pubspec.lock index d3d74c53e..3b120d999 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -360,6 +360,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.1" + flutter_displaymode: + dependency: "direct main" + description: + name: flutter_displaymode + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.2" flutter_driver: dependency: "direct dev" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 8fdcf6faa..064e8babd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: ref: aves flex_color_picker: fluster: + flutter_displaymode: flutter_highlight: flutter_map: flutter_markdown: diff --git a/untranslated.json b/untranslated.json index a504ad57d..5c67a6759 100644 --- a/untranslated.json +++ b/untranslated.json @@ -1,5 +1,7 @@ { "de": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -18,10 +20,14 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "es": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -40,10 +46,14 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "fr": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -62,7 +72,9 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "id": [ @@ -72,6 +84,8 @@ "videoControlsPlaySeek", "videoControlsPlayOutside", "videoControlsNone", + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -97,10 +111,14 @@ "settingsVideoGestureSideDoubleTapSeek", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "ja": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -119,10 +137,14 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "ko": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -141,10 +163,14 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "pt": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -163,10 +189,14 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ], "ru": [ + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", "themeBrightnessLight", "themeBrightnessDark", "themeBrightnessBlack", @@ -185,6 +215,8 @@ "settingsConfirmationDialogMoveUndatedItems", "settingsSectionDisplay", "settingsThemeBrightness", - "settingsThemeColorful" + "settingsThemeColorful", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeTitle" ] }