From e6a488a4e217065ff28fbf95e5a3506883f67d49 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:45:37 +0200 Subject: [PATCH] fix(settings): resolve tv-dependent defaults at read time --- .../base_shared_preferences_service.dart | 26 ++++++++++++++----- lib/services/settings_service.dart | 13 +++++----- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/services/base_shared_preferences_service.dart b/lib/services/base_shared_preferences_service.dart index 96a2ac00..fc5995f0 100644 --- a/lib/services/base_shared_preferences_service.dart +++ b/lib/services/base_shared_preferences_service.dart @@ -171,10 +171,15 @@ abstract class Pref { class BoolPref extends Pref { final bool defaultValue; + + /// Lazily-resolved default for values that depend on state unavailable at + /// static-init time (e.g. async TV detection). Wins over [defaultValue]. + final bool Function()? defaultValueProvider; final void Function(bool)? onWrite; - const BoolPref(super.key, {this.defaultValue = false, this.onWrite}); + const BoolPref(super.key, {this.defaultValue = false, this.defaultValueProvider, this.onWrite}); @override - bool readFrom(BaseSharedPreferencesService svc) => svc.readBool(key, defaultValue: defaultValue); + bool readFrom(BaseSharedPreferencesService svc) => + svc.readBool(key, defaultValue: defaultValueProvider?.call() ?? defaultValue); @override Future writeTo(BaseSharedPreferencesService svc, bool value) async { await svc.writeBool(key, value); @@ -248,17 +253,24 @@ class StringListPref extends Pref> { Future writeTo(BaseSharedPreferencesService svc, List value) => svc.writeStringList(key, value); } -/// Stores an enum by its [Enum.name]; falls back to [defaultValue] when the +/// Stores an enum by its [Enum.name]; falls back to the default when the /// stored string doesn't match any value in [values]. +/// +/// Exactly one of [defaultValue] / [defaultValueProvider] must be given; the +/// provider form resolves at read time, for defaults that depend on state +/// unavailable at static-init time (e.g. async TV detection). class EnumPref extends Pref { final List values; - final T defaultValue; - const EnumPref(super.key, {required this.values, required this.defaultValue}); + final T? defaultValue; + final T Function()? defaultValueProvider; + const EnumPref(super.key, {required this.values, this.defaultValue, this.defaultValueProvider}) + : assert((defaultValue != null) != (defaultValueProvider != null)); + T get _default => defaultValueProvider?.call() ?? defaultValue!; @override T readFrom(BaseSharedPreferencesService svc) { final stored = svc.prefs.getString(key); - if (stored == null) return defaultValue; - return values.firstWhere((v) => v.name == stored, orElse: () => defaultValue); + if (stored == null) return _default; + return values.firstWhere((v) => v.name == stored, orElse: () => _default); } @override diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 6edde3db..556e60f9 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -395,18 +395,19 @@ class SettingsService extends BaseSharedPreferencesService { static final defaultBoxFitMode = IntPref('default_box_fit_mode', transform: (v) => v.clamp(0, 2)); static final displaySwitchDelay = IntPref('display_switch_delay', transform: (v) => v.clamp(0, 10)); - static final themeMode = EnumPref( + static ThemeMode _tvAwareThemeModeDefault() => TvDetectionService.isTVSync() ? ThemeMode.oled : ThemeMode.system; + static const themeMode = EnumPref( 'theme_mode', values: ThemeMode.values, - defaultValue: TvDetectionService.isTVSync() ? ThemeMode.oled : ThemeMode.system, + defaultValueProvider: _tvAwareThemeModeDefault, ); - static final videoPlayerNavigationEnabled = BoolPref( + static const videoPlayerNavigationEnabled = BoolPref( 'video_player_navigation_enabled', - defaultValue: TvDetectionService.isTVSync(), + defaultValueProvider: TvDetectionService.isTVSync, ); - static final enableCompanionRemoteServer = BoolPref( + static const enableCompanionRemoteServer = BoolPref( 'enable_companion_remote_server', - defaultValue: PlatformDetector.isDesktopOS(), + defaultValueProvider: PlatformDetector.isDesktopOS, ); static const startInFullscreen = BoolPref('start_in_fullscreen'); static const exitFullscreenOnPlayerClose = BoolPref('exit_fullscreen_on_player_close');