mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
feat: album art dominant color as accent color (#447)
This commit is contained in:
parent
cac8ea6388
commit
31b9249cc8
@ -76,4 +76,5 @@ abstract class SpotubeIcons {
|
||||
static const hoverOff = Icons.back_hand_outlined;
|
||||
static const dragHandle = Icons.drag_indicator;
|
||||
static const lightning = Icons.flash_on_rounded;
|
||||
static const colorSync = FeatherIcons.activity;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import 'package:spotube/collections/routes.dart';
|
||||
import 'package:spotube/collections/intents.dart';
|
||||
import 'package:spotube/models/logger.dart';
|
||||
import 'package:spotube/provider/downloader_provider.dart';
|
||||
import 'package:spotube/provider/palette_provider.dart';
|
||||
import 'package:spotube/provider/user_preferences_provider.dart';
|
||||
import 'package:spotube/services/audio_player.dart';
|
||||
import 'package:spotube/services/pocketbase.dart';
|
||||
@ -188,6 +189,8 @@ class SpotubeState extends ConsumerState<Spotube> {
|
||||
ref.watch(userPreferencesProvider.select((s) => s.themeMode));
|
||||
final accentMaterialColor =
|
||||
ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme));
|
||||
final paletteColor =
|
||||
ref.watch(paletteProvider.select((s) => s?.dominantColor?.color));
|
||||
|
||||
useInitSysTray(ref);
|
||||
|
||||
@ -209,8 +212,8 @@ class SpotubeState extends ConsumerState<Spotube> {
|
||||
return DragToResizeArea(child: child!);
|
||||
},
|
||||
themeMode: themeMode,
|
||||
theme: theme(accentMaterialColor, Brightness.light),
|
||||
darkTheme: theme(accentMaterialColor, Brightness.dark),
|
||||
theme: theme(paletteColor ?? accentMaterialColor, Brightness.light),
|
||||
darkTheme: theme(paletteColor ?? accentMaterialColor, Brightness.dark),
|
||||
shortcuts: {
|
||||
...WidgetsApp.defaultShortcuts.map((key, value) {
|
||||
return MapEntry(
|
||||
|
@ -203,6 +203,15 @@ class SettingsPage extends HookConsumerWidget {
|
||||
),
|
||||
onTap: pickColorScheme(),
|
||||
),
|
||||
SwitchListTile(
|
||||
secondary: const Icon(SpotubeIcons.colorSync),
|
||||
title: const Text("Sync Album Color"),
|
||||
subtitle: const Text(
|
||||
"Uses the dominant color of the album art as the accent color",
|
||||
),
|
||||
value: preferences.albumColorSync,
|
||||
onChanged: preferences.setAlbumColorSync,
|
||||
),
|
||||
Text(
|
||||
" Playback",
|
||||
style: theme.textTheme.headlineSmall
|
||||
|
4
lib/provider/palette_provider.dart
Normal file
4
lib/provider/palette_provider.dart
Normal file
@ -0,0 +1,4 @@
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final paletteProvider = StateProvider<PaletteGenerator?>((ref) => null);
|
@ -2,11 +2,14 @@ import 'package:audio_service/audio_service.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/shared/image/universal_image.dart';
|
||||
import 'package:spotube/models/local_track.dart';
|
||||
import 'package:spotube/models/spotube_track.dart';
|
||||
import 'package:spotube/extensions/track.dart';
|
||||
import 'package:spotube/provider/blacklist_provider.dart';
|
||||
import 'package:spotube/provider/palette_provider.dart';
|
||||
import 'package:spotube/provider/user_preferences_provider.dart';
|
||||
import 'package:spotube/services/audio_player.dart';
|
||||
import 'package:spotube/services/linux_audio_service.dart';
|
||||
@ -532,6 +535,30 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
state = state!.copyWith(tracks: Set.from(tracks), active: active);
|
||||
}
|
||||
|
||||
Future<void> updatePalette() async {
|
||||
final palette = await PaletteGenerator.fromImageProvider(
|
||||
UniversalImage.imageProvider(
|
||||
TypeConversionUtils.image_X_UrlString(
|
||||
state?.activeTrack.album?.images,
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
height: 50,
|
||||
width: 50,
|
||||
),
|
||||
);
|
||||
ref.read(paletteProvider.notifier).state = palette;
|
||||
}
|
||||
|
||||
@override
|
||||
set state(state) {
|
||||
if (preferences.albumColorSync &&
|
||||
state != null &&
|
||||
state.active != this.state?.active) {
|
||||
updatePalette();
|
||||
}
|
||||
super.state = state;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PlaylistQueue>? fromJson(Map<String, dynamic> json) {
|
||||
if (json.isEmpty) return null;
|
||||
|
@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:spotube/components/settings/color_scheme_picker_dialog.dart';
|
||||
import 'package:spotube/provider/palette_provider.dart';
|
||||
import 'package:spotube/provider/playlist_queue_provider.dart';
|
||||
|
||||
import 'package:spotube/utils/persisted_change_notifier.dart';
|
||||
import 'package:spotube/utils/platform.dart';
|
||||
@ -33,6 +35,7 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
AudioQuality audioQuality;
|
||||
|
||||
SpotubeColor accentColorScheme;
|
||||
bool albumColorSync;
|
||||
bool skipSponsorSegments;
|
||||
|
||||
String downloadLocation;
|
||||
@ -45,12 +48,16 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
|
||||
bool showSystemTrayIcon;
|
||||
|
||||
UserPreferences({
|
||||
final Ref ref;
|
||||
|
||||
UserPreferences(
|
||||
this.ref, {
|
||||
required this.recommendationMarket,
|
||||
required this.themeMode,
|
||||
required this.layoutMode,
|
||||
required this.predownload,
|
||||
required this.accentColorScheme,
|
||||
this.albumColorSync = true,
|
||||
this.saveTrackLyrics = false,
|
||||
this.checkUpdate = true,
|
||||
this.audioQuality = AudioQuality.high,
|
||||
@ -98,7 +105,13 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setBackgroundColorScheme(MaterialColor color) {
|
||||
void setAlbumColorSync(bool sync) {
|
||||
albumColorSync = sync;
|
||||
if (!sync) {
|
||||
ref.read(paletteProvider.notifier).state = null;
|
||||
} else {
|
||||
ref.read(PlaylistQueueNotifier.notifier).updatePalette();
|
||||
}
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
@ -168,6 +181,7 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
accentColorScheme = map["accentColorScheme"] != null
|
||||
? SpotubeColor.fromString(map["accentColorScheme"])
|
||||
: accentColorScheme;
|
||||
albumColorSync = map["albumColorSync"] ?? albumColorSync;
|
||||
audioQuality = map["audioQuality"] != null
|
||||
? AudioQuality.values[map["audioQuality"]]
|
||||
: audioQuality;
|
||||
@ -196,6 +210,7 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
"recommendationMarket": recommendationMarket,
|
||||
"themeMode": themeMode.index,
|
||||
"accentColorScheme": accentColorScheme.toString(),
|
||||
"albumColorSync": albumColorSync,
|
||||
"checkUpdate": checkUpdate,
|
||||
"audioQuality": audioQuality.index,
|
||||
"skipSponsorSegments": skipSponsorSegments,
|
||||
@ -209,7 +224,8 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
}
|
||||
|
||||
final userPreferencesProvider = ChangeNotifierProvider(
|
||||
(_) => UserPreferences(
|
||||
(ref) => UserPreferences(
|
||||
ref,
|
||||
accentColorScheme: SpotubeColor(Colors.blue.value, name: "Blue"),
|
||||
recommendationMarket: 'US',
|
||||
themeMode: ThemeMode.system,
|
||||
|
Loading…
Reference in New Issue
Block a user