simplified the layout of TrackTableView

This commit is contained in:
Kingkor Roy Tirtho 2022-01-26 10:43:07 +06:00
parent 72ff732505
commit 8c3a62569a
2 changed files with 159 additions and 195 deletions

View File

@ -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() ?? }) ??
[], [],
]); ]);
}, },

View File

@ -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()
], ],
), ),
), ),