Add the feature for updating local favorites info

This commit is contained in:
2024-11-13 08:57:37 +08:00
parent 00bcbaa2eb
commit 8e99e94620
3 changed files with 136 additions and 6 deletions

View File

@@ -201,7 +201,10 @@
"Select All": "全选",
"Deselect": "取消选择",
"Invert Selection": "反选",
"Select in range": "区间选择"
"Select in range": "区间选择",
"Finished": "已完成",
"Updating": "更新中",
"Update Comics Info": "更新漫画信息"
},
"zh_TW": {
"Home": "首頁",
@@ -405,6 +408,9 @@
"Select All": "全選",
"Deselect": "取消選擇",
"Invert Selection": "反選",
"Select in range": "區間選擇"
"Select in range": "區間選擇",
"Finished": "已完成",
"Updating": "更新中",
"Update Comics Info": "更新漫畫信息"
}
}

View File

@@ -34,12 +34,11 @@ Future<void> newFolder() async {
child: Text("Import from file".tl),
onPressed: () async {
var file = await selectFile(ext: ['json']);
if(file == null) return;
if (file == null) return;
var data = await file.readAsBytes();
try {
LocalFavoritesManager().fromJson(utf8.decode(data));
}
catch(e) {
} catch (e) {
context.showMessage(message: "Failed to import".tl);
return;
}
@@ -113,7 +112,9 @@ void addFavorite(Comic comic) {
name: comic.title,
coverPath: comic.cover,
author: comic.subtitle ?? '',
type: ComicType((comic.sourceKey == 'local' ? 0 : comic.sourceKey.hashCode)),
type: ComicType((comic.sourceKey == 'local'
? 0
: comic.sourceKey.hashCode)),
tags: comic.tags ?? [],
),
);
@@ -128,3 +129,114 @@ void addFavorite(Comic comic) {
},
);
}
Future<List<FavoriteItem>> updateComicsInfo(String folder) async {
var comics = LocalFavoritesManager().getAllComics(folder);
Future<void> updateSingleComic(int index) async {
int retry = 3;
while (true) {
try {
var c = comics[index];
var comicSource = c.type.comicSource;
if (comicSource == null) return;
var newInfo = (await comicSource.loadComicInfo!(c.id)).data;
comics[index] = FavoriteItem(
id: c.id,
name: newInfo.title,
coverPath: newInfo.cover,
author: newInfo.subTitle ??
newInfo.tags['author']?.firstOrNull ??
c.author,
type: c.type,
tags: c.tags,
);
LocalFavoritesManager().updateInfo(folder, comics[index]);
return;
} catch (e) {
retry--;
if(retry == 0) {
rethrow;
}
continue;
}
}
}
var finished = ValueNotifier(0);
var errors = 0;
var index = 0;
bool isCanceled = false;
showDialog(
context: App.rootContext,
builder: (context) {
return ValueListenableBuilder(
valueListenable: finished,
builder: (context, value, child) {
var isFinished = value == comics.length;
return ContentDialog(
title: isFinished ? "Finished".tl : "Updating".tl,
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 4),
LinearProgressIndicator(
value: value / comics.length,
),
const SizedBox(height: 4),
Text("$value/${comics.length}"),
const SizedBox(height: 4),
if (errors > 0) Text("Errors: $errors"),
],
).paddingHorizontal(16),
actions: [
Button.filled(
color: isFinished ? null : context.colorScheme.error,
onPressed: () {
isCanceled = true;
context.pop();
},
child: isFinished ?Text("OK".tl) : Text("Cancel".tl),
),
],
);
},
);
},
).then((_) {
isCanceled = true;
});
while(index < comics.length) {
var futures = <Future>[];
const maxConcurrency = 4;
if(isCanceled) {
return comics;
}
for (var i = 0; i < maxConcurrency; i++) {
if (index+i >= comics.length) break;
futures.add(updateSingleComic(index + i).then((v) {
finished.value++;
}, onError: (_) {
errors++;
finished.value++;
}));
}
await Future.wait(futures);
index += maxConcurrency;
}
return comics;
}

View File

@@ -123,6 +123,18 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
filename: "${widget.folder}.json",
);
}),
MenuEntry(
icon: Icons.update,
text: "Update Comics Info".tl,
onClick: () {
updateComicsInfo(widget.folder).then((newComics) {
if(mounted) {
setState(() {
comics = newComics;
});
}
});
}),
],
),
],