mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
simplified the layout of TrackTableView
This commit is contained in:
parent
72ff732505
commit
8c3a62569a
@ -4,12 +4,10 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/components/Album/AlbumCard.dart';
|
import 'package:spotube/components/Album/AlbumCard.dart';
|
||||||
import 'package:spotube/components/Album/AlbumView.dart';
|
|
||||||
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
||||||
import 'package:spotube/components/Artist/ArtistCard.dart';
|
import 'package:spotube/components/Artist/ArtistCard.dart';
|
||||||
import 'package:spotube/components/Shared/LinkText.dart';
|
|
||||||
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
||||||
import 'package:spotube/helpers/artists-to-clickable-artists.dart';
|
import 'package:spotube/components/Shared/TracksTableView.dart';
|
||||||
import 'package:spotube/helpers/readable-number.dart';
|
import 'package:spotube/helpers/readable-number.dart';
|
||||||
import 'package:spotube/helpers/zero-pad-num-str.dart';
|
import 'package:spotube/helpers/zero-pad-num-str.dart';
|
||||||
import 'package:spotube/provider/Playback.dart';
|
import 'package:spotube/provider/Playback.dart';
|
||||||
@ -162,81 +160,49 @@ class _ArtistProfileState extends State<ArtistProfile> {
|
|||||||
"Top Tracks",
|
"Top Tracks",
|
||||||
style: Theme.of(context).textTheme.headline4,
|
style: Theme.of(context).textTheme.headline4,
|
||||||
),
|
),
|
||||||
IconButton(
|
Container(
|
||||||
icon: Icon(isPlaylistPlaying
|
margin: const EdgeInsets.symmetric(horizontal: 5),
|
||||||
? Icons.stop_circle_rounded
|
decoration: BoxDecoration(
|
||||||
: Icons.play_circle_filled_rounded),
|
color: Theme.of(context).primaryColor,
|
||||||
color: Theme.of(context).primaryColor,
|
borderRadius: BorderRadius.circular(50),
|
||||||
onPressed: trackSnapshot.hasData
|
),
|
||||||
? () =>
|
child: IconButton(
|
||||||
playPlaylist(trackSnapshot.data!.toList())
|
icon: Icon(isPlaylistPlaying
|
||||||
: null,
|
? Icons.stop_rounded
|
||||||
|
: Icons.play_arrow_rounded),
|
||||||
|
color: Colors.white,
|
||||||
|
onPressed: trackSnapshot.hasData
|
||||||
|
? () =>
|
||||||
|
playPlaylist(trackSnapshot.data!.toList())
|
||||||
|
: null,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
...trackSnapshot.data?.map((track) {
|
...trackSnapshot.data
|
||||||
|
?.toList()
|
||||||
|
.asMap()
|
||||||
|
.entries
|
||||||
|
.map((track) {
|
||||||
String duration =
|
String duration =
|
||||||
"${track.duration?.inMinutes.remainder(60)}:${zeroPadNumStr(track.duration?.inSeconds.remainder(60) ?? 0)}";
|
"${track.value.duration?.inMinutes.remainder(60)}:${zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}";
|
||||||
return Row(
|
String? thumbnailUrl = track.value.album != null &&
|
||||||
children: [
|
track.value.album!.images!.isNotEmpty
|
||||||
if (track.album != null &&
|
? track.value.album!.images!.last.url!
|
||||||
track.album!.images!.isNotEmpty)
|
: null;
|
||||||
Padding(
|
return TracksTableView.buildTrackTile(
|
||||||
padding: const EdgeInsets.all(8.0),
|
context,
|
||||||
child: ClipRRect(
|
playback,
|
||||||
borderRadius: const BorderRadius.all(
|
duration: duration,
|
||||||
Radius.circular(5)),
|
track: track,
|
||||||
child: CachedNetworkImage(
|
thumbnailUrl: thumbnailUrl,
|
||||||
placeholder: (context, url) {
|
onTrackPlayButtonPressed: (currentTrack) =>
|
||||||
return Container(
|
playPlaylist(
|
||||||
height: 40,
|
trackSnapshot.data!.toList(),
|
||||||
width: 40,
|
currentTrack: track.value,
|
||||||
color: Colors.green[300],
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
imageUrl:
|
|
||||||
track.album!.images!.last.url!,
|
|
||||||
maxHeightDiskCache: 40,
|
|
||||||
maxWidthDiskCache: 40,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
track.name ?? "",
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 17,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
artistsToClickableArtists(
|
|
||||||
track.artists ?? []),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
LinkText(
|
|
||||||
track.album!.name!,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) =>
|
|
||||||
AlbumView(track.album!),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Text(duration)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}).toList() ??
|
}) ??
|
||||||
[],
|
[],
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
@ -14,154 +14,152 @@ class TracksTableView extends StatelessWidget {
|
|||||||
const TracksTableView(this.tracks, {Key? key, this.onTrackPlayButtonPressed})
|
const TracksTableView(this.tracks, {Key? key, this.onTrackPlayButtonPressed})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
List<TableRow> trackToTableRow(
|
static Widget buildTrackTile(
|
||||||
BuildContext context, Playback playback, List<Track> tracks) {
|
BuildContext context,
|
||||||
return tracks.asMap().entries.map((track) {
|
Playback playback, {
|
||||||
String? thumbnailUrl = (track.value.album?.images?.isNotEmpty ?? false)
|
required MapEntry<int, Track> track,
|
||||||
? track.value.album?.images?.last.url
|
required String duration,
|
||||||
: null;
|
String? thumbnailUrl,
|
||||||
String duration =
|
final void Function(Track currentTrack)? onTrackPlayButtonPressed,
|
||||||
"${track.value.duration?.inMinutes.remainder(60)}:${zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}";
|
}) {
|
||||||
return (TableRow(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
TableCell(
|
SizedBox(
|
||||||
child: Padding(
|
height: 20,
|
||||||
|
width: 25,
|
||||||
|
child: Text(
|
||||||
|
(track.key + 1).toString(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (thumbnailUrl != null)
|
||||||
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text(
|
child: ClipRRect(
|
||||||
(track.key + 1).toString(),
|
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||||
textAlign: TextAlign.center,
|
child: CachedNetworkImage(
|
||||||
),
|
placeholder: (context, url) {
|
||||||
)),
|
return Container(
|
||||||
TableCell(
|
height: 40,
|
||||||
child: Row(
|
width: 40,
|
||||||
children: [
|
color: Colors.green[300],
|
||||||
IconButton(
|
);
|
||||||
icon: Icon(
|
},
|
||||||
playback.currentTrack?.id != null &&
|
imageUrl: thumbnailUrl,
|
||||||
playback.currentTrack?.id == track.value.id
|
maxHeightDiskCache: 40,
|
||||||
? Icons.pause_circle_rounded
|
maxWidthDiskCache: 40,
|
||||||
: Icons.play_circle_rounded,
|
),
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
),
|
|
||||||
onPressed: () => onTrackPlayButtonPressed?.call(
|
|
||||||
track.value,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (thumbnailUrl != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
|
||||||
child: CachedNetworkImage(
|
|
||||||
placeholder: (context, url) {
|
|
||||||
return Container(
|
|
||||||
height: 40,
|
|
||||||
width: 40,
|
|
||||||
color: Colors.green[300],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
imageUrl: thumbnailUrl,
|
|
||||||
maxHeightDiskCache: 40,
|
|
||||||
maxWidthDiskCache: 40,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Flexible(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
track.value.name ?? "",
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 17,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
artistsToClickableArtists(track.value.artists ?? []),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TableCell(
|
IconButton(
|
||||||
child: Padding(
|
icon: Icon(
|
||||||
padding: const EdgeInsets.all(8.0),
|
playback.currentTrack?.id != null &&
|
||||||
child: LinkText(
|
playback.currentTrack?.id == track.value.id
|
||||||
track.value.album?.name ?? "",
|
? Icons.pause_circle_rounded
|
||||||
|
: Icons.play_circle_rounded,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
|
onPressed: () => onTrackPlayButtonPressed?.call(
|
||||||
|
track.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
track.value.name ?? "",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 17,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
artistsToClickableArtists(track.value.artists ?? []),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
LinkText(
|
||||||
|
track.value.album!.name!,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => AlbumView(track.value.album!),
|
builder: (context) => AlbumView(track.value.album!),
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
TableCell(
|
),
|
||||||
child: Padding(
|
const SizedBox(width: 10),
|
||||||
padding: const EdgeInsets.all(8.0),
|
Text(duration),
|
||||||
child: Text(
|
const SizedBox(width: 10),
|
||||||
duration,
|
],
|
||||||
textAlign: TextAlign.center,
|
);
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}).toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Playback playback = context.watch<Playback>();
|
Playback playback = context.watch<Playback>();
|
||||||
|
|
||||||
TextStyle tableHeadStyle =
|
TextStyle tableHeadStyle =
|
||||||
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Scrollbar(
|
child: Scrollbar(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
SingleChildScrollView(
|
Row(
|
||||||
child: Table(
|
children: [
|
||||||
columnWidths: const {
|
Padding(
|
||||||
0: FixedColumnWidth(40),
|
padding: const EdgeInsets.all(8.0),
|
||||||
1: FlexColumnWidth(),
|
child: Text(
|
||||||
2: FlexColumnWidth(),
|
"#",
|
||||||
3: FixedColumnWidth(45),
|
textAlign: TextAlign.center,
|
||||||
},
|
style: tableHeadStyle,
|
||||||
children: [
|
),
|
||||||
TableRow(
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
TableCell(
|
Text(
|
||||||
child: Text(
|
|
||||||
"#",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: tableHeadStyle,
|
|
||||||
)),
|
|
||||||
TableCell(
|
|
||||||
child: Text(
|
|
||||||
"Title",
|
"Title",
|
||||||
style: tableHeadStyle,
|
style: tableHeadStyle,
|
||||||
)),
|
overflow: TextOverflow.ellipsis,
|
||||||
TableCell(
|
),
|
||||||
child: Text(
|
|
||||||
"Album",
|
|
||||||
style: tableHeadStyle,
|
|
||||||
)),
|
|
||||||
TableCell(
|
|
||||||
child: Text(
|
|
||||||
"Time",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: tableHeadStyle,
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
...trackToTableRow(context, playback, tracks),
|
),
|
||||||
],
|
// used alignment of this table-head
|
||||||
),
|
const SizedBox(width: 100),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Album",
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: tableHeadStyle,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Text("Time", style: tableHeadStyle),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
...tracks.asMap().entries.map((track) {
|
||||||
|
String? thumbnailUrl =
|
||||||
|
(track.value.album?.images?.isNotEmpty ?? false)
|
||||||
|
? track.value.album?.images?.last.url
|
||||||
|
: null;
|
||||||
|
String duration =
|
||||||
|
"${track.value.duration?.inMinutes.remainder(60)}:${zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}";
|
||||||
|
return buildTrackTile(context, playback,
|
||||||
|
track: track,
|
||||||
|
duration: duration,
|
||||||
|
thumbnailUrl: thumbnailUrl,
|
||||||
|
onTrackPlayButtonPressed: onTrackPlayButtonPressed);
|
||||||
|
}).toList()
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user