opt download (#1755)

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
dom
2025-11-27 21:00:13 +08:00
committed by GitHub
parent ded78e534f
commit 9ccaa3072b
25 changed files with 1161 additions and 410 deletions

View File

@@ -34,9 +34,11 @@ class DownloadService extends GetxService {
final _lock = Lock();
final flagNotifier = <void Function()>{};
final waitDownloadQueue = <BiliDownloadEntryInfo>[];
final downloadList = RxList<BiliDownloadEntryInfo>();
final waitDownloadQueue = RxList<BiliDownloadEntryInfo>();
final downloadList = <BiliDownloadEntryInfo>[];
int? _curCid;
int? get curCid => _curCid;
final curDownload = Rxn<BiliDownloadEntryInfo>();
void _updateCurStatus(DownloadStatus status) {
if (curDownload.value != null) {
@@ -62,15 +64,14 @@ class DownloadService extends GetxService {
}
Future<void> _readDownloadList() async {
downloadList.clear();
final downloadDir = Directory(await _getDownloadPath());
final list = <BiliDownloadEntryInfo>[];
await for (final dir in downloadDir.list()) {
if (dir is Directory) {
list.addAll(await _readDownloadDirectory(dir));
downloadList.addAll(await _readDownloadDirectory(dir));
}
}
downloadList.value = list
..sort((a, b) => b.timeUpdateStamp.compareTo(a.timeUpdateStamp));
downloadList.sort((a, b) => b.timeUpdateStamp.compareTo(a.timeUpdateStamp));
}
@pragma('vm:notify-debugger-on-exception')
@@ -92,8 +93,9 @@ class DownloadService extends GetxService {
final entry = BiliDownloadEntryInfo.fromJson(jsonDecode(entryJson))
..pageDirPath = pageDir.path
..entryDirPath = entryDir.path;
result.add(entry);
if (!entry.isCompleted) {
if (entry.isCompleted) {
result.add(entry);
} else {
waitDownloadQueue.add(entry..status = DownloadStatus.wait);
}
} catch (_) {}
@@ -114,6 +116,9 @@ class DownloadService extends GetxService {
if (downloadList.indexWhere((e) => e.cid == cid) != -1) {
return;
}
if (waitDownloadQueue.indexWhere((e) => e.cid == cid) != -1) {
return;
}
final pageData = PageInfo(
cid: cid,
page: page.page!,
@@ -171,6 +176,9 @@ class DownloadService extends GetxService {
if (downloadList.indexWhere((e) => e.cid == cid) != -1) {
return;
}
if (waitDownloadQueue.indexWhere((e) => e.cid == cid) != -1) {
return;
}
final currentTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
final source = SourceInfo(
avId: episode.aid!,
@@ -235,13 +243,10 @@ class DownloadService extends GetxService {
..pageDirPath = entryDir.parent.path
..entryDirPath = entryDir.path
..status = DownloadStatus.wait;
downloadList.insert(0, entry);
flagNotifier.refresh();
waitDownloadQueue.add(entry);
final currStatus = curDownload.value?.status?.index;
if (currStatus == null || currStatus > 3) {
startDownload(entry);
} else {
waitDownloadQueue.add(entry);
}
}
@@ -283,7 +288,9 @@ class DownloadService extends GetxService {
curDownload.value?.status = DownloadStatus.pause;
}
_curCid = entry.cid;
curDownload.value = entry;
waitDownloadQueue.refresh();
await _startDownload(entry);
});
}
@@ -450,6 +457,11 @@ class DownloadService extends GetxService {
}
void _onDone([Object? error]) {
if (error != null) {
_updateCurStatus(DownloadStatus.failDownload);
return;
}
final status = switch (_audioDownloadManager?.status) {
DownloadStatus.downloading => DownloadStatus.audioDownloading,
DownloadStatus.failDownload => DownloadStatus.failDownloadAudio,
@@ -458,9 +470,7 @@ class DownloadService extends GetxService {
_updateCurStatus(status);
if (curDownload.value case final curEntryInfo?) {
if (error == null) {
curEntryInfo.downloadedBytes = curEntryInfo.totalBytes;
}
curEntryInfo.downloadedBytes = curEntryInfo.totalBytes;
if (status == DownloadStatus.completed) {
_completeDownload();
} else {
@@ -493,29 +503,40 @@ class DownloadService extends GetxService {
..downloadedBytes = entry.totalBytes
..isCompleted = true;
await _updateBiliDownloadEntryJson(entry);
waitDownloadQueue.remove(entry);
downloadList.insert(0, entry);
flagNotifier.refresh();
_curCid = null;
curDownload.value = null;
_downloadManager = null;
_audioDownloadManager = null;
_nextDownload();
nextDownload();
}
void _nextDownload() {
void nextDownload() {
if (waitDownloadQueue.isNotEmpty) {
final next = waitDownloadQueue.removeAt(0);
if (!next.isCompleted && downloadList.contains(next)) {
startDownload(next);
} else {
_nextDownload();
}
startDownload(waitDownloadQueue.first);
}
}
Future<void> deleteDownload({
required BiliDownloadEntryInfo entry,
bool removeList = false,
bool removeQueue = false,
bool refresh = true,
bool downloadNext = true,
}) async {
if (removeList) {
downloadList.remove(entry);
}
if (removeQueue) {
waitDownloadQueue.remove(entry);
}
if (curDownload.value?.cid == entry.cid) {
await cancelDownload(isDelete: true);
await cancelDownload(
isDelete: true,
downloadNext: downloadNext,
);
}
final downloadDir = Directory(entry.pageDirPath);
if (downloadDir.existsSync()) {
@@ -528,15 +549,20 @@ class DownloadService extends GetxService {
}
}
}
downloadList.remove(entry);
waitDownloadQueue.remove(entry);
flagNotifier.refresh();
if (refresh) {
flagNotifier.refresh();
}
}
Future<void> deletePage({required String pageDirPath}) async {
Future<void> deletePage({
required String pageDirPath,
bool refresh = true,
}) async {
await Directory(pageDirPath).tryDel(recursive: true);
downloadList.removeWhere((e) => e.pageDirPath == pageDirPath);
flagNotifier.refresh();
if (refresh) {
flagNotifier.refresh();
}
}
Future<void> cancelDownload({
@@ -554,17 +580,18 @@ class DownloadService extends GetxService {
}
}
if (isDelete) {
_curCid = null;
curDownload.value = null;
} else {
_updateCurStatus(DownloadStatus.pause);
}
if (downloadNext) {
_nextDownload();
nextDownload();
}
}
}
extension on Set<void Function()> {
extension SetExt on Set<void Function()> {
void refresh() {
for (var i in this) {
i();