From ee5c417ac396ef0b1796fa74a6a494181e6e0396 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Wed, 7 Dec 2022 13:27:46 +0600 Subject: [PATCH] fix: player view artist link when local playlist is playing, lyric delay adjust button alignment --- lib/components/Home/Genres.dart | 8 ++-- lib/components/Lyrics/SyncedLyrics.dart | 36 +++++++-------- lib/components/Player/PlayerActions.dart | 57 +++++++++++++----------- lib/components/Player/PlayerView.dart | 40 ++++++++++++----- lib/components/Shared/Waypoint.dart | 24 ++++++---- lib/themes/light-theme.dart | 12 +++++ 6 files changed, 107 insertions(+), 70 deletions(-) diff --git a/lib/components/Home/Genres.dart b/lib/components/Home/Genres.dart index b7af2ae20..efcf61b02 100644 --- a/lib/components/Home/Genres.dart +++ b/lib/components/Home/Genres.dart @@ -44,12 +44,14 @@ class Genres extends HookConsumerWidget { .toList() ]; + final isMounted = useIsMounted(); + return PlatformScaffold( appBar: kIsDesktop ? PageWindowTitleBar() : null, body: Waypoint( - onTouchEdge: () { - if (categoriesQuery.hasNextPage) { - categoriesQuery.fetchNextPage(); + onTouchEdge: () async { + if (categoriesQuery.hasNextPage && isMounted()) { + await categoriesQuery.fetchNextPage(); } }, controller: scrollController, diff --git a/lib/components/Lyrics/SyncedLyrics.dart b/lib/components/Lyrics/SyncedLyrics.dart index ea130908d..b87aca82e 100644 --- a/lib/components/Lyrics/SyncedLyrics.dart +++ b/lib/components/Lyrics/SyncedLyrics.dart @@ -71,7 +71,7 @@ class SyncedLyrics extends HookConsumerWidget { return Column( children: [ SizedBox( - height: breakpoint >= Breakpoints.md ? 50 : 30, + height: breakpoint >= Breakpoints.md ? 50 : 40, child: Material( type: MaterialType.transparency, textStyle: PlatformTheme.of(context).textTheme!.body!, @@ -84,27 +84,25 @@ class SyncedLyrics extends HookConsumerWidget { isHovering: true, ), ), - Positioned.fill( + Positioned( + top: 10, + right: 10, child: Align( alignment: Alignment.centerRight, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: PlatformFilledButton( - child: const Icon( - Icons.av_timer_rounded, - size: 16, - ), - onPressed: () async { - final delay = await showPlatformAlertDialog( - context, - builder: (context) => - const LyricDelayAdjustDialog(), - ); - if (delay != null) { - ref.read(lyricDelayState.notifier).state = delay; - } - }, + child: PlatformFilledButton( + child: const Icon( + Icons.av_timer_rounded, + size: 16, ), + onPressed: () async { + final delay = await showPlatformAlertDialog( + context, + builder: (context) => const LyricDelayAdjustDialog(), + ); + if (delay != null) { + ref.read(lyricDelayState.notifier).state = delay; + } + }, ), ), ), diff --git a/lib/components/Player/PlayerActions.dart b/lib/components/Player/PlayerActions.dart index 9b543d552..a851522e3 100644 --- a/lib/components/Player/PlayerActions.dart +++ b/lib/components/Player/PlayerActions.dart @@ -28,6 +28,7 @@ class PlayerActions extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final Playback playback = ref.watch(playbackProvider); + final isLocalTrack = playback.playlist?.isLocal == true; final downloader = ref.watch(downloaderProvider); final isInQueue = downloader.inQueue.any((element) => element.id == playback.track?.id); @@ -74,32 +75,33 @@ class PlayerActions extends HookConsumerWidget { } : null, ), - PlatformIconButton( - icon: const Icon(Icons.alt_route_rounded), - tooltip: "Alternative Track Sources", - onPressed: playback.track != null - ? () { - showModalBottomSheet( - context: context, - isDismissible: true, - enableDrag: true, - isScrollControlled: true, - backgroundColor: Colors.black12, - barrierColor: Colors.black12, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * .5, - ), - builder: (context) { - return SiblingTracksSheet(floating: floatingQueue); - }, - ); - } - : null, - ), - if (!kIsWeb) + if (!isLocalTrack) + PlatformIconButton( + icon: const Icon(Icons.alt_route_rounded), + tooltip: "Alternative Track Sources", + onPressed: playback.track != null + ? () { + showModalBottomSheet( + context: context, + isDismissible: true, + enableDrag: true, + isScrollControlled: true, + backgroundColor: Colors.black12, + barrierColor: Colors.black12, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * .5, + ), + builder: (context) { + return SiblingTracksSheet(floating: floatingQueue); + }, + ); + } + : null, + ), + if (!kIsWeb && !isLocalTrack) if (isInQueue) const SizedBox( height: 20, @@ -120,7 +122,8 @@ class PlayerActions extends HookConsumerWidget { ? () => downloader.addToQueue(playback.track!) : null, ), - if (playback.track != null) TrackHeartButton(track: playback.track!), + if (playback.track != null && !isLocalTrack) + TrackHeartButton(track: playback.track!), ...(extraActions ?? []) ], ); diff --git a/lib/components/Player/PlayerView.dart b/lib/components/Player/PlayerView.dart index 6075f8f7b..ffa7440c4 100644 --- a/lib/components/Player/PlayerView.dart +++ b/lib/components/Player/PlayerView.dart @@ -6,6 +6,7 @@ import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:palette_generator/palette_generator.dart'; import 'package:platform_ui/platform_ui.dart'; +import 'package:spotify/spotify.dart'; import 'package:spotube/components/Player/PlayerActions.dart'; import 'package:spotube/components/Player/PlayerControls.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; @@ -28,6 +29,9 @@ class PlayerView extends HookConsumerWidget { final currentTrack = ref.watch(playbackProvider.select( (value) => value.track, )); + final isLocalTrack = ref.watch(playbackProvider.select( + (value) => value.playlist?.isLocal == true, + )); final breakpoint = useBreakpoints(); final canRotate = ref.watch( userPreferencesProvider.select((s) => s.rotatingAlbumArt), @@ -102,18 +106,30 @@ class PlayerView extends HookConsumerWidget { isHovering: true, ), ), - TypeConversionUtils.artists_X_ClickableArtists( - currentTrack?.artists ?? [], - textStyle: - Theme.of(context).textTheme.headline6!.copyWith( - fontWeight: FontWeight.bold, - color: paletteColor.bodyTextColor, - ), - onRouteChange: (route) { - GoRouter.of(context).pop(); - GoRouter.of(context).push(route); - }, - ), + if (isLocalTrack) + Text( + TypeConversionUtils.artists_X_String( + currentTrack?.artists ?? [], + ), + style: + Theme.of(context).textTheme.headline6!.copyWith( + fontWeight: FontWeight.bold, + color: paletteColor.bodyTextColor, + ), + ) + else + TypeConversionUtils.artists_X_ClickableArtists( + currentTrack?.artists ?? [], + textStyle: + Theme.of(context).textTheme.headline6!.copyWith( + fontWeight: FontWeight.bold, + color: paletteColor.bodyTextColor, + ), + onRouteChange: (route) { + GoRouter.of(context).pop(); + GoRouter.of(context).push(route); + }, + ), ], ), ), diff --git a/lib/components/Shared/Waypoint.dart b/lib/components/Shared/Waypoint.dart index 128d19aba..78c7a2685 100644 --- a/lib/components/Shared/Waypoint.dart +++ b/lib/components/Shared/Waypoint.dart @@ -1,9 +1,11 @@ +import 'dart:async'; + import 'package:flutter/cupertino.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:visibility_detector/visibility_detector.dart'; class Waypoint extends HookWidget { - final void Function()? onTouchEdge; + final FutureOr Function()? onTouchEdge; final Widget? child; final ScrollController controller; final bool isGrid; @@ -18,27 +20,31 @@ class Waypoint extends HookWidget { @override Widget build(BuildContext context) { + final isMounted = useIsMounted(); + useEffect(() { if (isGrid) { return null; } - listener() { + Future listener() async { // nextPageTrigger will have a value equivalent to 80% of the list size. final nextPageTrigger = 0.8 * controller.position.maxScrollExtent; // scrollController fetches the next paginated data when the current postion of the user on the screen has surpassed - if (controller.position.pixels >= nextPageTrigger) { - onTouchEdge?.call(); + if (controller.position.pixels >= nextPageTrigger && isMounted()) { + await onTouchEdge?.call(); } } - if (controller.hasClients) { - listener(); - } + WidgetsBinding.instance.addPostFrameCallback((_) { + if (controller.hasClients && isMounted()) { + listener(); + } - controller.addListener(listener); + controller.addListener(listener); + }); return () => controller.removeListener(listener); - }, [controller, onTouchEdge]); + }, [controller, onTouchEdge, isMounted]); if (isGrid) { return VisibilityDetector( diff --git a/lib/themes/light-theme.dart b/lib/themes/light-theme.dart index 5503d5b4e..ac15f954d 100644 --- a/lib/themes/light-theme.dart +++ b/lib/themes/light-theme.dart @@ -154,12 +154,24 @@ const iosDarkTheme = CupertinoThemeData( ); final linuxTheme = AdwaitaThemeData.light().copyWith( + extensions: [ + ShimmerColorTheme( + shimmerBackgroundColor: Colors.grey[300], + shimmerColor: Colors.grey[400], + ) + ], listTileTheme: ListTileThemeData( iconColor: Colors.grey[900], horizontalTitleGap: 0, ), ); final linuxDarkTheme = AdwaitaThemeData.dark().copyWith( + extensions: [ + ShimmerColorTheme( + shimmerBackgroundColor: Colors.grey[800], + shimmerColor: Colors.grey[900], + ) + ], listTileTheme: ListTileThemeData( iconColor: Colors.grey[50], horizontalTitleGap: 0,