135 lines
5.0 KiB
Dart
135 lines
5.0 KiB
Dart
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();
|
|
}
|
|
},
|
|
);
|
|
}
|
|
} |