Split discography, copy arl button, small fixes
This commit is contained in:
parent
4e5e3a3059
commit
b9004c3004
7 changed files with 227 additions and 102 deletions
|
@ -26,6 +26,15 @@ class AlbumDetails extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
//Get count of CDs in album
|
||||
int get cdCount {
|
||||
int c = 1;
|
||||
for (Track t in album.tracks) {
|
||||
if (t.diskNumber > c) c = t.diskNumber;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
@ -153,19 +162,27 @@ class AlbumDetails extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
...List.generate(album.tracks.length, (i) {
|
||||
Track t = album.tracks[i];
|
||||
return TrackTile(
|
||||
t,
|
||||
onTap: () {
|
||||
playerHelper.playFromAlbum(album, t.id);
|
||||
},
|
||||
onHold: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultTrackMenu(t);
|
||||
}
|
||||
...List.generate(cdCount, (cdi) {
|
||||
List<Track> tracks = album.tracks.where((t) => t.diskNumber == cdi + 1).toList();
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Text('Disk ${cdi + 1}'),
|
||||
),
|
||||
...List.generate(tracks.length, (i) => TrackTile(
|
||||
tracks[i],
|
||||
onTap: () {
|
||||
playerHelper.playFromAlbum(album, tracks[i].id);
|
||||
},
|
||||
onHold: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultTrackMenu(tracks[i]);
|
||||
}
|
||||
))
|
||||
],
|
||||
);
|
||||
})
|
||||
}),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
@ -433,7 +450,7 @@ class ArtistDetails extends StatelessWidget {
|
|||
|
||||
class DiscographyScreen extends StatefulWidget {
|
||||
|
||||
Artist artist;
|
||||
final Artist artist;
|
||||
DiscographyScreen({@required this.artist, Key key}): super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -445,7 +462,11 @@ class _DiscographyScreenState extends State<DiscographyScreen> {
|
|||
Artist artist;
|
||||
bool _loading = false;
|
||||
bool _error = false;
|
||||
ScrollController _scrollController = ScrollController();
|
||||
List<ScrollController> _controllers = [
|
||||
ScrollController(),
|
||||
ScrollController(),
|
||||
ScrollController()
|
||||
];
|
||||
|
||||
Future _load() async {
|
||||
if (artist.albums.length >= artist.albumCount || _loading) return;
|
||||
|
@ -471,16 +492,42 @@ class _DiscographyScreenState extends State<DiscographyScreen> {
|
|||
|
||||
}
|
||||
|
||||
//Get album tile
|
||||
Widget _tile(Album a) => AlbumTile(
|
||||
a,
|
||||
onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => AlbumDetails(a))),
|
||||
onHold: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultAlbumMenu(a);
|
||||
},
|
||||
);
|
||||
|
||||
Widget get _loadingWidget {
|
||||
if (_loading)
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [CircularProgressIndicator()],
|
||||
),
|
||||
);
|
||||
//Error
|
||||
if (_error)
|
||||
return ErrorScreen();
|
||||
//Success
|
||||
return Container(width: 0, height: 0,);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
artist = widget.artist;
|
||||
|
||||
//Lazy loading scroll
|
||||
_scrollController.addListener(() {
|
||||
double off = _scrollController.position.maxScrollExtent * 0.90;
|
||||
if (_scrollController.position.pixels > off) {
|
||||
_load();
|
||||
}
|
||||
_controllers.forEach((_c) {
|
||||
_c.addListener(() {
|
||||
double off = _c.position.maxScrollExtent * 0.85;
|
||||
if (_c.position.pixels > off) _load();
|
||||
});
|
||||
});
|
||||
|
||||
super.initState();
|
||||
|
@ -488,41 +535,68 @@ class _DiscographyScreenState extends State<DiscographyScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Discography'),),
|
||||
body: ListView.builder(
|
||||
controller: _scrollController,
|
||||
itemCount: artist.albums.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
//Loading
|
||||
if (i == artist.albums.length) {
|
||||
if (_loading)
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [CircularProgressIndicator()],
|
||||
);
|
||||
//Error
|
||||
if (_error)
|
||||
return ErrorScreen();
|
||||
//Success
|
||||
return Container(width: 0, height: 0,);
|
||||
}
|
||||
|
||||
Album a = artist.albums[i];
|
||||
return AlbumTile(
|
||||
a,
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => AlbumDetails(a))
|
||||
);
|
||||
},
|
||||
onHold: () {
|
||||
MenuSheet m = MenuSheet(context);
|
||||
m.defaultAlbumMenu(a);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
return DefaultTabController(
|
||||
length: 3,
|
||||
child: Builder(builder: (BuildContext context) {
|
||||
|
||||
final TabController tabController = DefaultTabController.of(context);
|
||||
tabController.addListener(() {
|
||||
if (!tabController.indexIsChanging) {
|
||||
//Load data if empty tabs
|
||||
int nSingles = artist.albums.where((a) => a.type == AlbumType.SINGLE).length;
|
||||
int nFeatures = artist.albums.where((a) => a.type == AlbumType.FEATURED).length;
|
||||
if ((nSingles == 0 || nFeatures == 0) && !_loading) _load();
|
||||
}
|
||||
});
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Discography'),
|
||||
bottom: TabBar(
|
||||
tabs: [
|
||||
Tab(icon: Icon(Icons.album)),
|
||||
Tab(icon: Icon(Icons.audiotrack)),
|
||||
Tab(icon: Icon(Icons.recent_actors))
|
||||
],
|
||||
),
|
||||
),
|
||||
body: TabBarView(
|
||||
children: [
|
||||
//Albums
|
||||
ListView.builder(
|
||||
controller: _controllers[0],
|
||||
itemCount: artist.albums.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
if (i == artist.albums.length) return _loadingWidget;
|
||||
if (artist.albums[i].type == AlbumType.ALBUM) return _tile(artist.albums[i]);
|
||||
return Container(width: 0, height: 0,);
|
||||
},
|
||||
),
|
||||
//Singles
|
||||
ListView.builder(
|
||||
controller: _controllers[1],
|
||||
itemCount: artist.albums.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
if (i == artist.albums.length) return _loadingWidget;
|
||||
if (artist.albums[i].type == AlbumType.SINGLE) return _tile(artist.albums[i]);
|
||||
return Container(width: 0, height: 0,);
|
||||
},
|
||||
),
|
||||
//Featured
|
||||
ListView.builder(
|
||||
controller: _controllers[2],
|
||||
itemCount: artist.albums.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
if (i == artist.albums.length) return _loadingWidget;
|
||||
if (artist.albums[i].type == AlbumType.FEATURED) return _tile(artist.albums[i]);
|
||||
return Container(width: 0, height: 0,);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:language_pickers/languages.dart';
|
|||
import 'package:package_info/package_info.dart';
|
||||
import 'package:path_provider_ex/path_provider_ex.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:clipboard/clipboard.dart';
|
||||
|
||||
import '../settings.dart';
|
||||
import '../main.dart';
|
||||
|
@ -34,7 +35,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
//Load about text
|
||||
PackageInfo.fromPlatform().then((PackageInfo info) {
|
||||
setState(() {
|
||||
_about = '${info.appName} ${info.version}';
|
||||
_about = '${info.appName}';
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
|
@ -566,6 +567,17 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
|||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Copy ARL'),
|
||||
subtitle: Text('Copy userToken/ARL Cookie for use in other apps.'),
|
||||
leading: Icon(Icons.lock),
|
||||
onTap: () async {
|
||||
await FlutterClipboard.copy(settings.arl);
|
||||
await Fluttertoast.showToast(
|
||||
msg: 'Copied',
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Log out', style: TextStyle(color: Colors.red),),
|
||||
leading: Icon(Icons.exit_to_app),
|
||||
|
|
|
@ -62,7 +62,16 @@ class _TrackTileState extends State<TrackTile> {
|
|||
),
|
||||
onTap: widget.onTap,
|
||||
onLongPress: widget.onHold,
|
||||
trailing: widget.trailing,
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 2.0),
|
||||
child: Text(widget.track.durationString),
|
||||
),
|
||||
widget.trailing??Container(width: 0, height: 0)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +129,7 @@ class ArtistTile extends StatelessWidget {
|
|||
CachedImage(
|
||||
url: artist.picture.thumb,
|
||||
circular: true,
|
||||
width: 64,
|
||||
width: 100,
|
||||
),
|
||||
Container(height: 4,),
|
||||
Text(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue