mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
fix: track_table_view table headers
This commit is contained in:
parent
c8b7de0879
commit
d88d287fc5
@ -121,7 +121,8 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: IconTheme(
|
child: IconTheme(
|
||||||
data: theme.iconTheme.copyWith(size: 26),
|
data: theme.iconTheme
|
||||||
|
.copyWith(size: 26, color: Colors.white),
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedSwitcher(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
child: !isHovering
|
child: !isHovering
|
||||||
|
@ -49,8 +49,6 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
TextStyle tableHeadStyle =
|
TextStyle tableHeadStyle =
|
||||||
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||||
|
|
||||||
final mediaQuery = MediaQuery.of(context);
|
|
||||||
|
|
||||||
final selected = useState<List<String>>([]);
|
final selected = useState<List<String>>([]);
|
||||||
final showCheck = useState<bool>(false);
|
final showCheck = useState<bool>(false);
|
||||||
final sortBy = ref.watch(trackCollectionSortState(playlistId ?? ''));
|
final sortBy = ref.watch(trackCollectionSortState(playlistId ?? ''));
|
||||||
@ -73,184 +71,191 @@ class TracksTableView extends HookConsumerWidget {
|
|||||||
? [const NotFound(vertical: true)]
|
? [const NotFound(vertical: true)]
|
||||||
: [
|
: [
|
||||||
if (heading != null) heading!,
|
if (heading != null) heading!,
|
||||||
Row(
|
LayoutBuilder(builder: (context, constrains) {
|
||||||
children: [
|
return Row(
|
||||||
Checkbox.adaptive(
|
children: [
|
||||||
value: selected.value.length == sortedTracks.length,
|
AnimatedSwitcher(
|
||||||
onChanged: (checked) {
|
duration: const Duration(milliseconds: 200),
|
||||||
if (!showCheck.value) showCheck.value = true;
|
transitionBuilder: (child, animation) {
|
||||||
if (checked == true) {
|
return FadeTransition(
|
||||||
selected.value = sortedTracks.map((s) => s.id!).toList();
|
opacity: animation,
|
||||||
} else {
|
child: ScaleTransition(
|
||||||
selected.value = [];
|
scale: animation,
|
||||||
showCheck.value = false;
|
child: child,
|
||||||
}
|
),
|
||||||
},
|
);
|
||||||
),
|
},
|
||||||
Padding(
|
child: showCheck.value
|
||||||
padding: const EdgeInsets.all(8.0),
|
? Checkbox.adaptive(
|
||||||
child: Text(
|
value: selected.value.length == sortedTracks.length,
|
||||||
"#",
|
onChanged: (checked) {
|
||||||
textAlign: TextAlign.center,
|
if (!showCheck.value) showCheck.value = true;
|
||||||
style: tableHeadStyle,
|
if (checked == true) {
|
||||||
|
selected.value =
|
||||||
|
sortedTracks.map((s) => s.id!).toList();
|
||||||
|
} else {
|
||||||
|
selected.value = [];
|
||||||
|
showCheck.value = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: constrains.mdAndUp
|
||||||
|
? const SizedBox(width: 32)
|
||||||
|
: const SizedBox(width: 16),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
context.l10n.title,
|
|
||||||
style: tableHeadStyle,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// used alignment of this table-head
|
|
||||||
if (mediaQuery.lgAndUp) ...[
|
|
||||||
const SizedBox(width: 100),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
context.l10n.album,
|
context.l10n.title,
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: tableHeadStyle,
|
style: tableHeadStyle,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
// used alignment of this table-head
|
||||||
if (!mediaQuery.isSm) ...[
|
if (constrains.mdAndUp)
|
||||||
const SizedBox(width: 10),
|
Expanded(
|
||||||
Text(context.l10n.time, style: tableHeadStyle),
|
flex: 3,
|
||||||
const SizedBox(width: 10),
|
child: Row(
|
||||||
],
|
children: [
|
||||||
SortTracksDropdown(
|
Text(
|
||||||
value: sortBy,
|
context.l10n.album,
|
||||||
onChanged: (value) {
|
overflow: TextOverflow.ellipsis,
|
||||||
ref
|
style: tableHeadStyle,
|
||||||
.read(
|
),
|
||||||
trackCollectionSortState(playlistId ?? '').notifier)
|
],
|
||||||
.state = value;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
PopupMenuButton(
|
|
||||||
tooltip: context.l10n.more_actions,
|
|
||||||
itemBuilder: (context) {
|
|
||||||
return [
|
|
||||||
PopupMenuItem(
|
|
||||||
enabled: selectedTracks.isNotEmpty,
|
|
||||||
value: "download",
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Icon(SpotubeIcons.download),
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
Text(
|
|
||||||
context.l10n
|
|
||||||
.download_count(selectedTracks.length),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (!userPlaylist)
|
),
|
||||||
|
SortTracksDropdown(
|
||||||
|
value: sortBy,
|
||||||
|
onChanged: (value) {
|
||||||
|
ref
|
||||||
|
.read(trackCollectionSortState(playlistId ?? '')
|
||||||
|
.notifier)
|
||||||
|
.state = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
PopupMenuButton(
|
||||||
|
tooltip: context.l10n.more_actions,
|
||||||
|
itemBuilder: (context) {
|
||||||
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
enabled: selectedTracks.isNotEmpty,
|
enabled: selectedTracks.isNotEmpty,
|
||||||
value: "add-to-playlist",
|
value: "download",
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const Icon(SpotubeIcons.playlistAdd),
|
const Icon(SpotubeIcons.download),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
Text(
|
Text(
|
||||||
context.l10n.add_count_to_playlist(
|
context.l10n
|
||||||
selectedTracks.length,
|
.download_count(selectedTracks.length),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
if (!userPlaylist)
|
||||||
enabled: selectedTracks.isNotEmpty,
|
PopupMenuItem(
|
||||||
value: "add-to-queue",
|
enabled: selectedTracks.isNotEmpty,
|
||||||
child: Row(
|
value: "add-to-playlist",
|
||||||
children: [
|
child: Row(
|
||||||
const Icon(SpotubeIcons.queueAdd),
|
children: [
|
||||||
const SizedBox(width: 5),
|
const Icon(SpotubeIcons.playlistAdd),
|
||||||
Text(
|
const SizedBox(width: 5),
|
||||||
context.l10n
|
Text(
|
||||||
.add_count_to_queue(selectedTracks.length),
|
context.l10n.add_count_to_playlist(
|
||||||
|
selectedTracks.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
enabled: selectedTracks.isNotEmpty,
|
||||||
|
value: "add-to-queue",
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(SpotubeIcons.queueAdd),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(
|
||||||
|
context.l10n
|
||||||
|
.add_count_to_queue(selectedTracks.length),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
PopupMenuItem(
|
||||||
PopupMenuItem(
|
enabled: selectedTracks.isNotEmpty,
|
||||||
enabled: selectedTracks.isNotEmpty,
|
value: "play-next",
|
||||||
value: "play-next",
|
child: Row(
|
||||||
child: Row(
|
children: [
|
||||||
children: [
|
const Icon(SpotubeIcons.lightning),
|
||||||
const Icon(SpotubeIcons.lightning),
|
const SizedBox(width: 5),
|
||||||
const SizedBox(width: 5),
|
Text(
|
||||||
Text(
|
context.l10n
|
||||||
context.l10n
|
.play_count_next(selectedTracks.length),
|
||||||
.play_count_next(selectedTracks.length),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
];
|
||||||
];
|
},
|
||||||
},
|
onSelected: (action) async {
|
||||||
onSelected: (action) async {
|
switch (action) {
|
||||||
switch (action) {
|
case "download":
|
||||||
case "download":
|
{
|
||||||
{
|
final confirmed = await showDialog(
|
||||||
final confirmed = await showDialog(
|
context: context,
|
||||||
context: context,
|
builder: (context) {
|
||||||
builder: (context) {
|
return const ConfirmDownloadDialog();
|
||||||
return const ConfirmDownloadDialog();
|
},
|
||||||
},
|
);
|
||||||
);
|
if (confirmed != true) return;
|
||||||
if (confirmed != true) return;
|
await downloader
|
||||||
await downloader.enqueueAll(selectedTracks.toList());
|
.enqueueAll(selectedTracks.toList());
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
selected.value = [];
|
||||||
|
showCheck.value = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "add-to-playlist":
|
||||||
|
{
|
||||||
|
await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return PlaylistAddTrackDialog(
|
||||||
|
tracks: selectedTracks.toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "play-next":
|
||||||
|
{
|
||||||
|
playback.addTracksAtFirst(selectedTracks);
|
||||||
selected.value = [];
|
selected.value = [];
|
||||||
showCheck.value = false;
|
showCheck.value = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case "add-to-queue":
|
||||||
}
|
{
|
||||||
case "add-to-playlist":
|
playback.addTracks(selectedTracks);
|
||||||
{
|
selected.value = [];
|
||||||
await showDialog(
|
showCheck.value = false;
|
||||||
context: context,
|
break;
|
||||||
builder: (context) {
|
}
|
||||||
return PlaylistAddTrackDialog(
|
default:
|
||||||
tracks: selectedTracks.toList(),
|
}
|
||||||
);
|
},
|
||||||
},
|
icon: const Icon(SpotubeIcons.moreVertical),
|
||||||
);
|
),
|
||||||
break;
|
const SizedBox(width: 10),
|
||||||
}
|
],
|
||||||
case "play-next":
|
);
|
||||||
{
|
}),
|
||||||
playback.addTracksAtFirst(selectedTracks);
|
|
||||||
selected.value = [];
|
|
||||||
showCheck.value = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "add-to-queue":
|
|
||||||
{
|
|
||||||
playback.addTracks(selectedTracks);
|
|
||||||
selected.value = [];
|
|
||||||
showCheck.value = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: const Icon(SpotubeIcons.moreVertical),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
...sortedTracks.mapIndexed((i, track) {
|
...sortedTracks.mapIndexed((i, track) {
|
||||||
return TrackTile(
|
return TrackTile(
|
||||||
index: i,
|
index: i,
|
||||||
|
Loading…
Reference in New Issue
Block a user