diff --git a/lib/main.dart b/lib/main.dart index 8025f7cc..af7da1b7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -26,6 +26,7 @@ import 'package:spotube/hooks/configurators/use_fix_window_stretching.dart'; import 'package:spotube/hooks/configurators/use_get_storage_perms.dart'; import 'package:spotube/hooks/configurators/use_has_touch.dart'; import 'package:spotube/models/database/database.dart'; +import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/provider/audio_player/audio_player_streams.dart'; import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/glance/glance.dart'; @@ -43,7 +44,6 @@ import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/wm_tools/wm_tools.dart'; import 'package:spotube/utils/migrations/sandbox.dart'; import 'package:spotube/utils/platform.dart'; -import 'package:system_theme/system_theme.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; @@ -83,8 +83,6 @@ Future main(List rawArgs) async { await windowManager.setPreventClose(true); } - await SystemTheme.accentColor.load(); - if (!kIsWeb) { MetadataGod.initialize(); } @@ -133,8 +131,8 @@ class Spotube extends HookConsumerWidget { final themeMode = ref.watch(userPreferencesProvider.select((s) => s.themeMode)); final locale = ref.watch(userPreferencesProvider.select((s) => s.locale)); - // final accentMaterialColor = - // ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); + final accentMaterialColor = + ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); // final isAmoledTheme = // ref.watch(userPreferencesProvider.select((s) => s.amoledDarkTheme)); // final paletteColor = @@ -217,14 +215,18 @@ class Spotube extends HookConsumerWidget { theme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.lightOrange(), + colorScheme: + colorSchemeMap[accentMaterialColor.name]?.call(ThemeMode.light) ?? + ColorSchemes.lightOrange(), surfaceOpacity: .8, surfaceBlur: 10, ), darkTheme: ThemeData( radius: .5, iconTheme: const IconThemeProperties(), - colorScheme: ColorSchemes.darkOrange(), + colorScheme: + colorSchemeMap[accentMaterialColor.name]?.call(ThemeMode.dark) ?? + ColorSchemes.darkOrange(), surfaceOpacity: .8, surfaceBlur: 10, ), diff --git a/lib/modules/home/sections/feed.dart b/lib/modules/home/sections/feed.dart index bce2ea5b..34a9ee4b 100644 --- a/lib/modules/home/sections/feed.dart +++ b/lib/modules/home/sections/feed.dart @@ -1,6 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/horizontal_playbutton_card_view/horizontal_playbutton_card_view.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/pages/home/feed/feed_section.dart'; @@ -38,18 +37,14 @@ class HomePageFeedSection extends HookConsumerWidget { hasNextPage: false, isLoadingNextPage: false, onFetchMore: () {}, - titleTrailing: Directionality( - textDirection: TextDirection.rtl, - child: Button.link( - leading: const Icon(SpotubeIcons.angleRight), - child: Text(context.l10n.browse_more), - onPressed: () => ServiceUtils.pushNamed( - context, - HomeFeedSectionPage.name, - pathParameters: { - "feedId": section.uri, - }, - ), + titleTrailing: Button.text( + child: Text(context.l10n.browse_all), + onPressed: () => ServiceUtils.pushNamed( + context, + HomeFeedSectionPage.name, + pathParameters: { + "feedId": section.uri, + }, ), ), ); diff --git a/lib/modules/home/sections/genres/genres.dart b/lib/modules/home/sections/genres/genres.dart index 520c1121..5e96f78f 100644 --- a/lib/modules/home/sections/genres/genres.dart +++ b/lib/modules/home/sections/genres/genres.dart @@ -74,7 +74,6 @@ class HomeGenresSection extends HookConsumerWidget { onPressed: () { context.pushNamed(GenrePage.name); }, - trailing: const Icon(SpotubeIcons.angleRight), child: Text( context.l10n.browse_all, ).muted(), diff --git a/lib/modules/settings/color_scheme_picker_dialog.dart b/lib/modules/settings/color_scheme_picker_dialog.dart index f2933505..8092f825 100644 --- a/lib/modules/settings/color_scheme_picker_dialog.dart +++ b/lib/modules/settings/color_scheme_picker_dialog.dart @@ -1,10 +1,11 @@ -import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:system_theme/system_theme.dart'; class SpotubeColor extends Color { final String name; @@ -25,23 +26,33 @@ class SpotubeColor extends Color { } final Set colorsMap = { - SpotubeColor(SystemTheme.accentColor.accent.value, name: "System"), - SpotubeColor(Colors.red.value, name: "Red"), - SpotubeColor(Colors.pink.value, name: "Pink"), - SpotubeColor(Colors.purple.value, name: "Purple"), - SpotubeColor(Colors.deepPurple.value, name: "DeepPurple"), - SpotubeColor(Colors.indigo.value, name: "Indigo"), - SpotubeColor(Colors.blue.value, name: "Blue"), - SpotubeColor(Colors.lightBlue.value, name: "LightBlue"), - SpotubeColor(Colors.cyan.value, name: "Cyan"), - SpotubeColor(Colors.teal.value, name: "Teal"), - SpotubeColor(Colors.green.value, name: "Green"), - SpotubeColor(Colors.lightGreen.value, name: "LightGreen"), - SpotubeColor(Colors.yellow.value, name: "Yellow"), - SpotubeColor(Colors.amber.value, name: "Amber"), - SpotubeColor(Colors.orange.value, name: "Orange"), - SpotubeColor(Colors.deepOrange.value, name: "DeepOrange"), - SpotubeColor(Colors.brown.value, name: "Brown"), + SpotubeColor(Colors.slate.value, name: "slate"), + SpotubeColor(Colors.gray.value, name: "gray"), + SpotubeColor(Colors.zinc.value, name: "zinc"), + SpotubeColor(Colors.neutral.value, name: "neutral"), + SpotubeColor(Colors.stone.value, name: "stone"), + SpotubeColor(Colors.red.value, name: "red"), + SpotubeColor(Colors.orange.value, name: "orange"), + SpotubeColor(Colors.yellow.value, name: "yellow"), + SpotubeColor(Colors.green.value, name: "green"), + SpotubeColor(Colors.blue.value, name: "blue"), + SpotubeColor(Colors.violet.value, name: "violet"), + SpotubeColor(Colors.rose.value, name: "rose"), +}; + +final colorSchemeMap = { + "slate": ColorSchemes.slate, + "gray": ColorSchemes.gray, + "zinc": ColorSchemes.zinc, + "neutral": ColorSchemes.neutral, + "stone": ColorSchemes.stone, + "red": ColorSchemes.red, + "orange": ColorSchemes.orange, + "yellow": ColorSchemes.yellow, + "green": ColorSchemes.green, + "blue": ColorSchemes.blue, + "violet": ColorSchemes.violet, + "rose": ColorSchemes.rose, }; class ColorSchemePickerDialog extends HookConsumerWidget { @@ -51,180 +62,93 @@ class ColorSchemePickerDialog extends HookConsumerWidget { Widget build(BuildContext context, ref) { final preferences = ref.watch(userPreferencesProvider); final preferencesNotifier = ref.watch(userPreferencesProvider.notifier); - final scheme = preferences.accentColorScheme; - final active = useState(colorsMap.firstWhere( - (element) { - return scheme.name == element.name; - }, - ).name); - onOk() { - preferencesNotifier.setAccentColorScheme( - colorsMap.firstWhere( - (element) { - return element.name == active.value; - }, - ), - ); - Navigator.pop(context); - } + final scheme = preferences.accentColorScheme; + final active = useState( + colorsMap.firstWhereOrNull( + (element) { + return scheme.name == element.name; + }, + )?.name, + ); return AlertDialog( - title: Text(context.l10n.pick_color_scheme), + title: Text( + context.l10n.pick_color_scheme, + style: TextStyle(color: context.theme.colorScheme.foreground), + ).large(), actions: [ - OutlinedButton( + Button.outline( child: Text(context.l10n.cancel), onPressed: () { Navigator.pop(context); }, ), - FilledButton( - onPressed: onOk, + Button.primary( + onPressed: () { + Navigator.pop(context); + }, child: Text(context.l10n.save), ), ], content: SizedBox( height: 200, width: 400, - child: ListView.separated( - separatorBuilder: (context, index) { - return const SizedBox(height: 10); - }, - itemCount: colorsMap.length, - itemBuilder: (context, index) { - final color = colorsMap.elementAt(index); - return ColorTile( - color: color, - isActive: active.value == color.name, - onPressed: () { - active.value = color.name; - }, - tooltip: color.name, - ); - }, + child: Wrap( + spacing: 8, + runSpacing: 8, + children: colorsMap.map( + (color) { + return ColorChip( + name: color.name, + color: color, + isActive: color.name == active.value, + onPressed: () { + active.value = color.name; + preferencesNotifier.setAccentColorScheme( + colorsMap.firstWhere( + (element) { + return element.name == color.name; + }, + ), + ); + }, + ); + }, + ).toList(), ), ), ); } } -class ColorTile extends StatelessWidget { +class ColorChip extends StatelessWidget { + final String name; final Color color; final bool isActive; - final void Function()? onPressed; - final String? tooltip; - final bool isCompact; - const ColorTile({ - required this.color, - this.isActive = false, - this.onPressed, - this.tooltip = "", - this.isCompact = false, + final VoidCallback onPressed; + const ColorChip({ super.key, + required this.name, + required this.color, + required this.isActive, + required this.onPressed, }); - factory ColorTile.compact({ - required Color color, - bool isActive = false, - void Function()? onPressed, - String? tooltip = "", - Key? key, - }) { - return ColorTile( - color: color, - isActive: isActive, - onPressed: onPressed, - tooltip: tooltip, - isCompact: true, - key: key, - ); - } - @override Widget build(BuildContext context) { - final theme = Theme.of(context); - - final lead = Container( - height: 40, - width: 40, - decoration: BoxDecoration( - border: isActive - ? Border.fromBorderSide( - BorderSide( - color: Color.lerp( - theme.colorScheme.primary, - theme.colorScheme.onPrimary, - 0.5, - )!, - width: 4, - ), - ) - : null, - borderRadius: BorderRadius.circular(15), - color: color, - ), - ); - - if (isCompact) { - return GestureDetector( - onTap: onPressed, - child: lead, - ); - } - - final colorScheme = ColorScheme.fromSeed(seedColor: color); - - final palette = [ - colorScheme.primary, - colorScheme.inversePrimary, - colorScheme.primaryContainer, - colorScheme.secondary, - colorScheme.secondaryContainer, - colorScheme.surface, - colorScheme.surface, - colorScheme.surfaceContainerHighest, - colorScheme.onPrimary, - colorScheme.onSurface, - ]; - - return GestureDetector( - onTap: onPressed, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - lead, - const SizedBox(width: 10), - Text( - tooltip!, - style: theme.textTheme.bodyLarge?.copyWith( - color: theme.colorScheme.primary, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - const SizedBox(height: 10), - Wrap( - alignment: WrapAlignment.start, - spacing: 10, - runSpacing: 10, - children: [ - ...palette.map( - (e) => Container( - height: 20, - width: 20, - decoration: BoxDecoration( - color: e, - borderRadius: BorderRadius.circular(5), - ), - ), - ), - ], - ), - ], + return Chip( + leading: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(10), + ), ), + onPressed: onPressed, + style: isActive ? ButtonVariance.primary : ButtonVariance.outline, + child: Text(name), ); } } diff --git a/lib/pages/settings/sections/appearance.dart b/lib/pages/settings/sections/appearance.dart index aaa2ce8a..55a8f1ef 100644 --- a/lib/pages/settings/sections/appearance.dart +++ b/lib/pages/settings/sections/appearance.dart @@ -94,10 +94,11 @@ class SettingsAppearanceSection extends HookConsumerWidget { horizontal: 15, vertical: 5, ), - trailing: ColorTile.compact( + trailing: ColorChip( color: preferences.accentColorScheme, + name: preferences.accentColorScheme.name, onPressed: pickColorScheme(), - isActive: true, + isActive: false, ), onTap: pickColorScheme(), ),