From b5b308c99d8d73ac7218efd82c839a00348454b5 Mon Sep 17 00:00:00 2001 From: Edouard Marquez Date: Thu, 13 Jun 2024 08:29:22 +0200 Subject: [PATCH] fix: `ThemeProvider` properly resync the theme (#5363) * Fix theme internals * Also fix the animation --- .../data_models/tagline/tagline_provider.dart | 6 ++-- .../lib/pages/scan/scan_tagline.dart | 6 ++-- .../lib/resources/app_animations.dart | 2 +- .../smooth_app/lib/themes/theme_provider.dart | 28 ++++++++++++++++--- .../lib/widgets/smooth_product_carousel.dart | 16 ++++------- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/packages/smooth_app/lib/data_models/tagline/tagline_provider.dart b/packages/smooth_app/lib/data_models/tagline/tagline_provider.dart index d1f3a684c18d..f80f1148f16f 100644 --- a/packages/smooth_app/lib/data_models/tagline/tagline_provider.dart +++ b/packages/smooth_app/lib/data_models/tagline/tagline_provider.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'dart:isolate'; import 'package:collection/collection.dart'; -import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; import 'package:http/http.dart' as http; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; @@ -63,9 +63,9 @@ class TagLineProvider extends ChangeNotifier { void _emit(TagLineState state) { _state = state; - try { + WidgetsBinding.instance.addPostFrameCallback((_) { notifyListeners(); - } catch (_) {} + }); } TagLineState get state => _state; diff --git a/packages/smooth_app/lib/pages/scan/scan_tagline.dart b/packages/smooth_app/lib/pages/scan/scan_tagline.dart index 1a906e818b33..8fabda2f8a84 100644 --- a/packages/smooth_app/lib/pages/scan/scan_tagline.dart +++ b/packages/smooth_app/lib/pages/scan/scan_tagline.dart @@ -112,7 +112,7 @@ class _ScanTagLineContentState extends State<_ScanTagLineContent> { DecoratedBox( decoration: BoxDecoration( color: currentNews.style?.titleBackground ?? - (themeProvider.isLightTheme + (!themeProvider.isDarkMode(context) ? theme.primarySemiDark : theme.primaryBlack), borderRadius: const BorderRadiusDirectional.only( @@ -137,7 +137,7 @@ class _ScanTagLineContentState extends State<_ScanTagLineContent> { child: DecoratedBox( decoration: BoxDecoration( color: currentNews.style?.contentBackgroundColor ?? - (themeProvider.isLightTheme + (!themeProvider.isDarkMode(context) ? theme.primaryMedium : theme.primaryDark), borderRadius: const BorderRadiusDirectional.only( @@ -253,7 +253,7 @@ class _TagLineContentBody extends StatelessWidget { text: message, textStyle: TextStyle( color: textColor ?? - (themeProvider.isLightTheme + (!themeProvider.isDarkMode(context) ? theme.primarySemiDark : theme.primaryLight), ), diff --git a/packages/smooth_app/lib/resources/app_animations.dart b/packages/smooth_app/lib/resources/app_animations.dart index d568adff8037..2b8a602ab100 100644 --- a/packages/smooth_app/lib/resources/app_animations.dart +++ b/packages/smooth_app/lib/resources/app_animations.dart @@ -169,7 +169,7 @@ class _SearchEyeAnimationState extends State { @override Widget build(BuildContext context) { final double size = widget.size ?? IconTheme.of(context).size ?? 24.0; - final bool lightTheme = context.watch().isLightTheme; + final bool lightTheme = context.watch().isDarkMode(context); return ExcludeSemantics( child: SizedBox( diff --git a/packages/smooth_app/lib/themes/theme_provider.dart b/packages/smooth_app/lib/themes/theme_provider.dart index 3f0626aee01a..0bb268f8d89a 100644 --- a/packages/smooth_app/lib/themes/theme_provider.dart +++ b/packages/smooth_app/lib/themes/theme_provider.dart @@ -7,15 +7,28 @@ const String THEME_DARK = 'Dark'; const String THEME_AMOLED = 'AMOLED'; class ThemeProvider with ChangeNotifier { - ThemeProvider(this._userPreferences); + ThemeProvider(this._userPreferences) + : _theme = _userPreferences.currentTheme { + _userPreferences.addListener(_onPreferencesChanged); + } final UserPreferences _userPreferences; // The onboarding needs the light mode. bool _forceLight = false; - String get currentTheme => - _forceLight ? THEME_LIGHT : _userPreferences.currentTheme; + // Local cache for [_userPreferences.currentTheme] + String _theme; + + void _onPreferencesChanged() { + final String newTheme = _userPreferences.currentTheme; + if (newTheme != _theme) { + _theme = newTheme; + notifyListeners(); + } + } + + String get currentTheme => _forceLight ? THEME_LIGHT : _theme; void setOnboardingComplete(final bool onboardingComplete) { _forceLight = !onboardingComplete; @@ -53,6 +66,13 @@ class ThemeProvider with ChangeNotifier { } bool isDarkMode(BuildContext context) { - return MediaQuery.platformBrightnessOf(context) == Brightness.dark; + return currentThemeMode != ThemeMode.light && + MediaQuery.platformBrightnessOf(context) == Brightness.dark; + } + + @override + void dispose() { + _userPreferences.removeListener(_onPreferencesChanged); + super.dispose(); } } diff --git a/packages/smooth_app/lib/widgets/smooth_product_carousel.dart b/packages/smooth_app/lib/widgets/smooth_product_carousel.dart index af7695ae3f2f..d5d806235c0c 100644 --- a/packages/smooth_app/lib/widgets/smooth_product_carousel.dart +++ b/packages/smooth_app/lib/widgets/smooth_product_carousel.dart @@ -263,12 +263,10 @@ class _SearchCard extends StatelessWidget { @override Widget build(BuildContext context) { final AppLocalizations localizations = AppLocalizations.of(context); - final ThemeProvider themeProvider = context.watch(); + final bool lightTheme = !context.watch().isDarkMode(context); final Widget widget = SmoothCard( - color: themeProvider.isLightTheme - ? Colors.grey.withOpacity(0.1) - : Colors.black, + color: lightTheme ? Colors.grey.withOpacity(0.1) : Colors.black, padding: const EdgeInsets.symmetric( vertical: MEDIUM_SPACE, horizontal: LARGE_SPACE, @@ -281,7 +279,7 @@ class _SearchCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ SvgPicture.asset( - Theme.of(context).brightness == Brightness.light + lightTheme ? 'assets/app/logo_text_black.svg' : 'assets/app/logo_text_white.svg', semanticsLabel: localizations.homepage_main_card_logo_description, @@ -317,9 +315,9 @@ class _SearchBar extends StatelessWidget { @override Widget build(BuildContext context) { final AppLocalizations localizations = AppLocalizations.of(context); - final ThemeProvider themeProvider = context.watch(); final SmoothColorsThemeExtension theme = Theme.of(context).extension()!; + final bool lightTheme = !context.watch().isDarkMode(context); return SizedBox( height: SEARCH_BAR_HEIGHT, @@ -329,7 +327,7 @@ class _SearchBar extends StatelessWidget { child: Ink( decoration: BoxDecoration( borderRadius: BorderRadius.circular(30.0), - color: themeProvider.isLightTheme ? Colors.white : theme.greyDark, + color: lightTheme ? Colors.white : theme.greyDark, border: Border.all(color: theme.primaryBlack), ), child: Row( @@ -347,9 +345,7 @@ class _SearchBar extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - color: themeProvider.isLightTheme - ? Colors.black - : Colors.white, + color: lightTheme ? Colors.black : Colors.white, ), ), ),