diff --git a/lib/frontend/screens/profile/font_settings_screen.dart b/lib/frontend/screens/profile/font_settings_screen.dart index d2b3753..ba3fd15 100644 --- a/lib/frontend/screens/profile/font_settings_screen.dart +++ b/lib/frontend/screens/profile/font_settings_screen.dart @@ -135,7 +135,6 @@ class _FontSettingsScreenState extends State { final cs = Theme.of(context).colorScheme; final app = KometApp.stateOf(context); final currentId = app?.fontId ?? AppFonts.fallback.id; - final scale = app?.fontScale ?? AppFonts.defaultScale; return Scaffold( backgroundColor: cs.surface, @@ -187,18 +186,22 @@ class _FontSettingsScreenState extends State { text: 'Размер шрифта', ), const SizedBox(height: 6), - _FontSizeControl( - scale: scale, - onChanged: (v) => app?.applyFontScale(v, persist: false), - onChangeEnd: (v) { - Haptics.selection(); - app?.applyFontScale(v); - }, - onReset: () { - Haptics.selection(); - app?.applyFontScale(AppFonts.defaultScale); - }, - ), + if (app != null) + ValueListenableBuilder( + valueListenable: app.fontScale, + builder: (context, scale, _) => _FontSizeControl( + scale: scale, + onChanged: (v) => app.applyFontScale(v, persist: false), + onChangeEnd: (v) { + Haptics.selection(); + app.applyFontScale(v); + }, + onReset: () { + Haptics.selection(); + app.applyFontScale(AppFonts.defaultScale); + }, + ), + ), ], ), ), diff --git a/lib/main.dart b/lib/main.dart index 7b64a8c..9e03307 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -106,7 +106,6 @@ class KometAppState extends State { late Locale _locale; late String _fontId; - late double _fontScale; bool _isLoggingOut = false; StreamSubscription? _sessionExpiredSub; StreamSubscription? _loginStatusSub; @@ -119,6 +118,9 @@ class KometAppState extends State { late final ValueNotifier vpnBypassEnabled = ValueNotifier( widget.initialVpnBypass, ); + late final ValueNotifier fontScale = ValueNotifier( + widget.initialFontScale, + ); final _profileUpdateController = StreamController.broadcast(); Stream get profileUpdateStream => _profileUpdateController.stream; @@ -127,7 +129,6 @@ class KometAppState extends State { super.initState(); _locale = widget.initialLocale; _fontId = widget.initialFontId; - _fontScale = widget.initialFontScale; api.setReconnectCallback(() async { try { @@ -203,6 +204,7 @@ class KometAppState extends State { _profileUpdateController.close(); fpsOverlayEnabled.dispose(); vpnBypassEnabled.dispose(); + fontScale.dispose(); super.dispose(); } @@ -234,7 +236,6 @@ class KometAppState extends State { } String get fontId => _fontId; - double get fontScale => _fontScale; Future applyAppFont(String fontId) async { if (_fontId == fontId) return; @@ -247,9 +248,7 @@ class KometAppState extends State { Future applyFontScale(double scale, {bool persist = true}) async { final next = AppFonts.clampScale(scale); - if (_fontScale != next && mounted) { - setState(() => _fontScale = next); - } + fontScale.value = next; if (persist) { final prefs = await SharedPreferences.getInstance(); await prefs.setDouble(AppFonts.scalePrefKey, next); @@ -364,21 +363,31 @@ class KometAppState extends State { darkTheme: _darkTheme, navigatorKey: KometApp.navigatorKey, builder: (context, child) { - final scaledChild = MediaQuery.withClampedTextScaling( - minScaleFactor: _fontScale, - maxScaleFactor: _fontScale, + return ValueListenableBuilder( + valueListenable: fontScale, child: child ?? const SizedBox.shrink(), - ); - return ValueListenableBuilder( - valueListenable: fpsOverlayEnabled, - builder: (context, fpsOn, _) { - return Stack( - fit: StackFit.expand, - clipBehavior: Clip.none, - children: [ - scaledChild, - if (fpsOn) const FpsOverlayLayer(), - ], + builder: (context, scale, appChild) { + Widget scaledChild = appChild!; + if ((scale - 1.0).abs() > 0.001) { + scaledChild = MediaQuery.withClampedTextScaling( + minScaleFactor: scale, + maxScaleFactor: scale, + child: scaledChild, + ); + } + return ValueListenableBuilder( + valueListenable: fpsOverlayEnabled, + child: scaledChild, + builder: (context, fpsOn, sChild) { + return Stack( + fit: StackFit.expand, + clipBehavior: Clip.none, + children: [ + sChild!, + if (fpsOn) const FpsOverlayLayer(), + ], + ); + }, ); }, );