fix: player view artist link when local playlist is playing, lyric delay adjust button alignment

This commit is contained in:
Kingkor Roy Tirtho 2022-12-07 13:27:46 +06:00
parent bc8a04e544
commit ee5c417ac3
6 changed files with 107 additions and 70 deletions

View File

@ -44,12 +44,14 @@ class Genres extends HookConsumerWidget {
.toList() .toList()
]; ];
final isMounted = useIsMounted();
return PlatformScaffold( return PlatformScaffold(
appBar: kIsDesktop ? PageWindowTitleBar() : null, appBar: kIsDesktop ? PageWindowTitleBar() : null,
body: Waypoint( body: Waypoint(
onTouchEdge: () { onTouchEdge: () async {
if (categoriesQuery.hasNextPage) { if (categoriesQuery.hasNextPage && isMounted()) {
categoriesQuery.fetchNextPage(); await categoriesQuery.fetchNextPage();
} }
}, },
controller: scrollController, controller: scrollController,

View File

@ -71,7 +71,7 @@ class SyncedLyrics extends HookConsumerWidget {
return Column( return Column(
children: [ children: [
SizedBox( SizedBox(
height: breakpoint >= Breakpoints.md ? 50 : 30, height: breakpoint >= Breakpoints.md ? 50 : 40,
child: Material( child: Material(
type: MaterialType.transparency, type: MaterialType.transparency,
textStyle: PlatformTheme.of(context).textTheme!.body!, textStyle: PlatformTheme.of(context).textTheme!.body!,
@ -84,27 +84,25 @@ class SyncedLyrics extends HookConsumerWidget {
isHovering: true, isHovering: true,
), ),
), ),
Positioned.fill( Positioned(
top: 10,
right: 10,
child: Align( child: Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Padding( child: PlatformFilledButton(
padding: const EdgeInsets.all(8.0), child: const Icon(
child: PlatformFilledButton( Icons.av_timer_rounded,
child: const Icon( size: 16,
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;
}
},
), ),
onPressed: () async {
final delay = await showPlatformAlertDialog(
context,
builder: (context) => const LyricDelayAdjustDialog(),
);
if (delay != null) {
ref.read(lyricDelayState.notifier).state = delay;
}
},
), ),
), ),
), ),

View File

@ -28,6 +28,7 @@ class PlayerActions extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final Playback playback = ref.watch(playbackProvider); final Playback playback = ref.watch(playbackProvider);
final isLocalTrack = playback.playlist?.isLocal == true;
final downloader = ref.watch(downloaderProvider); final downloader = ref.watch(downloaderProvider);
final isInQueue = final isInQueue =
downloader.inQueue.any((element) => element.id == playback.track?.id); downloader.inQueue.any((element) => element.id == playback.track?.id);
@ -74,32 +75,33 @@ class PlayerActions extends HookConsumerWidget {
} }
: null, : null,
), ),
PlatformIconButton( if (!isLocalTrack)
icon: const Icon(Icons.alt_route_rounded), PlatformIconButton(
tooltip: "Alternative Track Sources", icon: const Icon(Icons.alt_route_rounded),
onPressed: playback.track != null tooltip: "Alternative Track Sources",
? () { onPressed: playback.track != null
showModalBottomSheet( ? () {
context: context, showModalBottomSheet(
isDismissible: true, context: context,
enableDrag: true, isDismissible: true,
isScrollControlled: true, enableDrag: true,
backgroundColor: Colors.black12, isScrollControlled: true,
barrierColor: Colors.black12, backgroundColor: Colors.black12,
shape: RoundedRectangleBorder( barrierColor: Colors.black12,
borderRadius: BorderRadius.circular(10), shape: RoundedRectangleBorder(
), borderRadius: BorderRadius.circular(10),
constraints: BoxConstraints( ),
maxHeight: MediaQuery.of(context).size.height * .5, constraints: BoxConstraints(
), maxHeight: MediaQuery.of(context).size.height * .5,
builder: (context) { ),
return SiblingTracksSheet(floating: floatingQueue); builder: (context) {
}, return SiblingTracksSheet(floating: floatingQueue);
); },
} );
: null, }
), : null,
if (!kIsWeb) ),
if (!kIsWeb && !isLocalTrack)
if (isInQueue) if (isInQueue)
const SizedBox( const SizedBox(
height: 20, height: 20,
@ -120,7 +122,8 @@ class PlayerActions extends HookConsumerWidget {
? () => downloader.addToQueue(playback.track!) ? () => downloader.addToQueue(playback.track!)
: null, : null,
), ),
if (playback.track != null) TrackHeartButton(track: playback.track!), if (playback.track != null && !isLocalTrack)
TrackHeartButton(track: playback.track!),
...(extraActions ?? []) ...(extraActions ?? [])
], ],
); );

View File

@ -6,6 +6,7 @@ import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:palette_generator/palette_generator.dart'; import 'package:palette_generator/palette_generator.dart';
import 'package:platform_ui/platform_ui.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/PlayerActions.dart';
import 'package:spotube/components/Player/PlayerControls.dart'; import 'package:spotube/components/Player/PlayerControls.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
@ -28,6 +29,9 @@ class PlayerView extends HookConsumerWidget {
final currentTrack = ref.watch(playbackProvider.select( final currentTrack = ref.watch(playbackProvider.select(
(value) => value.track, (value) => value.track,
)); ));
final isLocalTrack = ref.watch(playbackProvider.select(
(value) => value.playlist?.isLocal == true,
));
final breakpoint = useBreakpoints(); final breakpoint = useBreakpoints();
final canRotate = ref.watch( final canRotate = ref.watch(
userPreferencesProvider.select((s) => s.rotatingAlbumArt), userPreferencesProvider.select((s) => s.rotatingAlbumArt),
@ -102,18 +106,30 @@ class PlayerView extends HookConsumerWidget {
isHovering: true, isHovering: true,
), ),
), ),
TypeConversionUtils.artists_X_ClickableArtists( if (isLocalTrack)
currentTrack?.artists ?? [], Text(
textStyle: TypeConversionUtils.artists_X_String<Artist>(
Theme.of(context).textTheme.headline6!.copyWith( currentTrack?.artists ?? [],
fontWeight: FontWeight.bold, ),
color: paletteColor.bodyTextColor, style:
), Theme.of(context).textTheme.headline6!.copyWith(
onRouteChange: (route) { fontWeight: FontWeight.bold,
GoRouter.of(context).pop(); color: paletteColor.bodyTextColor,
GoRouter.of(context).push(route); ),
}, )
), 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);
},
),
], ],
), ),
), ),

