2020-06-23 19:23:12 +00:00
|
|
|
import 'package:filesize/filesize.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
import 'cached_image.dart';
|
|
|
|
import '../api/download.dart';
|
|
|
|
|
|
|
|
|
|
|
|
class DownloadTile extends StatelessWidget {
|
|
|
|
|
|
|
|
final Download download;
|
2020-09-01 14:41:15 +00:00
|
|
|
Function onDelete;
|
|
|
|
DownloadTile(this.download, {this.onDelete});
|
2020-06-23 19:23:12 +00:00
|
|
|
|
|
|
|
String get subtitle {
|
|
|
|
switch (download.state) {
|
|
|
|
case DownloadState.NONE: return '';
|
|
|
|
case DownloadState.DOWNLOADING:
|
|
|
|
return '${filesize(download.received)} / ${filesize(download.total)}';
|
|
|
|
case DownloadState.POST:
|
|
|
|
return 'Post processing...';
|
|
|
|
case DownloadState.DONE:
|
|
|
|
return 'Done'; //Shouldn't be visible
|
|
|
|
}
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget get progressBar {
|
|
|
|
switch (download.state) {
|
|
|
|
case DownloadState.DOWNLOADING:
|
|
|
|
return LinearProgressIndicator(value: download.received / download.total);
|
|
|
|
case DownloadState.POST:
|
|
|
|
return LinearProgressIndicator();
|
|
|
|
default:
|
|
|
|
return Container(height: 0, width: 0,);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget get trailing {
|
|
|
|
if (download.private) {
|
|
|
|
return Icon(Icons.offline_pin);
|
|
|
|
}
|
|
|
|
return Icon(Icons.sd_card);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Column(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
ListTile(
|
|
|
|
title: Text(download.track.title),
|
|
|
|
subtitle: Text(subtitle),
|
|
|
|
leading: CachedImage(
|
|
|
|
url: download.track.albumArt.thumb,
|
2020-09-09 18:50:15 +00:00
|
|
|
width: 48.0,
|
2020-06-23 19:23:12 +00:00
|
|
|
),
|
|
|
|
trailing: trailing,
|
2020-09-01 14:41:15 +00:00
|
|
|
onTap: () {
|
|
|
|
//Delete if none
|
|
|
|
if (download.state == DownloadState.NONE) {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (context) {
|
|
|
|
return AlertDialog(
|
|
|
|
title: Text('Delete'),
|
|
|
|
content: Text('Are you sure, you want to delete this download?'),
|
|
|
|
actions: [
|
|
|
|
FlatButton(
|
|
|
|
child: Text('Cancel'),
|
|
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
|
|
),
|
|
|
|
FlatButton(
|
|
|
|
child: Text('Delete'),
|
|
|
|
onPressed: () {
|
|
|
|
downloadManager.removeDownload(download);
|
|
|
|
if (this.onDelete != null) this.onDelete();
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
2020-06-23 19:23:12 +00:00
|
|
|
),
|
|
|
|
progressBar
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-01 14:41:15 +00:00
|
|
|
class DownloadsScreen extends StatefulWidget {
|
|
|
|
@override
|
|
|
|
_DownloadsScreenState createState() => _DownloadsScreenState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _DownloadsScreenState extends State<DownloadsScreen> {
|
2020-06-23 19:23:12 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Scaffold(
|
2020-09-01 14:41:15 +00:00
|
|
|
appBar: AppBar(
|
|
|
|
title: Text('Downloads'),
|
|
|
|
actions: [
|
|
|
|
IconButton(
|
2020-09-09 18:50:15 +00:00
|
|
|
icon: Icon(downloadManager.stopped ? Icons.play_arrow : Icons.stop),
|
2020-09-01 14:41:15 +00:00
|
|
|
onPressed: () {
|
2020-09-09 18:50:15 +00:00
|
|
|
setState(() {
|
|
|
|
if (downloadManager.stopped) downloadManager.start();
|
|
|
|
else downloadManager.stop();
|
|
|
|
});
|
2020-09-01 14:41:15 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
body: ListView(
|
|
|
|
children: <Widget>[
|
|
|
|
StreamBuilder(
|
|
|
|
stream: Stream.periodic(Duration(milliseconds: 500)).asBroadcastStream(), //Periodic to get current download progress
|
|
|
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
2020-06-23 19:23:12 +00:00
|
|
|
|
2020-09-01 14:41:15 +00:00
|
|
|
if (downloadManager.queue.length == 0)
|
|
|
|
return Container(width: 0, height: 0,);
|
2020-06-23 19:23:12 +00:00
|
|
|
|
2020-09-01 14:41:15 +00:00
|
|
|
return Column(
|
2020-09-09 18:50:15 +00:00
|
|
|
children: [
|
|
|
|
...List.generate(downloadManager.queue.length, (i) {
|
|
|
|
return DownloadTile(downloadManager.queue[i], onDelete: () => setState(() => {}));
|
|
|
|
}),
|
|
|
|
if (downloadManager.queue.length > 1 || (downloadManager.stopped && downloadManager.queue.length > 0))
|
|
|
|
ListTile(
|
|
|
|
title: Text('Clear queue'),
|
|
|
|
subtitle: Text("This won't delete currently downloading item"),
|
|
|
|
leading: Icon(Icons.delete),
|
|
|
|
onTap: () async {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (context) {
|
|
|
|
return AlertDialog(
|
|
|
|
title: Text('Delete'),
|
|
|
|
content: Text('Are you sure, you want to delete all queued downloads?'),
|
|
|
|
actions: [
|
|
|
|
FlatButton(
|
|
|
|
child: Text('Cancel'),
|
|
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
|
|
),
|
|
|
|
FlatButton(
|
|
|
|
child: Text('Delete'),
|
|
|
|
onPressed: () async {
|
|
|
|
await downloadManager.clearQueue();
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
},
|
|
|
|
)
|
|
|
|
]
|
2020-09-01 14:41:15 +00:00
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
FutureBuilder(
|
|
|
|
future: downloadManager.getFinishedDownloads(),
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
if (!snapshot.hasData || snapshot.data.length == 0) return Container(height: 0, width: 0,);
|
2020-06-23 19:23:12 +00:00
|
|
|
|
2020-09-01 14:41:15 +00:00
|
|
|
return Column(
|
|
|
|
children: <Widget>[
|
|
|
|
Divider(),
|
|
|
|
Text(
|
|
|
|
'History',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 24.0,
|
|
|
|
fontWeight: FontWeight.bold
|
|
|
|
),
|
2020-06-23 19:23:12 +00:00
|
|
|
),
|
2020-09-01 14:41:15 +00:00
|
|
|
...List.generate(snapshot.data.length, (i) {
|
|
|
|
Download d = snapshot.data[i];
|
|
|
|
return DownloadTile(d);
|
|
|
|
}),
|
|
|
|
ListTile(
|
|
|
|
title: Text('Clear downloads history'),
|
|
|
|
leading: Icon(Icons.delete),
|
|
|
|
subtitle: Text('WARNING: This will only clear non-offline (external downloads)'),
|
|
|
|
onTap: () async {
|
|
|
|
await downloadManager.cleanDownloadHistory();
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
2020-06-23 19:23:12 +00:00
|
|
|
);
|
|
|
|
}
|
2020-09-01 14:41:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|