From 55d8f0763808d4abfe7309cf34c831e335e51d07 Mon Sep 17 00:00:00 2001 From: Yoshiro_fan Date: Sun, 5 Jan 2025 16:07:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20jm=E5=AF=BC=E5=85=A5,=20pica=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95nhentai=E6=9C=89=E9=97=AE=E9=A2=98,?= =?UTF-8?q?=20=E4=B8=80=E9=94=AE=E5=8F=8D=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/gradle.properties | 6 +- assets/translation.json | 2 + lib/foundation/comic_source/favorites.dart | 6 +- lib/foundation/comic_source/parser.dart | 4 +- lib/foundation/image_favorites.dart | 2 +- lib/pages/favorites/favorite_actions.dart | 8 +- lib/pages/favorites/local_favorites_page.dart | 58 ++++++----- .../image_favorites_item.dart | 96 ++++++++++++------- .../image_favorites_page.dart | 2 +- lib/utils/data.dart | 5 +- lib/utils/io.dart | 1 - "\344\273\273\345\212\241.md" | 64 ------------- 12 files changed, 114 insertions(+), 140 deletions(-) delete mode 100644 "\344\273\273\345\212\241.md" diff --git a/android/gradle.properties b/android/gradle.properties index f8197f1..85eda9d 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -3,8 +3,4 @@ android.useAndroidX=true android.enableJetifier=true android.defaults.buildfeatures.buildconfig=true android.nonTransitiveRClass=false -android.nonFinalResIds=false -systemProp.http.proxyHost=127.0.0.1 -systemProp.http.proxyPort=7890 -systemProp.https.proxyHost=127.0.0.1 -systemProp.https.proxyPort=7890 \ No newline at end of file +android.nonFinalResIds=false \ No newline at end of file diff --git a/assets/translation.json b/assets/translation.json index 6e9812f..a0f1a8f 100644 --- a/assets/translation.json +++ b/assets/translation.json @@ -41,6 +41,7 @@ "Select a folder": "选择一个文件夹", "Folder": "文件夹", "Confirm": "确认", + "Reversed successfully": "反转成功", "Remove comic from favorite?": "从收藏中移除漫画?", "Move": "移动", "Move to folder": "移动到文件夹", @@ -460,6 +461,7 @@ "Date": "日期", "Date Desc": "日期降序", "Start": "開始", + "Reversed successfully": "反轉成功", "Export App Data": "匯出應用數據", "Import App Data (Please restart after success)": "匯入應用數據(成功后請手動重啟)", "Export": "匯出", diff --git a/lib/foundation/comic_source/favorites.dart b/lib/foundation/comic_source/favorites.dart index 76b2ec0..a6423f5 100644 --- a/lib/foundation/comic_source/favorites.dart +++ b/lib/foundation/comic_source/favorites.dart @@ -11,8 +11,8 @@ class FavoriteData { final bool multiFolder; // 这个收藏时间新旧顺序, 是为了最小成本同步远端的收藏, 只拉取远程最新收藏的漫画, 就不需要全拉取一遍了 - // 如果为 null, 不做处理, 拉取全部 - final bool? isNewToOldSort; + // 如果为 null, 当做从新到旧 + final bool? isOldToNewSort; final Future>> Function(int page, [String? folder])? loadComic; @@ -48,7 +48,7 @@ class FavoriteData { this.addFolder, this.allFavoritesId, this.addOrDelFavorite, - this.isNewToOldSort, + this.isOldToNewSort, }); } diff --git a/lib/foundation/comic_source/parser.dart b/lib/foundation/comic_source/parser.dart index efef8e5..ea1b3b1 100644 --- a/lib/foundation/comic_source/parser.dart +++ b/lib/foundation/comic_source/parser.dart @@ -618,7 +618,7 @@ class ComicSourceParser { if (!_checkExists("favorites")) return null; final bool multiFolder = _getValue("favorites.multiFolder"); - final bool? isNewToOldSort = _getValue("favorites.isNewToOldSort"); + final bool? isOldToNewSort = _getValue("favorites.isOldToNewSort"); Future> retryZone(Future> Function() func) async { if (!ComicSource.find(_key!)!.isLogged) { @@ -771,7 +771,7 @@ class ComicSourceParser { addFolder: addFolder, deleteFolder: deleteFolder, addOrDelFavorite: addOrDelFavFunc, - isNewToOldSort: isNewToOldSort, + isOldToNewSort: isOldToNewSort, ); } diff --git a/lib/foundation/image_favorites.dart b/lib/foundation/image_favorites.dart index f27d97f..eb78ea7 100644 --- a/lib/foundation/image_favorites.dart +++ b/lib/foundation/image_favorites.dart @@ -73,7 +73,7 @@ class ImageFavoritePro extends ImageFavorite { } class ImageFavoritesEp { - final String eid; + String eid; final int ep; int maxPage; String epName; diff --git a/lib/pages/favorites/favorite_actions.dart b/lib/pages/favorites/favorite_actions.dart index 63fdc59..98a858e 100644 --- a/lib/pages/favorites/favorite_actions.dart +++ b/lib/pages/favorites/favorite_actions.dart @@ -333,7 +333,7 @@ Future importNetworkFolder( folderID ?? "", ); } - bool isNewToOldSort = comicSource.favoriteData?.isNewToOldSort ?? true; + bool isOldToNewSort = comicSource.favoriteData?.isOldToNewSort ?? false; var current = 0; int receivedComics = 0; int requestCount = 0; @@ -341,7 +341,7 @@ Future importNetworkFolder( int maxPage = 1; String? next; // 如果是从旧到新, 先取一下maxPage - if (!isNewToOldSort) { + if (isOldToNewSort) { var res = await comicSource.favoriteData?.loadComic!(1, folderID); maxPage = res?.subData ?? 1; } @@ -350,7 +350,7 @@ Future importNetworkFolder( while (updatePageNum >= requestCount && !isFinished) { try { if (comicSource.favoriteData?.loadComic != null) { - next ??= isNewToOldSort ? '1' : maxPage.toString(); + next ??= isOldToNewSort ? maxPage.toString() : '1'; var page = int.parse(next!); var res = await comicSource.favoriteData!.loadComic!(page, folderID); var count = 0; @@ -378,7 +378,7 @@ Future importNetworkFolder( next = null; } else { next = - isNewToOldSort ? (page + 1).toString() : (page - 1).toString(); + isOldToNewSort ? (page - 1).toString() : (page + 1).toString(); } } else if (comicSource.favoriteData?.loadNext != null) { var res = await comicSource.favoriteData!.loadNext!(next, folderID); diff --git a/lib/pages/favorites/local_favorites_page.dart b/lib/pages/favorites/local_favorites_page.dart index c71aa77..5247d89 100644 --- a/lib/pages/favorites/local_favorites_page.dart +++ b/lib/pages/favorites/local_favorites_page.dart @@ -44,30 +44,29 @@ class _SelectUpdatePageNumState extends State<_SelectUpdatePageNum> { Row( children: [Text(text)], ), - if (source?.favoriteData?.isNewToOldSort != null) - Row( - children: [ - Text("Update the page number by the latest collection".tl), - Spacer(), - Select( - current: updatePageNum.toString() == '9999999' - ? allPageText - : updatePageNum.toString(), - values: pageNumList, - minWidth: 64, - onTap: (index) { - setState(() { - updatePageNum = int.parse(pageNumList[index] == allPageText - ? '9999999' - : pageNumList[index]); - appdata.implicitData["local_favorites_update_page_num"] = - updatePageNum; - appdata.writeImplicitData(); - }); - }, - ) - ], - ), + Row( + children: [ + Text("Update the page number by the latest collection".tl), + Spacer(), + Select( + current: updatePageNum.toString() == '9999999' + ? allPageText + : updatePageNum.toString(), + values: pageNumList, + minWidth: 64, + onTap: (index) { + setState(() { + updatePageNum = int.parse(pageNumList[index] == allPageText + ? '9999999' + : pageNumList[index]); + appdata.implicitData["local_favorites_update_page_num"] = + updatePageNum; + appdata.writeImplicitData(); + }); + }, + ) + ], + ), ], ); } @@ -816,6 +815,17 @@ class _ReorderComicsPageState extends State<_ReorderComicsPage> { ); }, ), + IconButton( + icon: const Icon(Icons.swap_vert), + onPressed: () { + setState(() { + comics = comics.reversed.toList(); + changed = true; + showToast( + message: "Reversed successfully".tl, context: context); + }); + }, + ), ], ), body: ReorderableBuilder( diff --git a/lib/pages/image_favorites_page/image_favorites_item.dart b/lib/pages/image_favorites_page/image_favorites_item.dart index 7c7ec71..ca87269 100644 --- a/lib/pages/image_favorites_page/image_favorites_item.dart +++ b/lib/pages/image_favorites_page/image_favorites_item.dart @@ -28,7 +28,7 @@ class ImageFavoritesItemState extends State { bool hasRefreshImageKeyOnErr = false; late LoadingImageFavoritesComicRes loadingImageFavoritesComicRes; - // 如果 imageKey 失效了, 或者刚从pica导入(没有imageKey) + // 如果刚从pica导入(没有imageKey) 或者 imageKey 失效了, 刷新一下 void refreshImageKey(ImageFavoritesEp imageFavoritesEp) async { if (isImageKeyLoading || hasRefreshImageKeyOnErr || @@ -40,6 +40,7 @@ class ImageFavoritesItemState extends State { isImageKeyLoading = true; ComicSource? comicSource = ComicSource.find(widget.imageFavoritesComic.sourceKey); + // 拿一下漫画信息和对应章节的图片 var resArr = await Future.wait([ comicSource!.loadComicPages!( widget.imageFavoritesComic.id, @@ -54,33 +55,62 @@ class ImageFavoritesItemState extends State { if (comicInfoRes.errorMessage?.contains("404") ?? false) { loadingImageFavoritesComicRes.isInvalid = true; widget.setRefreshComicList(loadingImageFavoritesComicRes); - } else if (!comicPagesRes.error && !comicInfoRes.error) { - List images = comicPagesRes.data; + if (mounted) { + setState(() {}); + } + return; + } + if (!comicInfoRes.error) { ImageFavoritesSomething something = ImageFavoritesComic.getSomethingFromComicDetails( comicInfoRes.data, imageFavoritesEp.ep); // 刷新一下值, 保存最新的 widget.imageFavoritesComic.author = something.author; - widget.imageFavoritesComic.maxPage = images.length; widget.imageFavoritesComic.subTitle = something.subTitle; widget.imageFavoritesComic.tags = something.tags; widget.imageFavoritesComic.translatedTags = something.translatedTags; - imageFavoritesEp.maxPage = images.length; imageFavoritesEp.epName = something.epName; - // 塞一个封面进去 - if (!imageFavoritesEp.isHasFirstPage) { - ImageFavoritePro copy = - ImageFavoritePro.copy(imageFavoritesEp.imageFavorites[0]); - copy.page = ImageFavoritesEp.firstPage; - copy.isAutoFavorite = true; - imageFavoritesEp.imageFavorites.insert(0, copy); + } else { + return; + } + if (comicPagesRes.error) { + // 能加载漫画信息, 说明只是章节对不太上, 刷新一下章节 + var chapters = comicInfoRes.data.chapters; + // 兜底一下, 如果章节对不上return, 说明是调用接口更新过章节的, 比如拷贝, jm, 避免丢失最初正确的eid + // 拷贝, jm可能会更新章节顺序, 以eid为准比较好 + if (imageFavoritesEp.eid != imageFavoritesEp.ep.toString()) { + return; } - // 统一刷一下最新的imageKey - for (var ele in imageFavoritesEp.imageFavorites) { - ele.imageKey = images[ele.page - 1]; + var finalEid = chapters?.keys.elementAt(imageFavoritesEp.ep - 1) ?? '0'; + var resArr = await Future.wait([ + comicSource!.loadComicPages!( + widget.imageFavoritesComic.id, + finalEid, + ) + ]); + comicPagesRes = resArr[0]; + if (comicPagesRes.error) { + return; + } else { + imageFavoritesEp.eid = finalEid; } - ImageFavoriteManager.addOrUpdateOrDelete(widget.imageFavoritesComic); } + List images = comicPagesRes.data; + widget.imageFavoritesComic.maxPage = images.length; + imageFavoritesEp.maxPage = images.length; + // 塞一个封面进去 + if (!imageFavoritesEp.isHasFirstPage) { + ImageFavoritePro copy = + ImageFavoritePro.copy(imageFavoritesEp.imageFavorites[0]); + copy.page = ImageFavoritesEp.firstPage; + copy.isAutoFavorite = true; + imageFavoritesEp.imageFavorites.insert(0, copy); + } + // 统一刷一下最新的imageKey + for (var ele in imageFavoritesEp.imageFavorites) { + ele.imageKey = images[ele.page - 1]; + } + ImageFavoriteManager.addOrUpdateOrDelete(widget.imageFavoritesComic); if (mounted) { setState(() {}); } @@ -212,25 +242,9 @@ class ImageFavoritesItemState extends State { .firstWhere((e) { return e.eid == curImageFavorite.eid; }); - ImageProvider image = - ImageFavoritesProvider(curImageFavorite); bool isSelected = widget.selectedImageFavorites[curImageFavorite] ?? false; - Widget imageWidget = AnimatedImage( - image: image, - width: 96, - height: 128, - fit: BoxFit.cover, - filterQuality: FilterQuality.medium, - onError: (Object error, StackTrace? stackTrace) { - if (loadingImageFavoritesComicRes.isLoaded) { - return; - } - refreshImageKey(curImageFavoritesEp); - hasRefreshImageKeyOnErr = true; - }, - ); int curPage = curImageFavorite.page; String pageText = curPage == ImageFavoritesEp.firstPage ? '@a Cover' @@ -287,7 +301,23 @@ class ImageFavoritesItemState extends State { .secondaryContainer, ), clipBehavior: Clip.antiAlias, - child: imageWidget), + child: AnimatedImage( + image: ImageFavoritesProvider( + curImageFavorite), + width: 96, + height: 128, + fit: BoxFit.cover, + filterQuality: FilterQuality.medium, + onError: (Object error, + StackTrace? stackTrace) { + if (loadingImageFavoritesComicRes + .isLoaded) { + return; + } + refreshImageKey(curImageFavoritesEp); + hasRefreshImageKeyOnErr = true; + }, + )), Text( pageText, style: ts.s10, diff --git a/lib/pages/image_favorites_page/image_favorites_page.dart b/lib/pages/image_favorites_page/image_favorites_page.dart index 1ebff21..a8916ef 100644 --- a/lib/pages/image_favorites_page/image_favorites_page.dart +++ b/lib/pages/image_favorites_page/image_favorites_page.dart @@ -347,7 +347,7 @@ class ImageFavoritesPageState extends State { _debouncer.run(() { keyword = _textEditingController.text; update(); - }, Duration(seconds: 1)); + }, Duration(milliseconds: 500)); }, ), ), diff --git a/lib/utils/data.dart b/lib/utils/data.dart index ca5687f..13c0d1e 100644 --- a/lib/utils/data.dart +++ b/lib/utils/data.dart @@ -198,17 +198,18 @@ Future importPicaData(File file) async { 2 => 'jm'.hashCode, 3 => 'hitomi'.hashCode, 4 => 'wnacg'.hashCode, - 6 => 'nhentai'.hashCode, + 5 => 'nhentai'.hashCode, _ => comic['type'] }, "id": comic['target'], - "maxPage": comic["max_page"], + "max_page": comic["max_page"], "ep": comic["ep"], "page": comic["page"], "time": comic["time"], "title": comic["title"], "subtitle": comic["subtitle"], "cover": comic["cover"], + "readEpisode": [comic["ep"]], }), ); } diff --git a/lib/utils/io.dart b/lib/utils/io.dart index 79020d4..dc6df55 100644 --- a/lib/utils/io.dart +++ b/lib/utils/io.dart @@ -376,7 +376,6 @@ class _IOOverrides extends IOOverrides { return super.createFile(path); } } - } T overrideIO(T Function() f) { diff --git "a/\344\273\273\345\212\241.md" "b/\344\273\273\345\212\241.md" deleted file mode 100644 index 8377575..0000000 --- "a/\344\273\273\345\212\241.md" +++ /dev/null @@ -1,64 +0,0 @@ -1. 建好 image_favorite 表 ok - 1. 导入图片收藏 ok -2. 做好页面 - 1. 阅读时, 下方的收藏 - 1. 收藏时, 收藏封面 ok - 2. 上划收藏, 左滑收藏 ok - 2. 单独的图片收藏页 - 1. 时间筛选, 按照近七天, 一个月, 三个月, 半年, 2024年, 2023年 ok - 2. 单本收藏数最多排序, 单本收藏数比上总页数最多排序, 并且将小于10页的权重降低 ok - 3. 图片收藏group - 1. 看下History 怎么缓存图片的 ok - 1. 他用的封面图, 我这边应该是更加类似预览才行, 得看看comic_page ok - 2. 好像也不行, 还是直接显示原图吧 - 1. 用存的url可以拉取图片,然后缓存在 cacheManager - 2. 有没有办法根据存的漫画源和ep还有page, 拉取图片呢 - 3. 获取images, 用 type.comicSource!.loadComicPages, 用 loadImage 获取图片数据 - 1. comicSource = ComicSource.find(widget.sourceKey); - 2. 显示图片, 支持图片的缓存, 支持用本地图片 - 1. 方案, 检查一下, group中是否所有的图片都有 imageKey ok - 2. 如果有, 就用imageKey 在 imageFavoritesProvider 中调用 ok - 3. 如果检测到本地有这图片, 就用本地的展示, 待学习 - 4. 如果imageKey获取图片失败, 或者存在没有imageKey的图片收藏, 就拿一下loadComicPages, 用最新的来查, 如果还是失败, 就放弃, 如果成功, 就将最新的imageKey更新进去 - 3. list 渐进式加载, silver 本身就支持 ok - 4. 显示封面, 显示页面page ok - 5. 响应筛选和排序 ok - 4. 支持选中删除 ok - 5. 双击大图浏览 ok - 1. 显示标题 ok - 3. 支持取消收藏, 退出大图浏览时更新数据库 ok - 4. 点击进行阅读, 点击进入详情 ok - 5. 点击进入上一本, 下一本 ok - 6. 显示 tags no - 6. 打通本地收藏的图片收藏 after - 7. 首页显示最喜欢作者, 最多收藏tag, 最喜欢的本子(按照收藏数以及按照收藏比) ok - 8. 筛选 - 1. tag 搜索 ok - 2. 收藏数量范围 ok - 9. 支持导出 - 1. 导出成文本, 包含标题, 链接, 总页数, 收藏数, 收藏占比, 阅读时间, tag 数等 no - 2. 生成总结页面, 包含最喜欢作者, 本子, 共收藏本子数, 共收藏图片数, 最喜欢tag, 最喜欢本子, 按总页数, 收藏占比 no - 10. bug解决 - 1. 进入的时候都是一张图, 都是cover - 2. 并行请求太多 timeout 风险较高 - 11. 最后完整看一下数据结构, imagePath 是否需要存在, 以及ep是string还是int ok - 1. imagePath 不需要 - 2. ep 和 page 都不从0开始 - 3. eid 存在 otherInfo 里 - 4. 是否做一个大的改动, 将数据库改成一本漫画的一个章节对应一条记录的形式 - 12. 中英互译 ok - 13. 实际大数据量测试 - 14. 实机测试 - 3. 主页的图片收藏显示 ok -3. 打通联动 -4. 自测 -5. 有些旧有的功能没有补齐 - 1. 点击收藏直接进行阅读, 让作者做 - 1. 好像没有跳转到页面的能力 - 2. 没有显示全部的页数 - 3. 没有滚动条 - 4. sync 网络收藏到本地的时候没有拉取页数的能力, 我来优化一下 - 1. sync 的时候也卡卡的, 一直拉不下来 - 2. lib\pages\favorites\favorite_actions.dart 应该手动拉一下最大的页数, 然后从拉取倒数几页来判断重复比较好 - 1. getMaxPageNum getPageSize - 2. 修改设置, 支持全部, 然后加上之前的一些设置, 并在同步的那个气泡提示大概一页有多少 pageNum, 本次会拉取多少页 \ No newline at end of file