diff --git a/lib/components/settings/color_scheme_picker_dialog.dart b/lib/components/settings/color_scheme_picker_dialog.dart index 735f1e31d..c7e4988f7 100644 --- a/lib/components/settings/color_scheme_picker_dialog.dart +++ b/lib/components/settings/color_scheme_picker_dialog.dart @@ -16,7 +16,6 @@ final colorsMap = { "Teal": Colors.teal, "Green": Colors.green, "LightGreen": Colors.lightGreen, - "Lime": Colors.lime, "Yellow": Colors.yellow, "Amber": Colors.amber, "Orange": Colors.orange, @@ -74,25 +73,22 @@ class ColorSchemePickerDialog extends HookConsumerWidget { content: SizedBox( height: 200, width: 400, - child: SingleChildScrollView( - child: Center( - child: Wrap( - spacing: 10, - runSpacing: 10, - children: colorsMap.entries - .map( - (e) => ColorTile( - color: e.value, - isActive: active.value == e.key, - tooltip: e.key, - onPressed: () { - active.value = e.key; - }, - ), - ) - .toList(), - ), - ), + child: ListView.separated( + separatorBuilder: (context, index) { + return const SizedBox(height: 10); + }, + itemCount: colorsMap.length, + itemBuilder: (context, index) { + final color = colorsMap.entries.elementAt(index); + return ColorTile( + color: color.value, + isActive: active.value == color.key, + onPressed: () { + active.value = color.key; + }, + tooltip: color.key, + ); + }, ), ), ); @@ -104,32 +100,118 @@ class ColorTile extends StatelessWidget { 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, Key? key, }) : super(key: key); + factory ColorTile.compact({ + required MaterialColor 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[100]!, + width: 4, + ), + ) + : null, + borderRadius: BorderRadius.circular(15), + color: color, + ), + ); + + if (isCompact) { + return Tooltip( + message: tooltip, + child: GestureDetector( + onTap: onPressed, + child: lead, + ), + ); + } + + final colorScheme = ColorScheme.fromSwatch(primarySwatch: color); + + final palette = [ + colorScheme.primary, + colorScheme.inversePrimary, + colorScheme.primaryContainer, + colorScheme.secondary, + colorScheme.secondaryContainer, + colorScheme.background, + colorScheme.surface, + colorScheme.surfaceVariant, + colorScheme.onPrimary, + colorScheme.onSurface, + ]; + return Tooltip( message: tooltip, child: GestureDetector( onTap: onPressed, - child: Container( - height: 50, - width: 50, - decoration: BoxDecoration( - border: isActive - ? const Border.fromBorderSide( - BorderSide(color: Colors.black, width: 5), - ) - : null, - shape: BoxShape.circle, - color: color, - ), + 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), + ), + ), + ), + ], + ), + ], ), ), ); diff --git a/lib/pages/artist/artist.dart b/lib/pages/artist/artist.dart index e71e09222..3fddf5b09 100644 --- a/lib/pages/artist/artist.dart +++ b/lib/pages/artist/artist.dart @@ -1,4 +1,4 @@ -import 'package:fl_query/fl_query.dart'; +import 'package:fl_query_hooks/fl_query_hooks.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -60,6 +60,8 @@ class ArtistPage extends HookConsumerWidget { final auth = ref.watch(AuthenticationNotifier.provider); + final queryClient = useQueryClient(); + return SafeArea( bottom: false, child: Scaffold( @@ -172,6 +174,30 @@ class ArtistPage extends HookConsumerWidget { .artist .doIFollow(ref, artistId); + final followUnfollow = + useCallback(() async { + try { + isFollowingQuery.data! + ? await spotify.me.unfollow( + FollowingType.artist, + [artistId], + ) + : await spotify.me.follow( + FollowingType.artist, + [artistId], + ); + await isFollowingQuery.refresh(); + + queryClient + .refreshInfiniteQueryAllPages( + "user-following-artists"); + } finally { + queryClient.refreshQuery( + "user-follows-artists-query/$artistId", + ); + } + }, [isFollowingQuery]); + if (isFollowingQuery.isLoading || !isFollowingQuery.hasData) { return const SizedBox( @@ -181,36 +207,16 @@ class ArtistPage extends HookConsumerWidget { ); } - final queryBowl = - QueryClient.of(context); + if (isFollowingQuery.data!) { + return OutlinedButton( + onPressed: followUnfollow, + child: const Text("Following"), + ); + } return FilledButton( - onPressed: () async { - try { - isFollowingQuery.data! - ? await spotify.me.unfollow( - FollowingType.artist, - [artistId], - ) - : await spotify.me.follow( - FollowingType.artist, - [artistId], - ); - await isFollowingQuery.refresh(); - - queryBowl - .refreshInfiniteQueryAllPages( - "user-following-artists"); - } finally { - QueryClient.of(context).refreshQuery( - "user-follows-artists-query/$artistId"); - } - }, - child: Text( - isFollowingQuery.data! - ? "Following" - : "Follow", - ), + onPressed: followUnfollow, + child: const Text("Follow"), ); }, ), diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index a6f429bc6..e9630b8ee 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -67,17 +67,13 @@ class SettingsPage extends HookConsumerWidget { SpotubeIcons.login, color: theme.colorScheme.primary, ), - title: SizedBox( - height: 50, - width: 200, - child: Align( - alignment: Alignment.centerLeft, - child: AutoSizeText( - "Login with your Spotify account", - maxLines: 1, - style: TextStyle( - color: theme.colorScheme.primary, - ), + title: Align( + alignment: Alignment.centerLeft, + child: AutoSizeText( + "Login with your Spotify account", + maxLines: 1, + style: TextStyle( + color: theme.colorScheme.primary, ), ), ), @@ -197,7 +193,7 @@ class SettingsPage extends HookConsumerWidget { horizontal: 15, vertical: 5, ), - trailing: ColorTile( + trailing: ColorTile.compact( color: preferences.accentColorScheme, onPressed: pickColorScheme(ColorSchemeType.accent), isActive: true, diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 49caffbfd..f0ef6709e 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) screen_retriever_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); + g_autoptr(FlPluginRegistrar) system_theme_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SystemThemePlugin"); + system_theme_plugin_register_with_registrar(system_theme_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 81a1f2e11..d47b37c9d 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST catcher metadata_god screen_retriever + system_theme url_launcher_linux window_manager window_size diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 3ded505b4..57de7f06f 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -16,6 +16,7 @@ import path_provider_foundation import screen_retriever import shared_preferences_foundation import sqflite +import system_theme import url_launcher_macos import window_manager import window_size @@ -32,6 +33,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + SystemThemePlugin.register(with: registry.registrar(forPlugin: "SystemThemePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) WindowSizePlugin.register(with: registry.registrar(forPlugin: "WindowSizePlugin")) diff --git a/pubspec.lock b/pubspec.lock index b8e1490cf..721e0dac1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1548,6 +1548,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + system_theme: + dependency: "direct main" + description: + name: system_theme + sha256: "28bb63b997c252eee7fea6dc9e3528a9a6bf4b566ccbc8b49926389ca3e2c96b" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + system_theme_web: + dependency: transitive + description: + name: system_theme_web + sha256: "7566f5a928f6d28d7a60c97bea8a851d1c6bc9b86a4df2366230a97458489219" + url: "https://pub.dev" + source: hosted + version: "0.0.2" term_glyph: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1f1f82ee8..b34639694 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -69,6 +69,7 @@ dependencies: git: url: https://github.com/rinukkusu/spotify-dart ref: 9e8ef4556942d42d74874de5491253156e7e6f43 + system_theme: ^2.1.0 titlebar_buttons: ^1.0.0 tuple: ^2.0.1 url_launcher: ^6.1.7 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 245222383..b6e567c05 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); + SystemThemePluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SystemThemePlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowManagerPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b8a3a01b4..2a1df701e 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST metadata_god permission_handler_windows screen_retriever + system_theme url_launcher_windows window_manager window_size