mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
refactor: extend list item for PopSheetEntry for better interactivity
This commit is contained in:
parent
b4713e377a
commit
0620b62023
@ -86,4 +86,5 @@ abstract class SpotubeIcons {
|
|||||||
static const volumeMedium = FeatherIcons.volume1;
|
static const volumeMedium = FeatherIcons.volume1;
|
||||||
static const volumeLow = FeatherIcons.volume;
|
static const volumeLow = FeatherIcons.volume;
|
||||||
static const volumeMute = FeatherIcons.volumeX;
|
static const volumeMute = FeatherIcons.volumeX;
|
||||||
|
static const timer = FeatherIcons.clock;
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,11 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart' hide Offset;
|
||||||
import 'package:spotube/collections/spotube_icons.dart';
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
import 'package:spotube/components/player/player_queue.dart';
|
import 'package:spotube/components/player/player_queue.dart';
|
||||||
import 'package:spotube/components/player/sibling_tracks_sheet.dart';
|
import 'package:spotube/components/player/sibling_tracks_sheet.dart';
|
||||||
|
import 'package:spotube/components/shared/adaptive/adaptive_pop_sheet_list.dart';
|
||||||
import 'package:spotube/components/shared/heart_button.dart';
|
import 'package:spotube/components/shared/heart_button.dart';
|
||||||
import 'package:spotube/extensions/context.dart';
|
import 'package:spotube/extensions/context.dart';
|
||||||
import 'package:spotube/models/local_track.dart';
|
import 'package:spotube/models/local_track.dart';
|
||||||
@ -127,6 +128,35 @@ class PlayerActions extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
if (playlist.activeTrack != null && !isLocalTrack && auth != null)
|
if (playlist.activeTrack != null && !isLocalTrack && auth != null)
|
||||||
TrackHeartButton(track: playlist.activeTrack!),
|
TrackHeartButton(track: playlist.activeTrack!),
|
||||||
|
AdaptivePopSheetList(
|
||||||
|
offset: const Offset(0, -50 * 5),
|
||||||
|
headings: [
|
||||||
|
Text(context.l10n.sleep_timer),
|
||||||
|
],
|
||||||
|
icon: const Icon(SpotubeIcons.timer),
|
||||||
|
children: [
|
||||||
|
PopSheetEntry(
|
||||||
|
value: const Duration(minutes: 15),
|
||||||
|
title: Text(context.l10n.mins(15)),
|
||||||
|
),
|
||||||
|
PopSheetEntry(
|
||||||
|
value: const Duration(minutes: 30),
|
||||||
|
title: Text(context.l10n.mins(30)),
|
||||||
|
),
|
||||||
|
PopSheetEntry(
|
||||||
|
value: const Duration(hours: 1),
|
||||||
|
title: Text(context.l10n.hour(1)),
|
||||||
|
),
|
||||||
|
PopSheetEntry(
|
||||||
|
value: const Duration(hours: 2),
|
||||||
|
title: Text(context.l10n.hours(2)),
|
||||||
|
),
|
||||||
|
PopSheetEntry(
|
||||||
|
value: Duration.zero,
|
||||||
|
title: Text(context.l10n.cancel),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
...(extraActions ?? [])
|
...(extraActions ?? [])
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -2,17 +2,47 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:spotube/collections/spotube_icons.dart';
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
import 'package:spotube/extensions/constrains.dart';
|
import 'package:spotube/extensions/constrains.dart';
|
||||||
|
|
||||||
class PopSheetEntry<T> {
|
_emptyCB() {}
|
||||||
final T? value;
|
|
||||||
final VoidCallback? onTap;
|
|
||||||
final Widget child;
|
|
||||||
final bool enabled;
|
|
||||||
|
|
||||||
|
class PopSheetEntry<T> extends ListTile {
|
||||||
|
final T? value;
|
||||||
const PopSheetEntry({
|
const PopSheetEntry({
|
||||||
required this.child,
|
|
||||||
this.value,
|
this.value,
|
||||||
this.onTap,
|
super.key,
|
||||||
this.enabled = true,
|
super.leading,
|
||||||
|
super.title,
|
||||||
|
super.subtitle,
|
||||||
|
super.trailing,
|
||||||
|
super.isThreeLine = false,
|
||||||
|
super.dense,
|
||||||
|
super.visualDensity,
|
||||||
|
super.shape,
|
||||||
|
super.style,
|
||||||
|
super.selectedColor,
|
||||||
|
super.iconColor,
|
||||||
|
super.textColor,
|
||||||
|
super.titleTextStyle,
|
||||||
|
super.subtitleTextStyle,
|
||||||
|
super.leadingAndTrailingTextStyle,
|
||||||
|
super.contentPadding,
|
||||||
|
super.enabled = true,
|
||||||
|
super.onTap = _emptyCB,
|
||||||
|
super.onLongPress,
|
||||||
|
super.onFocusChange,
|
||||||
|
super.mouseCursor,
|
||||||
|
super.selected = false,
|
||||||
|
super.focusColor,
|
||||||
|
super.hoverColor,
|
||||||
|
super.splashColor,
|
||||||
|
super.focusNode,
|
||||||
|
super.autofocus = false,
|
||||||
|
super.tileColor,
|
||||||
|
super.selectedTileColor,
|
||||||
|
super.enableFeedback,
|
||||||
|
super.horizontalTitleGap,
|
||||||
|
super.minVerticalPadding,
|
||||||
|
super.minLeadingWidth,
|
||||||
|
super.titleAlignment,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +60,7 @@ class AdaptivePopSheetList<T> extends StatelessWidget {
|
|||||||
final ValueChanged<T>? onSelected;
|
final ValueChanged<T>? onSelected;
|
||||||
|
|
||||||
final BorderRadius borderRadius;
|
final BorderRadius borderRadius;
|
||||||
|
final Offset offset;
|
||||||
|
|
||||||
const AdaptivePopSheetList({
|
const AdaptivePopSheetList({
|
||||||
super.key,
|
super.key,
|
||||||
@ -41,6 +72,7 @@ class AdaptivePopSheetList<T> extends StatelessWidget {
|
|||||||
this.onSelected,
|
this.onSelected,
|
||||||
this.borderRadius = const BorderRadius.all(Radius.circular(999)),
|
this.borderRadius = const BorderRadius.all(Radius.circular(999)),
|
||||||
this.tooltip,
|
this.tooltip,
|
||||||
|
this.offset = Offset.zero,
|
||||||
}) : assert(
|
}) : assert(
|
||||||
!(icon != null && child != null),
|
!(icon != null && child != null),
|
||||||
'Either icon or child must be provided',
|
'Either icon or child must be provided',
|
||||||
@ -55,11 +87,13 @@ class AdaptivePopSheetList<T> extends StatelessWidget {
|
|||||||
return PopupMenuButton(
|
return PopupMenuButton(
|
||||||
icon: icon,
|
icon: icon,
|
||||||
tooltip: tooltip,
|
tooltip: tooltip,
|
||||||
|
offset: offset,
|
||||||
child: child == null ? null : IgnorePointer(child: child),
|
child: child == null ? null : IgnorePointer(child: child),
|
||||||
itemBuilder: (context) => children
|
itemBuilder: (context) => children
|
||||||
.map(
|
.map(
|
||||||
(item) => PopupMenuItem(
|
(item) => PopupMenuItem(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
|
enabled: false,
|
||||||
child: _AdaptivePopSheetListItem(
|
child: _AdaptivePopSheetListItem(
|
||||||
item: item,
|
item: item,
|
||||||
onSelected: onSelected,
|
onSelected: onSelected,
|
||||||
@ -151,8 +185,11 @@ class _AdaptivePopSheetListItem<T> extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: (theme.listTileTheme.shape as RoundedRectangleBorder?)
|
||||||
|
?.borderRadius as BorderRadius? ??
|
||||||
|
const BorderRadius.all(Radius.circular(10)),
|
||||||
onTap: !item.enabled
|
onTap: !item.enabled
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
@ -162,16 +199,9 @@ class _AdaptivePopSheetListItem<T> extends StatelessWidget {
|
|||||||
onSelected?.call(item.value as T);
|
onSelected?.call(item.value as T);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: DefaultTextStyle(
|
|
||||||
style: TextStyle(
|
|
||||||
color: item.enabled
|
|
||||||
? theme.textTheme.bodyMedium!.color
|
|
||||||
: theme.textTheme.bodyMedium!.color!.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: item.child,
|
child: IgnorePointer(child: item),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,60 +25,39 @@ class SortTracksDropdown extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.none,
|
value: SortBy.none,
|
||||||
enabled: value != SortBy.none,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.none,
|
enabled: value != SortBy.none,
|
||||||
title: Text(context.l10n.none),
|
title: Text(context.l10n.none),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.ascending,
|
value: SortBy.ascending,
|
||||||
enabled: value != SortBy.ascending,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.ascending,
|
enabled: value != SortBy.ascending,
|
||||||
title: Text(context.l10n.sort_a_z),
|
title: Text(context.l10n.sort_a_z),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.descending,
|
value: SortBy.descending,
|
||||||
enabled: value != SortBy.descending,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.descending,
|
enabled: value != SortBy.descending,
|
||||||
title: Text(context.l10n.sort_z_a),
|
title: Text(context.l10n.sort_z_a),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.newest,
|
value: SortBy.newest,
|
||||||
enabled: value != SortBy.newest,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.newest,
|
enabled: value != SortBy.newest,
|
||||||
title: Text(context.l10n.sort_newest),
|
title: Text(context.l10n.sort_newest),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.oldest,
|
value: SortBy.oldest,
|
||||||
enabled: value != SortBy.oldest,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.oldest,
|
enabled: value != SortBy.oldest,
|
||||||
title: Text(context.l10n.sort_oldest),
|
title: Text(context.l10n.sort_oldest),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.artist,
|
value: SortBy.artist,
|
||||||
enabled: value != SortBy.artist,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.artist,
|
enabled: value != SortBy.artist,
|
||||||
title: Text(context.l10n.sort_artist),
|
title: Text(context.l10n.sort_artist),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: SortBy.album,
|
value: SortBy.album,
|
||||||
enabled: value != SortBy.album,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: value != SortBy.album,
|
enabled: value != SortBy.album,
|
||||||
title: Text(context.l10n.sort_album),
|
title: Text(context.l10n.sort_album),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
headings: [
|
headings: [
|
||||||
Text(context.l10n.sort_tracks),
|
Text(context.l10n.sort_tracks),
|
||||||
|
@ -207,42 +207,32 @@ class TrackOptions extends HookConsumerWidget {
|
|||||||
LocalTrack => [
|
LocalTrack => [
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.delete,
|
value: TrackOptionValue.delete,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.trash),
|
leading: const Icon(SpotubeIcons.trash),
|
||||||
title: Text(context.l10n.delete),
|
title: Text(context.l10n.delete),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
_ => [
|
_ => [
|
||||||
if (!playlist.containsTrack(track)) ...[
|
if (!playlist.containsTrack(track)) ...[
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.addToQueue,
|
value: TrackOptionValue.addToQueue,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.queueAdd),
|
leading: const Icon(SpotubeIcons.queueAdd),
|
||||||
title: Text(context.l10n.add_to_queue),
|
title: Text(context.l10n.add_to_queue),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.playNext,
|
value: TrackOptionValue.playNext,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.lightning),
|
leading: const Icon(SpotubeIcons.lightning),
|
||||||
title: Text(context.l10n.play_next),
|
title: Text(context.l10n.play_next),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
] else
|
] else
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.removeFromQueue,
|
value: TrackOptionValue.removeFromQueue,
|
||||||
enabled: playlist.activeTrack?.id != track.id,
|
|
||||||
child: ListTile(
|
|
||||||
enabled: playlist.activeTrack?.id != track.id,
|
enabled: playlist.activeTrack?.id != track.id,
|
||||||
leading: const Icon(SpotubeIcons.queueRemove),
|
leading: const Icon(SpotubeIcons.queueRemove),
|
||||||
title: Text(context.l10n.remove_from_queue),
|
title: Text(context.l10n.remove_from_queue),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
if (favorites.me.hasData)
|
if (favorites.me.hasData)
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.favorite,
|
value: TrackOptionValue.favorite,
|
||||||
child: ListTile(
|
|
||||||
leading: favorites.isLiked
|
leading: favorites.isLiked
|
||||||
? const Icon(
|
? const Icon(
|
||||||
SpotubeIcons.heartFilled,
|
SpotubeIcons.heartFilled,
|
||||||
@ -255,19 +245,15 @@ class TrackOptions extends HookConsumerWidget {
|
|||||||
: context.l10n.save_as_favorite,
|
: context.l10n.save_as_favorite,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
if (auth != null)
|
if (auth != null)
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.addToPlaylist,
|
value: TrackOptionValue.addToPlaylist,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.playlistAdd),
|
leading: const Icon(SpotubeIcons.playlistAdd),
|
||||||
title: Text(context.l10n.add_to_playlist),
|
title: Text(context.l10n.add_to_playlist),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
if (userPlaylist && auth != null)
|
if (userPlaylist && auth != null)
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.removeFromPlaylist,
|
value: TrackOptionValue.removeFromPlaylist,
|
||||||
child: ListTile(
|
|
||||||
leading: (removeTrack.isMutating || !removeTrack.hasData) &&
|
leading: (removeTrack.isMutating || !removeTrack.hasData) &&
|
||||||
removingTrack.value == track.uri
|
removingTrack.value == track.uri
|
||||||
? const Center(
|
? const Center(
|
||||||
@ -276,10 +262,8 @@ class TrackOptions extends HookConsumerWidget {
|
|||||||
: const Icon(SpotubeIcons.removeFilled),
|
: const Icon(SpotubeIcons.removeFilled),
|
||||||
title: Text(context.l10n.remove_from_playlist),
|
title: Text(context.l10n.remove_from_playlist),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.blacklist,
|
value: TrackOptionValue.blacklist,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.playlistRemove),
|
leading: const Icon(SpotubeIcons.playlistRemove),
|
||||||
iconColor: !isBlackListed ? Colors.red[400] : null,
|
iconColor: !isBlackListed ? Colors.red[400] : null,
|
||||||
textColor: !isBlackListed ? Colors.red[400] : null,
|
textColor: !isBlackListed ? Colors.red[400] : null,
|
||||||
@ -289,21 +273,16 @@ class TrackOptions extends HookConsumerWidget {
|
|||||||
: context.l10n.add_to_blacklist,
|
: context.l10n.add_to_blacklist,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.share,
|
value: TrackOptionValue.share,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.share),
|
leading: const Icon(SpotubeIcons.share),
|
||||||
title: Text(context.l10n.share),
|
title: Text(context.l10n.share),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
PopSheetEntry(
|
PopSheetEntry(
|
||||||
value: TrackOptionValue.details,
|
value: TrackOptionValue.details,
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.info),
|
leading: const Icon(SpotubeIcons.info),
|
||||||
title: Text(context.l10n.details),
|
title: Text(context.l10n.details),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -185,55 +185,6 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
style: tableHeadStyle,
|
style: tableHeadStyle,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
children: [
|
|
||||||
PopSheetEntry(
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
value: "download",
|
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.download),
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
title: Text(
|
|
||||||
context.l10n.download_count(selectedTracks.length),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!userPlaylist)
|
|
||||||
PopSheetEntry(
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
value: "add-to-playlist",
|
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.playlistAdd),
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
title: Text(
|
|
||||||
context.l10n
|
|
||||||
.add_count_to_playlist(selectedTracks.length),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PopSheetEntry(
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
value: "add-to-queue",
|
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.queueAdd),
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
title: Text(
|
|
||||||
context.l10n
|
|
||||||
.add_count_to_queue(selectedTracks.length),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PopSheetEntry(
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
value: "play-next",
|
|
||||||
child: ListTile(
|
|
||||||
leading: const Icon(SpotubeIcons.lightning),
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
title: Text(
|
|
||||||
context.l10n.play_count_next(selectedTracks.length),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
onSelected: (action) async {
|
onSelected: (action) async {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "download":
|
case "download":
|
||||||
@ -283,6 +234,43 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(SpotubeIcons.moreVertical),
|
icon: const Icon(SpotubeIcons.moreVertical),
|
||||||
|
children: [
|
||||||
|
PopSheetEntry(
|
||||||
|
value: "download",
|
||||||
|
leading: const Icon(SpotubeIcons.download),
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
title: Text(
|
||||||
|
context.l10n.download_count(selectedTracks.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!userPlaylist)
|
||||||
|
PopSheetEntry(
|
||||||
|
value: "add-to-playlist",
|
||||||
|
leading: const Icon(SpotubeIcons.playlistAdd),
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
title: Text(
|
||||||
|
context.l10n
|
||||||
|
.add_count_to_playlist(selectedTracks.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PopSheetEntry(
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
value: "add-to-queue",
|
||||||
|
leading: const Icon(SpotubeIcons.queueAdd),
|
||||||
|
title: Text(
|
||||||
|
context.l10n
|
||||||
|
.add_count_to_queue(selectedTracks.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PopSheetEntry(
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
value: "play-next",
|
||||||
|
leading: const Icon(SpotubeIcons.lightning),
|
||||||
|
title: Text(
|
||||||
|
context.l10n.play_count_next(selectedTracks.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
],
|
],
|
||||||
|
@ -239,5 +239,9 @@
|
|||||||
"streamUrl": "Stream URL",
|
"streamUrl": "Stream URL",
|
||||||
"stop": "Stop",
|
"stop": "Stop",
|
||||||
"sort_newest": "Sort by newest added",
|
"sort_newest": "Sort by newest added",
|
||||||
"sort_oldest": "Sort by oldest added"
|
"sort_oldest": "Sort by oldest added",
|
||||||
|
"sleep_timer": "Sleep Timer",
|
||||||
|
"mins": "{minutes} Minutes",
|
||||||
|
"hours": "{hours} Hours",
|
||||||
|
"hour": "{hours} Hour"
|
||||||
}
|
}
|
@ -197,6 +197,9 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
label: Text(context.l10n.details),
|
label: Text(context.l10n.details),
|
||||||
style: OutlinedButton.styleFrom(
|
style: OutlinedButton.styleFrom(
|
||||||
foregroundColor: bodyTextColor,
|
foregroundColor: bodyTextColor,
|
||||||
|
side: BorderSide(
|
||||||
|
color: bodyTextColor ?? Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onPressed: currentTrack == null
|
onPressed: currentTrack == null
|
||||||
? null
|
? null
|
||||||
@ -218,6 +221,9 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
icon: const Icon(SpotubeIcons.music),
|
icon: const Icon(SpotubeIcons.music),
|
||||||
style: OutlinedButton.styleFrom(
|
style: OutlinedButton.styleFrom(
|
||||||
foregroundColor: bodyTextColor,
|
foregroundColor: bodyTextColor,
|
||||||
|
side: BorderSide(
|
||||||
|
color: bodyTextColor ?? Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
@ -257,7 +263,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
overlayColor: titleTextColor?.withOpacity(0.2),
|
overlayColor: titleTextColor?.withOpacity(0.2),
|
||||||
trackHeight: 2,
|
trackHeight: 2,
|
||||||
thumbShape: const RoundSliderThumbShape(
|
thumbShape: const RoundSliderThumbShape(
|
||||||
enabledThumbRadius: 6,
|
enabledThumbRadius: 8,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
|
Loading…
Reference in New Issue
Block a user