From 4478d5de07250845b4a50e6c1087fb90529841f7 Mon Sep 17 00:00:00 2001 From: Vincent Velociter Date: Wed, 15 Jan 2025 15:26:48 +0800 Subject: [PATCH] More work on flex color scheme --- lib/src/app.dart | 291 ++++++++---------- .../model/settings/general_preferences.dart | 75 +++++ lib/src/utils/color_palette.dart | 44 ++- lib/src/view/play/quick_game_matrix.dart | 2 +- lib/src/view/settings/app_theme_screen.dart | 93 ++++++ lib/src/view/settings/theme_screen.dart | 87 +++--- lib/src/view/study/study_gamebook.dart | 4 +- lib/src/widgets/list.dart | 2 +- pubspec.lock | 8 +- pubspec.yaml | 2 +- 10 files changed, 392 insertions(+), 216 deletions(-) create mode 100644 lib/src/view/settings/app_theme_screen.dart diff --git a/lib/src/app.dart b/lib/src/app.dart index 1777732a5f..e169cfa3ab 100644 --- a/lib/src/app.dart +++ b/lib/src/app.dart @@ -120,181 +120,134 @@ class _AppState extends ConsumerState { @override Widget build(BuildContext context) { final generalPrefs = ref.watch(generalPreferencesProvider); - - final brightness = ref.watch(currentBrightnessProvider); - + // final boardTheme = ref.watch(boardPreferencesProvider.select((state) => state.boardTheme)); + final isTablet = isTabletOrLarger(context); + final isIOS = Theme.of(context).platform == TargetPlatform.iOS; final remainingHeight = estimateRemainingHeightLeftBoard(context); - return DynamicColorBuilder( - builder: (lightColorScheme, darkColorScheme) { - final isTablet = isTabletOrLarger(context); - final isIOS = Theme.of(context).platform == TargetPlatform.iOS; - - final colorScheme = - brightness == Brightness.light ? AppTheme.light.colorScheme : AppTheme.dark.colorScheme; + final flexSchemeLightColors = generalPrefs.appTheme.flexScheme.light; + final flexSchemeDarkColors = generalPrefs.appTheme.flexScheme.dark; + + final lightTheme = FlexThemeData.light( + colors: flexSchemeLightColors, + surfaceMode: FlexSurfaceMode.highBackgroundLowScaffold, + blendLevel: 1, + appBarStyle: FlexAppBarStyle.background, + bottomAppBarElevation: 2.0, + visualDensity: FlexColorScheme.comfortablePlatformDensity, + cupertinoOverrideTheme: const CupertinoThemeData(applyThemeToAll: true), + ); + final darkTheme = FlexThemeData.dark( + colors: flexSchemeDarkColors, + surfaceMode: FlexSurfaceMode.highBackgroundLowScaffold, + blendLevel: 28, + appBarStyle: FlexAppBarStyle.background, + bottomAppBarElevation: 2.0, + visualDensity: FlexColorScheme.comfortablePlatformDensity, + cupertinoOverrideTheme: const CupertinoThemeData(applyThemeToAll: true), + ); - final appTheme = brightness == Brightness.light ? AppTheme.light : AppTheme.dark; + final lightCupertinoTheme = CupertinoThemeData( + primaryColor: lightTheme.colorScheme.primary, + primaryContrastingColor: lightTheme.colorScheme.onPrimary, + brightness: Brightness.light, + textTheme: CupertinoTheme.of(context).textTheme.copyWith( + primaryColor: lightTheme.colorScheme.primary, + textStyle: CupertinoTheme.of( + context, + ).textTheme.textStyle.copyWith(color: lightTheme.colorScheme.onSurface), + navTitleTextStyle: CupertinoTheme.of( + context, + ).textTheme.navTitleTextStyle.copyWith(color: Styles.cupertinoTitleColor), + navLargeTitleTextStyle: CupertinoTheme.of( + context, + ).textTheme.navLargeTitleTextStyle.copyWith(color: Styles.cupertinoTitleColor), + ), + scaffoldBackgroundColor: lightTheme.colorScheme.surface, + barBackgroundColor: lightTheme.appBarTheme.backgroundColor?.withValues( + alpha: isTablet ? 1.0 : 0.9, + ), + applyThemeToAll: true, + ); - final cupertinoThemeData = CupertinoThemeData( - primaryColor: colorScheme.primary, - primaryContrastingColor: colorScheme.onPrimary, - brightness: brightness, - textTheme: CupertinoTheme.of(context).textTheme.copyWith( - primaryColor: colorScheme.primary, - textStyle: CupertinoTheme.of( - context, - ).textTheme.textStyle.copyWith(color: colorScheme.onSurface), - navTitleTextStyle: CupertinoTheme.of( - context, - ).textTheme.navTitleTextStyle.copyWith(color: Styles.cupertinoTitleColor), - navLargeTitleTextStyle: CupertinoTheme.of( - context, - ).textTheme.navLargeTitleTextStyle.copyWith(color: Styles.cupertinoTitleColor), - ), - scaffoldBackgroundColor: colorScheme.surface, - barBackgroundColor: appTheme.appBarTheme.backgroundColor?.withValues( - alpha: isTablet ? 1.0 : 0.9, - ), - applyThemeToAll: true, - ); + final darkCupertinoTheme = CupertinoThemeData( + primaryColor: darkTheme.colorScheme.primary, + primaryContrastingColor: darkTheme.colorScheme.onPrimary, + brightness: Brightness.dark, + textTheme: CupertinoTheme.of(context).textTheme.copyWith( + primaryColor: darkTheme.colorScheme.primary, + textStyle: CupertinoTheme.of( + context, + ).textTheme.textStyle.copyWith(color: darkTheme.colorScheme.onSurface), + navTitleTextStyle: CupertinoTheme.of( + context, + ).textTheme.navTitleTextStyle.copyWith(color: Styles.cupertinoTitleColor), + navLargeTitleTextStyle: CupertinoTheme.of( + context, + ).textTheme.navLargeTitleTextStyle.copyWith(color: Styles.cupertinoTitleColor), + ), + scaffoldBackgroundColor: darkTheme.colorScheme.surface, + barBackgroundColor: darkTheme.appBarTheme.backgroundColor?.withValues( + alpha: isTablet ? 1.0 : 0.9, + ), + applyThemeToAll: true, + ); - return MaterialApp( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: kSupportedLocales, - onGenerateTitle: (BuildContext context) => 'lichess.org', - locale: generalPrefs.locale, - theme: AppTheme.light.copyWith( - cupertinoOverrideTheme: cupertinoThemeData, - textTheme: - Theme.of(context).platform == TargetPlatform.iOS ? Typography.blackCupertino : null, - navigationBarTheme: NavigationBarTheme.of(context).copyWith( - height: remainingHeight < kSmallRemainingHeightLeftBoardThreshold ? 60 : null, - ), - extensions: [lichessCustomColors.harmonized(colorScheme)], - ), - darkTheme: AppTheme.dark - .copyWith( - textTheme: - isIOS - ? brightness == Brightness.light - ? Typography.blackCupertino - : Styles.whiteCupertinoTextTheme - : null, - ) - .copyWith( - splashFactory: isIOS ? NoSplash.splashFactory : null, - cupertinoOverrideTheme: cupertinoThemeData, - navigationBarTheme: NavigationBarTheme.of(context).copyWith( - height: remainingHeight < kSmallRemainingHeightLeftBoardThreshold ? 60 : null, - ), - extensions: [lichessCustomColors.harmonized(colorScheme)], - ), - themeMode: switch (generalPrefs.themeMode) { - BackgroundThemeMode.light => ThemeMode.light, - BackgroundThemeMode.dark => ThemeMode.dark, - BackgroundThemeMode.system => ThemeMode.system, - }, - builder: - Theme.of(context).platform == TargetPlatform.iOS - ? (context, child) { - // return CupertinoTheme( - // data: cupertinoThemeData, - // child: IconTheme.merge( - // data: IconThemeData( - // color: CupertinoTheme.of(context).textTheme.textStyle.color, - // ), - // child: Material(child: child), - // ), - // ); - return Material(child: child); - } - : null, - home: const BottomNavScaffold(), - navigatorObservers: [rootNavPageRouteObserver], - ); + return MaterialApp( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: kSupportedLocales, + onGenerateTitle: (BuildContext context) => 'lichess.org', + locale: generalPrefs.locale, + theme: lightTheme.copyWith( + cupertinoOverrideTheme: lightCupertinoTheme, + splashFactory: isIOS ? NoSplash.splashFactory : null, + textTheme: isIOS ? Typography.blackCupertino : null, + listTileTheme: ListTileTheme.of(context).copyWith( + titleTextStyle: isIOS ? lightCupertinoTheme.textTheme.textStyle : null, + subtitleTextStyle: isIOS ? lightCupertinoTheme.textTheme.textStyle : null, + leadingAndTrailingTextStyle: isIOS ? lightCupertinoTheme.textTheme.textStyle : null, + ), + navigationBarTheme: NavigationBarTheme.of( + context, + ).copyWith(height: remainingHeight < kSmallRemainingHeightLeftBoardThreshold ? 60 : null), + extensions: [lichessCustomColors.harmonized(lightTheme.colorScheme)], + ), + darkTheme: darkTheme.copyWith( + cupertinoOverrideTheme: darkCupertinoTheme, + splashFactory: isIOS ? NoSplash.splashFactory : null, + textTheme: isIOS ? Typography.whiteCupertino : null, + listTileTheme: ListTileTheme.of(context).copyWith( + titleTextStyle: isIOS ? darkCupertinoTheme.textTheme.textStyle : null, + subtitleTextStyle: isIOS ? darkCupertinoTheme.textTheme.textStyle : null, + leadingAndTrailingTextStyle: isIOS ? darkCupertinoTheme.textTheme.textStyle : null, + ), + navigationBarTheme: NavigationBarTheme.of( + context, + ).copyWith(height: remainingHeight < kSmallRemainingHeightLeftBoardThreshold ? 60 : null), + extensions: [lichessCustomColors.harmonized(darkTheme.colorScheme)], + ), + themeMode: switch (generalPrefs.themeMode) { + BackgroundThemeMode.light => ThemeMode.light, + BackgroundThemeMode.dark => ThemeMode.dark, + BackgroundThemeMode.system => ThemeMode.system, }, + builder: + Theme.of(context).platform == TargetPlatform.iOS + ? (context, child) { + // return CupertinoTheme( + // data: cupertinoThemeData, + // child: IconTheme.merge( + // data: IconThemeData( + // color: CupertinoTheme.of(context).textTheme.textStyle.color, + // ), + // child: Material(child: child), + // ), + // ); + return Material(child: child); + } + : null, + home: const BottomNavScaffold(), + navigatorObservers: [rootNavPageRouteObserver], ); } } - -/// The [AppTheme] defines light and dark themes for the app. -/// -/// Theme setup for FlexColorScheme package v8. -/// Use same major flex_color_scheme package version. If you use a -/// lower minor version, some properties may not be supported. -/// In that case, remove them after copying this theme to your -/// app or upgrade package to version 8.0.2. -/// -/// Use in [MaterialApp] like this: -/// -/// MaterialApp( -/// theme: AppTheme.light, -/// darkTheme: AppTheme.dark, -/// : -/// ); -sealed class AppTheme { - // The defined light theme. - static ThemeData light = FlexThemeData.light( - scheme: FlexScheme.espresso, - surfaceMode: FlexSurfaceMode.highBackgroundLowScaffold, - blendLevel: 1, - appBarStyle: FlexAppBarStyle.background, - bottomAppBarElevation: 2.0, - visualDensity: FlexColorScheme.comfortablePlatformDensity, - cupertinoOverrideTheme: const CupertinoThemeData(applyThemeToAll: true), - ); - // The defined dark theme. - static ThemeData dark = FlexThemeData.dark( - scheme: FlexScheme.espresso, - surfaceMode: FlexSurfaceMode.highBackgroundLowScaffold, - blendLevel: 16, - appBarStyle: FlexAppBarStyle.background, - bottomAppBarElevation: 2.0, - visualDensity: FlexColorScheme.comfortablePlatformDensity, - cupertinoOverrideTheme: const CupertinoThemeData(applyThemeToAll: true), - ); -} - -// -- - -(ColorScheme light, ColorScheme dark) _generateDynamicColourSchemes( - ColorScheme lightDynamic, - ColorScheme darkDynamic, -) { - final lightBase = ColorScheme.fromSeed(seedColor: lightDynamic.primary); - final darkBase = ColorScheme.fromSeed( - seedColor: darkDynamic.primary, - brightness: Brightness.dark, - ); - - final lightAdditionalColours = _extractAdditionalColours(lightBase); - final darkAdditionalColours = _extractAdditionalColours(darkBase); - - final lightScheme = _insertAdditionalColours(lightBase, lightAdditionalColours); - final darkScheme = _insertAdditionalColours(darkBase, darkAdditionalColours); - - return (lightScheme.harmonized(), darkScheme.harmonized()); -} - -List _extractAdditionalColours(ColorScheme scheme) => [ - scheme.surface, - scheme.surfaceDim, - scheme.surfaceBright, - scheme.surfaceContainerLowest, - scheme.surfaceContainerLow, - scheme.surfaceContainer, - scheme.surfaceContainerHigh, - scheme.surfaceContainerHighest, -]; - -ColorScheme _insertAdditionalColours(ColorScheme scheme, List additionalColours) => - scheme.copyWith( - surface: additionalColours[0], - surfaceDim: additionalColours[1], - surfaceBright: additionalColours[2], - surfaceContainerLowest: additionalColours[3], - surfaceContainerLow: additionalColours[4], - surfaceContainer: additionalColours[5], - surfaceContainerHigh: additionalColours[6], - surfaceContainerHighest: additionalColours[7], - ); diff --git a/lib/src/model/settings/general_preferences.dart b/lib/src/model/settings/general_preferences.dart index 7fa2643f2d..e02b8797f1 100644 --- a/lib/src/model/settings/general_preferences.dart +++ b/lib/src/model/settings/general_preferences.dart @@ -1,7 +1,9 @@ import 'dart:ui' show Locale; +import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:lichess_mobile/src/model/settings/preferences_storage.dart'; +import 'package:lichess_mobile/src/utils/color_palette.dart'; import 'package:lichess_mobile/src/utils/json.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -49,6 +51,10 @@ class GeneralPreferences extends _$GeneralPreferences with PreferencesStorage setAppThemeSeed(AppThemeSeed seed) { return save(state.copyWith(appThemeSeed: seed)); } + + Future setAppTheme(AppTheme appTheme) { + return save(state.copyWith(appTheme: appTheme)); + } } @Freezed(fromJson: true, toJson: true) @@ -62,6 +68,9 @@ class GeneralPrefs with _$GeneralPrefs implements Serializable { @Deprecated('Use appThemeSeed instead') bool? systemColors, + @JsonKey(unknownEnumValue: AppTheme.gold, defaultValue: AppTheme.gold) + required AppTheme appTheme, + /// App theme seed @JsonKey(unknownEnumValue: AppThemeSeed.board, defaultValue: AppThemeSeed.board) required AppThemeSeed appThemeSeed, @@ -76,6 +85,7 @@ class GeneralPrefs with _$GeneralPrefs implements Serializable { soundTheme: SoundTheme.standard, masterVolume: 0.8, appThemeSeed: AppThemeSeed.board, + appTheme: AppTheme.gold, ); factory GeneralPrefs.fromJson(Map json) { @@ -91,6 +101,71 @@ enum AppThemeSeed { board, } +enum AppTheme { + /// The app theme is based on the user's system theme (only available on Android 10+). + system, + + /// Below values from [FlexScheme] + blue, + indigo, + hippieBlue, + aquaBlue, + brandBlue, + deepBlue, + sakura, + mandyRed, + red, + redWine, + purpleBrown, + green, + money, + jungle, + greyLaw, + wasabi, + gold, + mango, + amber, + vesuviusBurn, + deepPurple, + ebonyClay, + barossa, + shark, + bigStone, + damask, + bahamaBlue, + mallardGreen, + espresso, + outerSpace, + blueWhale, + sanJuanBlue, + rosewood, + blumineBlue, + flutterDash, + materialBaseline, + verdunHemlock, + dellGenoa, + redM3, + pinkM3, + purpleM3, + indigoM3, + blueM3, + cyanM3, + tealM3, + greenM3, + limeM3, + yellowM3, + orangeM3, + deepOrangeM3, + blackWhite, + greys, + sepia; + + static final _flexSchemesNameMap = FlexScheme.values.asNameMap(); + + FlexSchemeData get flexScheme => + this == AppTheme.system ? getSystemScheme()! : _flexSchemesNameMap[name]!.data; +} + /// Describes the background theme of the app. enum BackgroundThemeMode { /// Use either the light or dark theme based on what the user has selected in diff --git a/lib/src/utils/color_palette.dart b/lib/src/utils/color_palette.dart index 6ecdd18d82..8e80820fac 100644 --- a/lib/src/utils/color_palette.dart +++ b/lib/src/utils/color_palette.dart @@ -2,23 +2,58 @@ import 'dart:ui'; import 'package:chessground/chessground.dart'; import 'package:dartchess/dartchess.dart'; +import 'package:dynamic_color/dynamic_color.dart'; +import 'package:flex_color_scheme/flex_color_scheme.dart' show FlexSchemeColor, FlexSchemeData; import 'package:material_color_utilities/material_color_utilities.dart'; CorePalette? _corePalette; +FlexSchemeData? _systemScheme; + ChessboardColorScheme? _boardColorScheme; /// Set the system core palette if available (android 12+ only). /// /// It also defines the system board colors based on the core palette. void setCorePalette(CorePalette? palette) { - _corePalette = palette; + _corePalette ??= palette; if (palette != null) { + final lightScheme = palette.toColorScheme(); + final darkScheme = palette.toColorScheme(brightness: Brightness.dark); + + _systemScheme ??= FlexSchemeData( + name: 'System', + description: 'System core palette on Android 12+', + light: FlexSchemeColor( + primary: lightScheme.primary, + primaryContainer: lightScheme.primaryContainer, + secondary: lightScheme.secondary, + secondaryContainer: lightScheme.secondaryContainer, + tertiary: lightScheme.tertiary, + tertiaryContainer: lightScheme.tertiaryContainer, + error: lightScheme.error, + errorContainer: lightScheme.errorContainer, + ), + dark: FlexSchemeColor( + primary: darkScheme.primary, + primaryContainer: darkScheme.primaryContainer, + primaryLightRef: lightScheme.primary, + secondary: darkScheme.secondary, + secondaryContainer: darkScheme.secondaryContainer, + secondaryLightRef: lightScheme.secondary, + tertiary: darkScheme.tertiary, + tertiaryContainer: darkScheme.tertiaryContainer, + tertiaryLightRef: lightScheme.tertiary, + error: darkScheme.error, + errorContainer: darkScheme.errorContainer, + ), + ); + final darkSquare = Color(palette.secondary.get(60)); final lightSquare = Color(palette.primary.get(95)); - _boardColorScheme = ChessboardColorScheme( + _boardColorScheme ??= ChessboardColorScheme( darkSquare: darkSquare, lightSquare: lightSquare, background: SolidColorChessboardBackground(lightSquare: lightSquare, darkSquare: darkSquare), @@ -50,6 +85,11 @@ CorePalette? getCorePalette() { return _corePalette; } +/// Get the system [FlexSchemeData] if available (android 12+ only). +FlexSchemeData? getSystemScheme() { + return _systemScheme; +} + /// Get the board colors based on the core palette, if available (android 12+). ChessboardColorScheme? getBoardColorScheme() { return _boardColorScheme; diff --git a/lib/src/view/play/quick_game_matrix.dart b/lib/src/view/play/quick_game_matrix.dart index 90ed0a6b0c..e657403579 100644 --- a/lib/src/view/play/quick_game_matrix.dart +++ b/lib/src/view/play/quick_game_matrix.dart @@ -142,7 +142,7 @@ class _ChoiceChip extends StatefulWidget { class _ChoiceChipState extends State<_ChoiceChip> { @override Widget build(BuildContext context) { - final cardColor = Theme.of(context).colorScheme.surfaceContainer.withValues(alpha: 0.7); + final cardColor = Theme.of(context).colorScheme.surfaceContainerHigh.withValues(alpha: 0.7); return Opacity( opacity: widget.onTap != null ? 1.0 : 0.5, diff --git a/lib/src/view/settings/app_theme_screen.dart b/lib/src/view/settings/app_theme_screen.dart new file mode 100644 index 0000000000..15baeec9fa --- /dev/null +++ b/lib/src/view/settings/app_theme_screen.dart @@ -0,0 +1,93 @@ +import 'package:flex_color_scheme/flex_color_scheme.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:lichess_mobile/src/model/settings/board_preferences.dart'; +import 'package:lichess_mobile/src/model/settings/general_preferences.dart'; +import 'package:lichess_mobile/src/utils/color_palette.dart'; +import 'package:lichess_mobile/src/utils/l10n_context.dart'; +import 'package:lichess_mobile/src/widgets/list.dart'; +import 'package:lichess_mobile/src/widgets/platform.dart'; + +class AppThemeScreen extends StatelessWidget { + const AppThemeScreen({super.key}); + + @override + Widget build(BuildContext context) { + return PlatformWidget(androidBuilder: _androidBuilder, iosBuilder: _iosBuilder); + } + + Widget _androidBuilder(BuildContext context) { + return Scaffold(appBar: AppBar(title: Text('Theme')), body: _Body()); + } + + Widget _iosBuilder(BuildContext context) { + return CupertinoPageScaffold(navigationBar: const CupertinoNavigationBar(), child: _Body()); + } +} + +class _Body extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) { + final appTheme = ref.watch(generalPreferencesProvider.select((p) => p.appTheme)); + + final hasSystemColors = getCorePalette() != null; + + final choices = AppTheme.values.where((t) => t != AppTheme.system || hasSystemColors).toList(); + + void onChanged(AppTheme? value) => + ref.read(generalPreferencesProvider.notifier).setAppTheme(value ?? AppTheme.gold); + + final checkedIcon = + Theme.of(context).platform == TargetPlatform.android + ? const Icon(Icons.check) + : Icon( + CupertinoIcons.check_mark_circled_solid, + color: CupertinoTheme.of(context).primaryColor, + ); + + final brightness = Theme.of(context).brightness; + + return SafeArea( + child: ListView.separated( + itemBuilder: (context, index) { + final t = choices[index]; + final fsd = t.flexScheme; + + return AdaptiveListTile( + // selected: t == appTheme, + leading: SizedBox( + width: 52, + height: 36, + child: FlexThemeModeOptionButton( + flexSchemeColor: brightness == Brightness.light ? fsd.light : fsd.dark, + selected: false, + unselectedBorder: BorderSide.none, + selectedBorder: BorderSide(color: Theme.of(context).colorScheme.outline, width: 3), + backgroundColor: Theme.of(context).colorScheme.surface, + width: 26, + height: 18, + padding: EdgeInsets.zero, + borderRadius: 0, + optionButtonPadding: EdgeInsets.zero, + optionButtonMargin: EdgeInsets.zero, + optionButtonBorderRadius: 4, + ), + ), + trailing: t == appTheme ? checkedIcon : null, + title: Text(fsd.name), + onTap: () => onChanged(t), + ); + }, + separatorBuilder: + (_, __) => PlatformDivider( + height: 1, + // on iOS: 52 (leading) + 14 (default indent) + 16 (padding) + indent: Theme.of(context).platform == TargetPlatform.iOS ? 52 + 14 + 16 : null, + color: Theme.of(context).platform == TargetPlatform.iOS ? null : Colors.transparent, + ), + itemCount: choices.length, + ), + ); + } +} diff --git a/lib/src/view/settings/theme_screen.dart b/lib/src/view/settings/theme_screen.dart index 8fe386ed46..88e8392f37 100644 --- a/lib/src/view/settings/theme_screen.dart +++ b/lib/src/view/settings/theme_screen.dart @@ -14,6 +14,7 @@ import 'package:lichess_mobile/src/utils/color_palette.dart'; import 'package:lichess_mobile/src/utils/l10n_context.dart'; import 'package:lichess_mobile/src/utils/navigation.dart'; import 'package:lichess_mobile/src/utils/screen.dart'; +import 'package:lichess_mobile/src/view/settings/app_theme_screen.dart'; import 'package:lichess_mobile/src/view/settings/board_theme_screen.dart'; import 'package:lichess_mobile/src/view/settings/piece_set_screen.dart'; import 'package:lichess_mobile/src/widgets/adaptive_action_sheet.dart'; @@ -170,43 +171,55 @@ class _BodyState extends ConsumerState<_Body> { ListSection( hasLeading: true, children: [ - if (getCorePalette() != null) - SettingsListTile( - icon: const Icon(Icons.colorize_outlined), - settingsLabel: const Text('Color scheme'), - settingsValue: switch (generalPrefs.appThemeSeed) { - AppThemeSeed.board => context.l10n.board, - AppThemeSeed.system => context.l10n.mobileSystemColors, - }, - onTap: () { - showAdaptiveActionSheet( - context: context, - actions: - AppThemeSeed.values - .where( - (t) => t != AppThemeSeed.system || getCorePalette() != null, - ) - .map( - (t) => BottomSheetAction( - makeLabel: - (context) => switch (t) { - AppThemeSeed.board => Text(context.l10n.board), - AppThemeSeed.system => Text( - context.l10n.mobileSystemColors, - ), - }, - onPressed: (context) { - ref - .read(generalPreferencesProvider.notifier) - .setAppThemeSeed(t); - }, - dismissOnPress: true, - ), - ) - .toList(), - ); - }, - ), + // if (getCorePalette() != null) + // SettingsListTile( + // icon: const Icon(Icons.colorize_outlined), + // settingsLabel: const Text('Color scheme'), + // settingsValue: switch (generalPrefs.appThemeSeed) { + // AppThemeSeed.board => context.l10n.board, + // AppThemeSeed.system => context.l10n.mobileSystemColors, + // }, + // onTap: () { + // showAdaptiveActionSheet( + // context: context, + // actions: + // AppThemeSeed.values + // .where( + // (t) => t != AppThemeSeed.system || getCorePalette() != null, + // ) + // .map( + // (t) => BottomSheetAction( + // makeLabel: + // (context) => switch (t) { + // AppThemeSeed.board => Text(context.l10n.board), + // AppThemeSeed.system => Text( + // context.l10n.mobileSystemColors, + // ), + // }, + // onPressed: (context) { + // ref + // .read(generalPreferencesProvider.notifier) + // .setAppThemeSeed(t); + // }, + // dismissOnPress: true, + // ), + // ) + // .toList(), + // ); + // }, + // ), + SettingsListTile( + icon: const Icon(Icons.palette), + settingsLabel: Text('Theme'), + settingsValue: generalPrefs.appTheme.flexScheme.name, + onTap: () { + pushPlatformRoute( + context, + title: 'Theme', + builder: (context) => const AppThemeScreen(), + ); + }, + ), SettingsListTile( icon: const Icon(LichessIcons.chess_board), settingsLabel: Text(context.l10n.board), diff --git a/lib/src/view/study/study_gamebook.dart b/lib/src/view/study/study_gamebook.dart index c12c09ed5e..716a393771 100644 --- a/lib/src/view/study/study_gamebook.dart +++ b/lib/src/view/study/study_gamebook.dart @@ -5,6 +5,7 @@ import 'package:lichess_mobile/src/model/common/id.dart'; import 'package:lichess_mobile/src/model/study/study_controller.dart'; import 'package:lichess_mobile/src/utils/l10n_context.dart'; import 'package:lichess_mobile/src/widgets/buttons.dart'; +import 'package:lichess_mobile/src/widgets/platform.dart'; import 'package:url_launcher/url_launcher.dart'; class StudyGamebook extends StatelessWidget { @@ -19,7 +20,8 @@ class StudyGamebook extends StatelessWidget { child: Column( children: [ Expanded( - child: Card( + child: PlatformCard( + margin: const EdgeInsets.all(8.0), child: Padding( padding: const EdgeInsets.all(10), child: Column( diff --git a/lib/src/widgets/list.dart b/lib/src/widgets/list.dart index 87e02b4980..fdc880f6d9 100644 --- a/lib/src/widgets/list.dart +++ b/lib/src/widgets/list.dart @@ -182,7 +182,7 @@ class ListSection extends StatelessWidget { decoration: BoxDecoration( color: cupertinoBackgroundColor ?? - Theme.of(context).colorScheme.surfaceContainer, + Theme.of(context).colorScheme.surfaceContainerHigh, borderRadius: cupertinoBorderRadius ?? const BorderRadius.all(Radius.circular(10.0)), ), diff --git a/pubspec.lock b/pubspec.lock index 8d08b19b76..2d5d995d47 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -530,18 +530,18 @@ packages: dependency: "direct main" description: name: flex_color_scheme - sha256: "90f4fe67b9561ae8a4af117df65a8ce9988624025667c54e6d304e65cff77d52" + sha256: "09bea5d776f694c5a67f2229f2aa500cc7cce369322dc6500ab01cf9ad1b4e1a" url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "8.1.0" flex_seed_scheme: dependency: transitive description: name: flex_seed_scheme - sha256: "7639d2c86268eff84a909026eb169f008064af0fb3696a651b24b0fa24a40334" + sha256: d3ba3c5c92d2d79d45e94b4c6c71d01fac3c15017da1545880c53864da5dfeb0 url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.5.0" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index c62da5ce0b..dd638a22ae 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,7 +31,7 @@ dependencies: firebase_crashlytics: ^4.0.0 firebase_messaging: ^15.0.0 fl_chart: ^0.70.0 - flex_color_scheme: ^8.0.2 + flex_color_scheme: ^8.1.0 flutter: sdk: flutter flutter_appauth: ^8.0.0+1