diff --git a/lib/components/AlbumScreen/track_list_tile.dart b/lib/components/AlbumScreen/track_list_tile.dart index 7fb55412..a2776e70 100644 --- a/lib/components/AlbumScreen/track_list_tile.dart +++ b/lib/components/AlbumScreen/track_list_tile.dart @@ -301,6 +301,7 @@ class QueueListTile extends StatelessWidget { final int actualIndex; final int indexOffset; final bool isCurrentTrack; + final bool isPreviousTrack; final bool isInPlaylist; final bool allowReorder; @@ -318,6 +319,7 @@ class QueueListTile extends StatelessWidget { required this.isCurrentTrack, required this.isInPlaylist, required this.allowReorder, + this.isPreviousTrack = false, this.parentItem, this.onRemoveFromList, this.themeCallback, @@ -337,6 +339,7 @@ class QueueListTile extends StatelessWidget { parentItem: parentItem, listIndex: listIndex, actualIndex: item.indexNumber ?? -1, + isPreviousTrack: isPreviousTrack, isInPlaylist: isInPlaylist, allowReorder: allowReorder, onRemoveFromList: onRemoveFromList, @@ -356,6 +359,7 @@ class TrackListItem extends ConsumerStatefulWidget { final bool showIndex; final bool showArtists; final bool showPlayCount; + final bool isPreviousTrack; final bool isInPlaylist; final bool allowReorder; final Widget dismissBackground; @@ -372,6 +376,7 @@ class TrackListItem extends ConsumerStatefulWidget { required this.onTap, required this.confirmDismiss, this.parentItem, + this.isPreviousTrack = false, this.isInPlaylist = false, this.allowReorder = false, this.showIndex = false, @@ -460,6 +465,7 @@ class TrackListItemState extends ConsumerState child: ThemedTrackListTile( playable: playable, isCurrentTrack: isCurrentlyPlaying, + isPreviousTrack: widget.isPreviousTrack, themeCallback: (x) => _menuTheme = x, baseItem: widget.baseItem, listIndex: widget.listIndex, @@ -477,6 +483,7 @@ class TrackListItemState extends ConsumerState : ThemedTrackListTile( playable: playable, isCurrentTrack: isCurrentlyPlaying, + isPreviousTrack: widget.isPreviousTrack, themeCallback: (x) => _menuTheme = x, baseItem: widget.baseItem, listIndex: widget.listIndex, @@ -518,6 +525,7 @@ class TrackListItemState extends ConsumerState class ThemedTrackListTile extends ConsumerWidget { final bool playable; final bool isCurrentTrack; + final bool isPreviousTrack; final void Function(FinampTheme) themeCallback; final jellyfin_models.BaseItemDto baseItem; final Future? listIndex; @@ -533,6 +541,7 @@ class ThemedTrackListTile extends ConsumerWidget { super.key, required this.playable, required this.isCurrentTrack, + required this.isPreviousTrack, required this.themeCallback, required this.baseItem, required this.listIndex, @@ -548,7 +557,7 @@ class ThemedTrackListTile extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return Opacity( - opacity: playable ? 1.0 : 0.5, + opacity: playable ? (isPreviousTrack ? 0.7 : 1.0) : 0.5, child: Card( color: Colors.transparent, elevation: 0, diff --git a/lib/components/PlayerScreen/queue_list.dart b/lib/components/PlayerScreen/queue_list.dart index f5b296d2..b94b0379 100644 --- a/lib/components/PlayerScreen/queue_list.dart +++ b/lib/components/PlayerScreen/queue_list.dart @@ -29,7 +29,6 @@ import '../../services/process_artist.dart'; import '../../services/queue_service.dart'; import '../album_image.dart'; import '../themed_bottom_sheet.dart'; -import 'queue_list_item.dart'; import 'queue_source_helper.dart'; class _QueueListStreamState { @@ -466,16 +465,17 @@ class _PreviousTracksListState extends State final item = _previousTracks![index]; final actualIndex = index; final indexOffset = -((_previousTracks?.length ?? 0) - index); - return QueueListItem( + return QueueListTile( key: ValueKey(item.id), - item: item, - listIndex: index, + item: item.baseItem!, + listIndex: Future.value(index), actualIndex: actualIndex, indexOffset: indexOffset, - subqueue: _previousTracks!, + isInPlaylist: queueItemInPlaylist(item), + parentItem: item.source.item, allowReorder: _queueService.playbackOrder == FinampPlaybackOrder.linear, - onTap: () async { + onTap: (bool playable) async { FeedbackHelper.feedback(FeedbackType.selection); await _queueService.skipByOffset(indexOffset); scrollToKey( @@ -522,7 +522,7 @@ class _NextUpTracksListState extends State { _nextUp ??= snapshot.data!.nextUp; return SliverPadding( - padding: const EdgeInsets.only(top: 0.0, left: 4.0, right: 4.0), + padding: const EdgeInsets.only(top: 0.0, left: 8.0, right: 8.0), sliver: SliverReorderableList( autoScrollerVelocityScalar: 20.0, onReorder: (oldIndex, newIndex) { @@ -558,14 +558,17 @@ class _NextUpTracksListState extends State { final item = _nextUp![index]; final actualIndex = index; final indexOffset = index + 1; - return QueueListItem( + return QueueListTile( key: ValueKey(item.id), - item: item, - listIndex: index, + item: item.baseItem!, + listIndex: Future.value(index), actualIndex: actualIndex, indexOffset: indexOffset, - subqueue: _nextUp!, - onTap: () async { + isInPlaylist: queueItemInPlaylist(item), + parentItem: item.source.item, + allowReorder: _queueService.playbackOrder == + FinampPlaybackOrder.linear, + onTap: (bool playable) async { FeedbackHelper.feedback(FeedbackType.selection); await _queueService.skipByOffset(indexOffset); scrollToKey( @@ -649,24 +652,6 @@ class _QueueTracksListState extends State { final actualIndex = index; final indexOffset = index + _nextUp!.length + 1; - // return QueueListItem( - // key: ValueKey(item.id), - // item: item, - // listIndex: index, - // actualIndex: actualIndex, - // indexOffset: indexOffset, - // subqueue: _queue!, - // allowReorder: - // _queueService.playbackOrder == FinampPlaybackOrder.linear, - // onTap: () async { - // FeedbackHelper.feedback(FeedbackType.selection); - // await _queueService.skipByOffset(indexOffset); - // scrollToKey( - // key: widget.previousTracksHeaderKey, - // duration: const Duration(milliseconds: 500)); - // }, - // isCurrentTrack: false, - // ); return QueueListTile( key: ValueKey(item.id), item: item.baseItem!, diff --git a/lib/components/PlayerScreen/queue_list_item.dart b/lib/components/PlayerScreen/queue_list_item.dart deleted file mode 100644 index 902a3d44..00000000 --- a/lib/components/PlayerScreen/queue_list_item.dart +++ /dev/null @@ -1,219 +0,0 @@ -import 'package:finamp/components/AlbumScreen/song_menu.dart'; -import 'package:finamp/components/PlayerScreen/queue_source_helper.dart'; -import 'package:finamp/components/album_image.dart'; -import 'package:finamp/models/finamp_models.dart'; -import 'package:finamp/models/jellyfin_models.dart' as jellyfin_models; -import 'package:finamp/services/feedback_helper.dart'; -import 'package:finamp/services/finamp_settings_helper.dart'; -import 'package:finamp/services/process_artist.dart'; -import 'package:finamp/services/queue_service.dart'; -import 'package:flutter/material.dart' hide ReorderableList; -import 'package:flutter_tabler_icons/flutter_tabler_icons.dart'; -import 'package:flutter_vibrate/flutter_vibrate.dart'; -import 'package:get_it/get_it.dart'; - -import '../../services/theme_provider.dart'; - -@Deprecated("Use QueueListItem instead") -class QueueListItem extends StatefulWidget { - final FinampQueueItem item; - final int listIndex; - final int actualIndex; - final int indexOffset; - final List subqueue; - final bool isCurrentTrack; - final bool isPreviousTrack; - final bool allowReorder; - final void Function() onTap; - - const QueueListItem({ - super.key, - required this.item, - required this.listIndex, - required this.actualIndex, - required this.indexOffset, - required this.subqueue, - required this.onTap, - this.allowReorder = true, - this.isCurrentTrack = false, - this.isPreviousTrack = false, - }); - @override - State createState() => _QueueListItemState(); -} - -class _QueueListItemState extends State - with AutomaticKeepAliveClientMixin { - final _queueService = GetIt.instance(); - - @override - bool get wantKeepAlive => true; - - FinampTheme? _menuTheme; - - @override - void dispose() { - _menuTheme?.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - super.build(context); - - jellyfin_models.BaseItemDto baseItem = jellyfin_models.BaseItemDto.fromJson( - widget.item.item.extras?["itemJson"]); - - final cardBackground = Theme.of(context).brightness == Brightness.dark - ? const Color.fromRGBO(255, 255, 255, 0.075) - : const Color.fromRGBO(255, 255, 255, 0.125); - - void menuCallback() { - var currentTrack = _queueService.getCurrentTrack()?.baseItem; - showModalSongMenu( - context: context, - item: baseItem, - usePlayerTheme: widget.item.baseItem?.blurHash != null && - widget.item.baseItem?.blurHash == currentTrack?.blurHash, - themeProvider: _menuTheme, - isInPlaylist: queueItemInPlaylist(widget.item), - parentItem: widget.item.source.item, - confirmPlaylistRemoval: true, - ); - } - - return Dismissible( - key: Key(widget.item.id), - direction: FinampSettingsHelper.finampSettings.disableGesture - ? DismissDirection.none - : DismissDirection.horizontal, - onDismissed: (direction) async { - FeedbackHelper.feedback(FeedbackType.impact); - await _queueService.removeAtOffset(widget.indexOffset); - setState(() {}); - }, - child: GestureDetector( - onTapDown: (_) { - _menuTheme?.calculate(Theme.of(context).brightness); - }, - onLongPressStart: (details) => menuCallback(), - onSecondaryTapDown: (details) => menuCallback(), - child: Opacity( - opacity: widget.isPreviousTrack ? 0.8 : 1.0, - child: Card( - color: cardBackground, - elevation: 0, - margin: - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 5.0), - clipBehavior: Clip.antiAlias, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - child: ListTile( - visualDensity: VisualDensity.standard, - minVerticalPadding: 0.0, - horizontalTitleGap: 10.0, - contentPadding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 0.0), - tileColor: widget.isCurrentTrack - ? Theme.of(context).colorScheme.secondary.withOpacity(0.1) - : null, - leading: AlbumImage( - item: widget.item.item.extras?["itemJson"] == null - ? null - : jellyfin_models.BaseItemDto.fromJson( - widget.item.item.extras?["itemJson"]), - borderRadius: BorderRadius.zero, - ), - title: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(0.0), - child: Text( - widget.item.item.title, - style: widget.isCurrentTrack - ? TextStyle( - color: - Theme.of(context).colorScheme.secondary, - fontSize: 16, - fontWeight: FontWeight.w400, - overflow: TextOverflow.ellipsis) - : null, - overflow: TextOverflow.ellipsis, - ), - ), - Padding( - padding: const EdgeInsets.only(top: 6.0), - child: Text( - processArtist(widget.item.item.artist, context), - style: TextStyle( - color: Theme.of(context) - .textTheme - .bodyMedium! - .color!, - fontSize: 13, - fontWeight: FontWeight.w300, - overflow: TextOverflow.ellipsis), - overflow: TextOverflow.ellipsis, - ), - ), - ], - ), - trailing: Container( - margin: const EdgeInsets.only(right: 8.0), - padding: const EdgeInsets.only(right: 6.0), - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - "${widget.item.item.duration?.inMinutes.toString()}:${((widget.item.item.duration?.inSeconds ?? 0) % 60).toString().padLeft(2, '0')}", - textAlign: TextAlign.end, - style: TextStyle( - color: Theme.of(context).textTheme.bodySmall?.color, - ), - ), - if (FinampSettingsHelper.finampSettings.disableGesture) - IconButton( - padding: const EdgeInsets.only(left: 6.0), - visualDensity: VisualDensity.compact, - icon: const Icon( - TablerIcons.x, - color: Colors.white, - weight: 1.5, - ), - iconSize: 24.0, - onPressed: () async { - FeedbackHelper.feedback(FeedbackType.light); - await _queueService - .removeAtOffset(widget.indexOffset); - }, - ), - if (widget.allowReorder) - ReorderableDragStartListener( - index: widget.listIndex, - child: Padding( - padding: const EdgeInsets.only(left: 6.0), - child: Icon( - TablerIcons.grip_horizontal, - color: Theme.of(context) - .textTheme - .bodyMedium - ?.color ?? - Colors.white, - size: 28.0, - weight: 1.5, - ), - ), - ), - ], - ), - ), - onTap: widget.onTap, - )), - )), - ); - } -}