View File

@ -1,9 +1,11 @@
import 'dart:async';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:visibility_detector/visibility_detector.dart'; import 'package:visibility_detector/visibility_detector.dart';
class Waypoint extends HookWidget { class Waypoint extends HookWidget {
final void Function()? onTouchEdge; final FutureOr<void> Function()? onTouchEdge;
final Widget? child; final Widget? child;
final ScrollController controller; final ScrollController controller;
final bool isGrid; final bool isGrid;
@ -18,27 +20,31 @@ class Waypoint extends HookWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isMounted = useIsMounted();
useEffect(() { useEffect(() {
if (isGrid) { if (isGrid) {
return null; return null;
} }
listener() { Future<void> listener() async {
// nextPageTrigger will have a value equivalent to 80% of the list size. // nextPageTrigger will have a value equivalent to 80% of the list size.
final nextPageTrigger = 0.8 * controller.position.maxScrollExtent; 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 // scrollController fetches the next paginated data when the current postion of the user on the screen has surpassed
if (controller.position.pixels >= nextPageTrigger) { if (controller.position.pixels >= nextPageTrigger && isMounted()) {
onTouchEdge?.call(); await onTouchEdge?.call();
} }
} }
if (controller.hasClients) { WidgetsBinding.instance.addPostFrameCallback((_) {
listener(); if (controller.hasClients && isMounted()) {
} listener();
}
controller.addListener(listener); controller.addListener(listener);
});
return () => controller.removeListener(listener); return () => controller.removeListener(listener);
}, [controller, onTouchEdge]); }, [controller, onTouchEdge, isMounted]);
if (isGrid) { if (isGrid) {
return VisibilityDetector( return VisibilityDetector(

View File

@ -154,12 +154,24 @@ const iosDarkTheme = CupertinoThemeData(
); );
final linuxTheme = AdwaitaThemeData.light().copyWith( final linuxTheme = AdwaitaThemeData.light().copyWith(
extensions: [
ShimmerColorTheme(
shimmerBackgroundColor: Colors.grey[300],
shimmerColor: Colors.grey[400],
)
],
listTileTheme: ListTileThemeData( listTileTheme: ListTileThemeData(
iconColor: Colors.grey[900], iconColor: Colors.grey[900],
horizontalTitleGap: 0, horizontalTitleGap: 0,
), ),
); );
final linuxDarkTheme = AdwaitaThemeData.dark().copyWith( final linuxDarkTheme = AdwaitaThemeData.dark().copyWith(
extensions: [
ShimmerColorTheme(
shimmerBackgroundColor: Colors.grey[800],
shimmerColor: Colors.grey[900],
)
],
listTileTheme: ListTileThemeData( listTileTheme: ListTileThemeData(
iconColor: Colors.grey[50], iconColor: Colors.grey[50],
horizontalTitleGap: 0, horizontalTitleGap: 0,