feat(player): replace bg blur with gradient, proper fg color and align title and artist name

This commit is contained in:
Kingkor Roy Tirtho 2023-04-06 11:13:14 +06:00
parent 36396b7583
commit 159f03e7ca
7 changed files with 158 additions and 136 deletions

View File

@ -11,10 +11,10 @@ import 'package:spotube/provider/playlist_queue_provider.dart';
import 'package:spotube/utils/primitive_utils.dart';
class PlayerControls extends HookConsumerWidget {
final Color? iconColor;
final Color? color;
PlayerControls({
this.iconColor,
this.color,
Key? key,
}) : super(key: key);
@ -109,23 +109,26 @@ class PlayerControls extends HookConsumerWidget {
),
);
},
activeColor: iconColor,
activeColor: color,
inactiveColor: color?.withOpacity(0.15),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
child: DefaultTextStyle(
style:
theme.textTheme.bodySmall!.copyWith(color: color),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"$currentMinutes:$currentSeconds",
),
Text("$currentMinutes:$currentSeconds"),
Text("$totalMinutes:$totalSeconds"),
],
),
),
),
],
);
},
@ -157,7 +160,7 @@ class PlayerControls extends HookConsumerWidget {
tooltip: "Previous track",
icon: Icon(
SpotubeIcons.skipBack,
color: iconColor,
color: color,
),
onPressed: playlistNotifier.previous,
),
@ -171,7 +174,7 @@ class PlayerControls extends HookConsumerWidget {
)
: Icon(
playing ? SpotubeIcons.pause : SpotubeIcons.play,
color: iconColor,
color: color,
),
onPressed: Actions.handler<PlayPauseIntent>(
context,
@ -182,7 +185,7 @@ class PlayerControls extends HookConsumerWidget {
tooltip: "Next track",
icon: Icon(
SpotubeIcons.skipForward,
color: iconColor,
color: color,
),
onPressed: playlistNotifier.next,
),

View File

@ -144,10 +144,7 @@ class PlaylistHeartButton extends HookConsumerWidget {
),
[playlist.images]);
final color = usePaletteGenerator(
context,
titleImage,
).dominantColor;
final color = usePaletteGenerator(titleImage).dominantColor;
if (me.isLoading || !me.hasData) {
return const CircularProgressIndicator();

View File

@ -68,7 +68,7 @@ class _PageWindowTitleBarState extends State<PageWindowTitleBar> {
automaticallyImplyLeading: widget.automaticallyImplyLeading,
actions: [
...?widget.actions,
const WindowTitleBarButtons(),
WindowTitleBarButtons(foregroundColor: widget.foregroundColor),
],
backgroundColor: widget.backgroundColor,
foregroundColor: widget.foregroundColor,
@ -86,7 +86,11 @@ class _PageWindowTitleBarState extends State<PageWindowTitleBar> {
}
class WindowTitleBarButtons extends HookWidget {
const WindowTitleBarButtons({Key? key}) : super(key: key);
final Color? foregroundColor;
const WindowTitleBarButtons({
Key? key,
this.foregroundColor,
}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -110,7 +114,7 @@ class WindowTitleBarButtons extends HookWidget {
final theme = Theme.of(context);
final colors = WindowButtonColors(
normal: Colors.transparent,
iconNormal: theme.colorScheme.onBackground,
iconNormal: foregroundColor ?? theme.colorScheme.onBackground,
mouseOver: theme.colorScheme.onBackground.withOpacity(0.1),
mouseDown: theme.colorScheme.onBackground.withOpacity(0.2),
iconMouseOver: theme.colorScheme.onBackground,
@ -119,7 +123,7 @@ class WindowTitleBarButtons extends HookWidget {
final closeColors = WindowButtonColors(
normal: Colors.transparent,
iconNormal: theme.colorScheme.onBackground,
iconNormal: foregroundColor ?? theme.colorScheme.onBackground,
mouseOver: Colors.red,
mouseDown: Colors.red[800]!,
iconMouseOver: Colors.white,

View File

@ -66,10 +66,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
Widget build(BuildContext context, ref) {
final theme = Theme.of(context);
final auth = ref.watch(AuthenticationNotifier.provider);
final color = usePaletteGenerator(
context,
titleImage,
).dominantColor;
final color = usePaletteGenerator(titleImage).dominantColor;
final List<Widget> buttons = [
if (showShare)

View File

@ -12,6 +12,7 @@ final _paletteColorState = StateProvider<PaletteColor>(
PaletteColor usePaletteColor(String imageUrl, WidgetRef ref) {
final context = useContext();
final theme = Theme.of(context);
final paletteColor = ref.watch(_paletteColorState);
final mounted = useIsMounted();
@ -25,7 +26,7 @@ PaletteColor usePaletteColor(String imageUrl, WidgetRef ref) {
),
);
if (!mounted()) return;
final color = Theme.of(context).brightness == Brightness.light
final color = theme.brightness == Brightness.light
? palette.lightMutedColor ?? palette.lightVibrantColor
: palette.darkMutedColor ?? palette.darkVibrantColor;
if (color != null) {
@ -38,10 +39,7 @@ PaletteColor usePaletteColor(String imageUrl, WidgetRef ref) {
return paletteColor;
}
PaletteGenerator usePaletteGenerator(
BuildContext context,
String imageUrl,
) {
PaletteGenerator usePaletteGenerator(String imageUrl) {
final palette = useState(PaletteGenerator.fromColors([]));
final mounted = useIsMounted();

View File

@ -1,13 +1,11 @@
import 'dart:ui';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:palette_generator/palette_generator.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/collections/assets.gen.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/player/player_actions.dart';
import 'package:spotube/components/player/player_controls.dart';
@ -56,40 +54,64 @@ class PlayerView extends HookConsumerWidget {
[currentTrack?.album?.images],
);
final PaletteColor paletteColor = usePaletteColor(albumArt, ref);
final palette = usePaletteGenerator(albumArt);
final bgColor = palette.dominantColor?.color ?? theme.colorScheme.primary;
final titleTextColor = palette.dominantColor?.titleTextColor;
final bodyTextColor = palette.dominantColor?.bodyTextColor;
useCustomStatusBarColor(
paletteColor.color,
bgColor,
GoRouter.of(context).location == "/player",
noSetBGColor: true,
);
return Scaffold(
return IconTheme(
data: theme.iconTheme.copyWith(color: bodyTextColor),
child: Scaffold(
appBar: PageWindowTitleBar(
backgroundColor: Colors.transparent,
foregroundColor: paletteColor.titleTextColor,
foregroundColor: titleTextColor,
toolbarOpacity: 1,
leading: BackButton(color: paletteColor.titleTextColor),
leading: const BackButton(),
),
extendBodyBehindAppBar: true,
body: DecoratedBox(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: UniversalImage.imageProvider(albumArt),
fit: BoxFit.cover,
color: palette.dominantColor?.color,
gradient: LinearGradient(
colors: [
palette.dominantColor?.color ?? theme.colorScheme.primary,
palette.mutedColor?.color ?? theme.colorScheme.secondary,
],
transform: const GradientRotation(0.5),
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
alignment: Alignment.center,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 580),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
ClipRRect(
DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black26,
spreadRadius: 2,
blurRadius: 10,
offset: Offset(0, 0),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: UniversalImage(
path: albumArt,
placeholder: Assets.albumPlaceholder.path,
),
),
),
const SizedBox(height: 10),
@ -103,7 +125,7 @@ class PlayerView extends HookConsumerWidget {
currentTrack?.name ?? "Not playing",
style: TextStyle(
fontSize: 20,
color: paletteColor.titleTextColor,
color: titleTextColor,
),
maxLines: 1,
textAlign: TextAlign.start,
@ -115,7 +137,7 @@ class PlayerView extends HookConsumerWidget {
),
style: theme.textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.bold,
color: paletteColor.bodyTextColor,
color: bodyTextColor,
),
)
else
@ -123,7 +145,7 @@ class PlayerView extends HookConsumerWidget {
currentTrack?.artists ?? [],
textStyle: theme.textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.bold,
color: paletteColor.bodyTextColor,
color: bodyTextColor,
),
onRouteChange: (route) {
GoRouter.of(context).pop();
@ -134,7 +156,7 @@ class PlayerView extends HookConsumerWidget {
),
),
const SizedBox(height: 40),
PlayerControls(iconColor: paletteColor.bodyTextColor),
PlayerControls(color: bodyTextColor),
const Spacer(),
PlayerActions(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -175,6 +197,7 @@ class PlayerView extends HookConsumerWidget {
),
),
),
),
);
}
}

View File

@ -1778,4 +1778,4 @@ packages:
version: "1.12.3"
sdks:
dart: ">=2.19.2 <3.0.0"
flutter: ">=3.7.0"
flutter: ">=3.3.0"