first commit
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
import '../../models/finamp_models.dart';
|
||||
import '../../services/downloads_helper.dart';
|
||||
import '../../services/download_update_stream.dart';
|
||||
import '../../models/jellyfin_models.dart';
|
||||
import '../error_snackbar.dart';
|
||||
|
||||
class DownloadedIndicator extends StatefulWidget {
|
||||
const DownloadedIndicator({
|
||||
Key? key,
|
||||
required this.item,
|
||||
this.size,
|
||||
}) : super(key: key);
|
||||
|
||||
final BaseItemDto item;
|
||||
final double? size;
|
||||
|
||||
@override
|
||||
State<DownloadedIndicator> createState() => _DownloadedIndicatorState();
|
||||
}
|
||||
|
||||
class _DownloadedIndicatorState extends State<DownloadedIndicator> {
|
||||
final _downloadsHelper = GetIt.instance<DownloadsHelper>();
|
||||
final _downloadUpdateStream = GetIt.instance<DownloadUpdateStream>();
|
||||
|
||||
late Future<List<DownloadTask>?> _downloadedIndicatorFuture;
|
||||
String? _downloadTaskId;
|
||||
|
||||
DownloadTaskStatus? _currentStatus;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_downloadedIndicatorFuture =
|
||||
_downloadsHelper.getDownloadStatus([widget.item.id]);
|
||||
|
||||
// We do this instead of using a StreamBuilder because the StreamBuilder
|
||||
// kept dropping events. With this, we can also make it so that the widget
|
||||
// only rebuilds when it actually has to.
|
||||
_downloadUpdateStream.stream.listen((event) {
|
||||
if (event.id == _downloadTaskId && event.status != _currentStatus) {
|
||||
setState(() {
|
||||
_currentStatus = event.status;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<List<DownloadTask>?>(
|
||||
future: _downloadedIndicatorFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
if (snapshot.data != null && snapshot.data!.isNotEmpty) {
|
||||
_downloadTaskId = snapshot.data?[0].taskId;
|
||||
_currentStatus = snapshot.data?[0].status;
|
||||
}
|
||||
// This ValueListenable is used to get the download task ID of new
|
||||
// downloads. It also clears the task ID and status when the download
|
||||
// is deleted. This only rebuilds when the item with key
|
||||
// widget.item.id is changed, so this should only rebuild when the
|
||||
// item is first downloaded and when it is deleted.
|
||||
return ValueListenableBuilder<Box<DownloadedSong>>(
|
||||
valueListenable: _downloadsHelper
|
||||
.getDownloadedItemsListenable(keys: [widget.item.id]),
|
||||
builder: (context, box, _) {
|
||||
if (_downloadTaskId == null && box.get(widget.item.id) != null) {
|
||||
_downloadTaskId = box.get(widget.item.id)!.downloadId;
|
||||
} else if (box.get(widget.item.id) == null) {
|
||||
_downloadTaskId = null;
|
||||
_currentStatus = null;
|
||||
}
|
||||
// return StreamBuilder<DownloadUpdate>(
|
||||
// stream: _downloadUpdateStream.stream,
|
||||
// builder: (context, snapshot) {
|
||||
// print("Streambuilder rebuild ${snapshot.data}");
|
||||
// if (snapshot.hasData &&
|
||||
// snapshot.data!.id == _downloadTask?.taskId) {
|
||||
// print("Change $_currentStatus to ${snapshot.data?.status}");
|
||||
// if (snapshot.data?.status == DownloadTaskStatus.complete) {
|
||||
// print(
|
||||
// "COMPLETE IN STREAMBUILDER ${widget.item.name}!!!!");
|
||||
// }
|
||||
// _currentStatus = snapshot.data?.status;
|
||||
// }
|
||||
if (_currentStatus == null) {
|
||||
return const SizedBox.shrink();
|
||||
} else if (_currentStatus == DownloadTaskStatus.complete) {
|
||||
return Icon(
|
||||
Icons.download,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
size: widget.size,
|
||||
);
|
||||
} else if (_currentStatus == DownloadTaskStatus.failed ||
|
||||
_currentStatus == DownloadTaskStatus.undefined) {
|
||||
return Icon(
|
||||
Icons.error,
|
||||
color: Colors.red,
|
||||
size: widget.size,
|
||||
);
|
||||
} else if (_currentStatus == DownloadTaskStatus.paused) {
|
||||
return Icon(
|
||||
Icons.pause,
|
||||
color: Colors.yellow,
|
||||
size: widget.size,
|
||||
);
|
||||
} else if (_currentStatus == DownloadTaskStatus.enqueued ||
|
||||
_currentStatus == DownloadTaskStatus.running) {
|
||||
return Icon(
|
||||
Icons.download_outlined,
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
size: widget.size,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
// },
|
||||
// );
|
||||
},
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
errorSnackbar(snapshot.error, context);
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user