diff --git a/changelog/v7.4.8+147.md b/changelog/v7.4.8+147.md index d5aeb9a5..8fbe145f 100644 --- a/changelog/v7.4.8+147.md +++ b/changelog/v7.4.8+147.md @@ -1,6 +1,7 @@ - 移动端支持自定义阅读页亮度 - 现在所有平台和布局模式下均可以自定义鼠标滚轮滚动速度 - 阅读页在从上至下布局模式下,现在可以支持自定义图片区域宽度 +- 下载设置中支持自定义默认下载分组 - 优化保存图片时的图片命名规则 - 优化解压归档时的icon显示 - 收藏页和关注页搜索不再继承关键字 @@ -17,6 +18,7 @@ - Support customizing the brightness of the reading page on the mobile terminal - Now you can customize the mouse wheel scrolling speed in all platforms and layout modes - In the top to bottom layout mode, the reading page can now support customizing the width of the image area +- The download settings support customizing the default download group - Optimize the toast message when canceling favorites - Optimize the image naming rules when saving images - Optimize the icon display when decompressing archives diff --git a/lib/src/l18n/en_US.dart b/lib/src/l18n/en_US.dart index 09ac3f84..6f77e5d2 100644 --- a/lib/src/l18n/en_US.dart +++ b/lib/src/l18n/en_US.dart @@ -588,6 +588,8 @@ class en_US { 'downloadOriginalImageByDefault': 'Choose Original Image By Default', 'originalImage': 'Original', 'resampleImage': 'Resample', + 'defaultGalleryGroup': 'Default Gallery Group', + 'defaultArchiveGroup': 'Default Archive Group', 'never': 'Never', 'manual': 'Manual', 'always': 'Always', diff --git a/lib/src/l18n/ko_KR.dart b/lib/src/l18n/ko_KR.dart index 5ed086e8..5ce58b7e 100644 --- a/lib/src/l18n/ko_KR.dart +++ b/lib/src/l18n/ko_KR.dart @@ -587,6 +587,8 @@ class ko_KR { 'downloadOriginalImageByDefault': '기본값으로 원본 이미지 선택', 'originalImage': '원본', 'resampleImage': '압축', + 'defaultGalleryGroup':'Default Gallery Group', + 'defaultArchiveGroup':'Default Archive Group', 'never': '영원히 안 함', 'manual': '수동', 'always': '항상 함', diff --git a/lib/src/l18n/pt_BR.dart b/lib/src/l18n/pt_BR.dart index b4a30c60..4b5690e4 100644 --- a/lib/src/l18n/pt_BR.dart +++ b/lib/src/l18n/pt_BR.dart @@ -590,6 +590,8 @@ class pt_BR { 'downloadOriginalImageByDefault': 'Escolher imagem original por padrão', 'originalImage': 'Original', 'resampleImage': 'Redimensionada', + 'defaultGalleryGroup':'Default Gallery Group', + 'defaultArchiveGroup':'Default Archive Group', 'never': 'Nunca', 'manual': 'Manual', 'always': 'Sempre', diff --git a/lib/src/l18n/zh_CN.dart b/lib/src/l18n/zh_CN.dart index bea45901..2711cb1c 100644 --- a/lib/src/l18n/zh_CN.dart +++ b/lib/src/l18n/zh_CN.dart @@ -588,6 +588,8 @@ class zh_CN { 'downloadOriginalImageByDefault': '默认选中下载原图', 'originalImage': '原图', 'resampleImage': '压缩', + 'defaultGalleryGroup':'默认分组(下载)', + 'defaultArchiveGroup':'默认分组(归档)', 'never': '从不', 'manual': '手动', 'always': '总是', diff --git a/lib/src/l18n/zh_TW.dart b/lib/src/l18n/zh_TW.dart index 7e4316c9..55dd45e5 100644 --- a/lib/src/l18n/zh_TW.dart +++ b/lib/src/l18n/zh_TW.dart @@ -587,6 +587,8 @@ class zh_TW { 'downloadOriginalImageByDefault': '默認選中下載原圖', 'originalImage': '原圖', 'resampleImage': '壓縮', + 'defaultGalleryGroup':'默認分組(下載)', + 'defaultArchiveGroup':'默認分組(歸檔)', 'never': '從不', 'manual': '手動', 'always': '總是', diff --git a/lib/src/pages/details/details_page_logic.dart b/lib/src/pages/details/details_page_logic.dart index 10ea2e36..96ac542d 100644 --- a/lib/src/pages/details/details_page_logic.dart +++ b/lib/src/pages/details/details_page_logic.dart @@ -19,6 +19,7 @@ import 'package:jhentai/src/network/eh_request.dart'; import 'package:jhentai/src/pages/download/download_base_page.dart'; import 'package:jhentai/src/service/local_gallery_service.dart'; import 'package:jhentai/src/service/super_resolution_service.dart'; +import 'package:jhentai/src/setting/download_setting.dart'; import 'package:jhentai/src/setting/my_tags_setting.dart'; import 'package:jhentai/src/utils/string_uril.dart'; import 'package:jhentai/src/widget/eh_add_tag_dialog.dart'; @@ -246,11 +247,13 @@ class DetailsPageLogic extends GetxController with LoginRequiredMixin, Scroll2To /// new download if (galleryDownloadedData == null || downloadProgress == null) { - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'chooseGroup'.tr, + currentGroup: DownloadSetting.defaultGalleryGroup.value, candidates: downloadService.allGroups, - showDownloadOriginalImageCheckBox: true, + showDownloadOriginalImageCheckBox: UserSetting.hasLoggedIn(), + downloadOriginalImage: DownloadSetting.downloadOriginalImageByDefault.value, ), ); @@ -259,8 +262,8 @@ class DetailsPageLogic extends GetxController with LoginRequiredMixin, Scroll2To } downloadService.downloadGallery(gallery.toGalleryDownloadedData( - downloadOriginalImage: result['downloadOriginalImage'] ?? false, - group: result['group'] ?? 'default'.tr, + downloadOriginalImage: result.downloadOriginalImage, + group: result.group, )); toast('${'beginToDownload'.tr}: ${gallery.gid}', isCenter: false); @@ -440,20 +443,23 @@ class DetailsPageLogic extends GetxController with LoginRequiredMixin, Scroll2To /// new download if (archiveStatus == null) { - Map? result = await Get.dialog(EHArchiveDialog( - archivePageUrl: state.galleryDetails!.archivePageUrl, - candidates: archiveDownloadService.allGroups, - currentGroup: 'default'.tr, - )); + ({bool isOriginal, int size, String group})? result = await Get.dialog( + EHArchiveDialog( + title: 'chhoseArchive'.tr, + archivePageUrl: state.galleryDetails!.archivePageUrl, + currentGroup: DownloadSetting.defaultArchiveGroup.value, + candidates: archiveDownloadService.allGroups, + ), + ); if (result == null) { return; } ArchiveDownloadedData archive = state.gallery!.toArchiveDownloadedData( archivePageUrl: state.galleryDetails!.archivePageUrl, - isOriginal: result['isOriginal'], - size: result['size'], - group: result['group'] ?? 'default'.tr, + isOriginal: result.isOriginal, + size: result.size, + group: result.group, ); archiveDownloadService.downloadArchive(archive); diff --git a/lib/src/pages/download/mixin/archive/archive_download_page_logic_mixin.dart b/lib/src/pages/download/mixin/archive/archive_download_page_logic_mixin.dart index 36ccdc91..0f96bcf5 100644 --- a/lib/src/pages/download/mixin/archive/archive_download_page_logic_mixin.dart +++ b/lib/src/pages/download/mixin/archive/archive_download_page_logic_mixin.dart @@ -37,7 +37,7 @@ mixin ArchiveDownloadPageLogicMixin on GetxController implements Scroll2TopLogic Future handleChangeArchiveGroup(ArchiveDownloadedData archive) async { String oldGroup = archiveDownloadService.archiveDownloadInfos[archive.gid]!.group; - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'changeGroup'.tr, currentGroup: oldGroup, @@ -49,7 +49,7 @@ mixin ArchiveDownloadPageLogicMixin on GetxController implements Scroll2TopLogic return; } - String newGroup = result['group'] ?? 'default'.tr; + String newGroup = result.group; if (newGroup == oldGroup) { return; } @@ -84,7 +84,7 @@ mixin ArchiveDownloadPageLogicMixin on GetxController implements Scroll2TopLogic } Future handleRenameGroup(String oldGroup) async { - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'renameGroup'.tr, currentGroup: oldGroup, @@ -96,7 +96,7 @@ mixin ArchiveDownloadPageLogicMixin on GetxController implements Scroll2TopLogic return; } - String newGroup = result['group'] ?? 'default'.tr; + String newGroup = result.group; if (newGroup == oldGroup) { return; } @@ -243,7 +243,7 @@ mixin ArchiveDownloadPageLogicMixin on GetxController implements Scroll2TopLogic } Future handleMultiChangeGroup() async { - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'changeGroup'.tr, candidates: archiveDownloadService.allGroups, @@ -254,7 +254,7 @@ mixin ArchiveDownloadPageLogicMixin on GetxController implements Scroll2TopLogic return; } - String newGroup = result['group'] ?? 'default'.tr; + String newGroup = result.group; for (int gid in multiSelectDownloadPageState.selectedGids) { await archiveDownloadService.updateArchiveGroupByGid(gid, newGroup); diff --git a/lib/src/pages/download/mixin/gallery/gallery_download_page_logic_mixin.dart b/lib/src/pages/download/mixin/gallery/gallery_download_page_logic_mixin.dart index a396e3e3..26221d3f 100644 --- a/lib/src/pages/download/mixin/gallery/gallery_download_page_logic_mixin.dart +++ b/lib/src/pages/download/mixin/gallery/gallery_download_page_logic_mixin.dart @@ -28,7 +28,7 @@ mixin GalleryDownloadPageLogicMixin on GetxController implements Scroll2TopLogic Future handleChangeGroup(GalleryDownloadedData gallery) async { String oldGroup = downloadService.galleryDownloadInfos[gallery.gid]!.group; - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'changeGroup'.tr, currentGroup: oldGroup, @@ -40,7 +40,7 @@ mixin GalleryDownloadPageLogicMixin on GetxController implements Scroll2TopLogic return; } - String newGroup = result['group'] ?? 'default'.tr; + String newGroup = result.group; if (newGroup == oldGroup) { return; } @@ -58,7 +58,7 @@ mixin GalleryDownloadPageLogicMixin on GetxController implements Scroll2TopLogic } Future handleRenameGroup(String oldGroup) async { - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'renameGroup'.tr, currentGroup: oldGroup, @@ -70,7 +70,7 @@ mixin GalleryDownloadPageLogicMixin on GetxController implements Scroll2TopLogic return; } - String newGroup = result['group'] ?? 'default'.tr; + String newGroup = result.group; if (newGroup == oldGroup) { return; } @@ -316,7 +316,7 @@ mixin GalleryDownloadPageLogicMixin on GetxController implements Scroll2TopLogic } Future handleMultiChangeGroup() async { - Map? result = await Get.dialog( + ({String group, bool downloadOriginalImage})? result = await Get.dialog( EHDownloadDialog( title: 'changeGroup'.tr, candidates: downloadService.allGroups, @@ -327,7 +327,7 @@ mixin GalleryDownloadPageLogicMixin on GetxController implements Scroll2TopLogic return; } - String newGroup = result['group'] ?? 'default'.tr; + String newGroup = result.group; for (int gid in multiSelectDownloadPageState.selectedGids) { await downloadService.updateGroupByGid(gid, newGroup); diff --git a/lib/src/pages/read/layout/vertical_list/vertical_list_layout.dart b/lib/src/pages/read/layout/vertical_list/vertical_list_layout.dart index e007ce0a..c5ccaef2 100644 --- a/lib/src/pages/read/layout/vertical_list/vertical_list_layout.dart +++ b/lib/src/pages/read/layout/vertical_list/vertical_list_layout.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:jhentai/src/config/ui_config.dart'; import 'package:jhentai/src/model/read_page_info.dart'; import 'package:jhentai/src/pages/read/layout/vertical_list/vertical_list_layout_state.dart'; import 'package:photo_view/photo_view_gallery.dart'; diff --git a/lib/src/pages/setting/download/setting_download_page.dart b/lib/src/pages/setting/download/setting_download_page.dart index 606967f0..2f4ee792 100644 --- a/lib/src/pages/setting/download/setting_download_page.dart +++ b/lib/src/pages/setting/download/setting_download_page.dart @@ -21,6 +21,7 @@ import '../../../service/gallery_download_service.dart'; import '../../../utils/log.dart'; import '../../../utils/permission_util.dart'; import '../../../utils/route_util.dart'; +import '../../../widget/eh_download_dialog.dart'; class SettingDownloadPage extends StatefulWidget { const SettingDownloadPage({Key? key}) : super(key: key); @@ -63,6 +64,8 @@ class _SettingDownloadPageState extends State { _buildExtraGalleryScanPath(), if (GetPlatform.isDesktop) _buildSingleImageSavePath(), _buildDownloadOriginalImage(), + _buildDefaultGalleryGroup(context), + _buildDefaultArchiveGroup(context), _buildDownloadConcurrency(), _buildSpeedLimit(context), _buildDownloadAllGallerysOfSamePriority(), @@ -119,7 +122,7 @@ class _SettingDownloadPageState extends State { return ListTile( title: Text('downloadOriginalImageByDefault'.tr), trailing: Switch( - value: DownloadSetting.downloadOriginalImageByDefault.value ?? false, + value: DownloadSetting.downloadOriginalImageByDefault.value, onChanged: (value) { if (!UserSetting.hasLoggedIn()) { toast('needLoginToOperate'.tr); @@ -131,6 +134,48 @@ class _SettingDownloadPageState extends State { ); } + Widget _buildDefaultGalleryGroup(BuildContext context) { + return ListTile( + title: Text('defaultGalleryGroup'.tr), + trailing: Text(DownloadSetting.defaultGalleryGroup.value ?? 'default'.tr, style: UIConfig.settingPageListTileTrailingTextStyle(context)), + onTap: () async { + ({String group, bool downloadOriginalImage})? result = await showDialog( + context: context, + builder: (_) => EHDownloadDialog( + title: 'chooseGroup'.tr, + currentGroup: DownloadSetting.defaultGalleryGroup.value, + candidates: galleryDownloadService.allGroups, + ), + ); + + if (result != null) { + DownloadSetting.saveDefaultGalleryGroup(result.group); + } + }, + ).marginOnly(right: 12); + } + + Widget _buildDefaultArchiveGroup(BuildContext context) { + return ListTile( + title: Text('defaultArchiveGroup'.tr), + trailing: Text(DownloadSetting.defaultArchiveGroup.value ?? 'default'.tr, style: UIConfig.settingPageListTileTrailingTextStyle(context)), + onTap: () async { + ({String group, bool downloadOriginalImage})? result = await showDialog( + context: context, + builder: (_) => EHDownloadDialog( + title: 'chooseGroup'.tr, + currentGroup: DownloadSetting.defaultArchiveGroup.value, + candidates: archiveDownloadService.allGroups, + ), + ); + + if (result != null) { + DownloadSetting.saveDefaultArchiveGroup(result.group); + } + }, + ).marginOnly(right: 12); + } + Widget _buildDownloadConcurrency() { return ListTile( title: Text('downloadTaskConcurrency'.tr), diff --git a/lib/src/setting/download_setting.dart b/lib/src/setting/download_setting.dart index 0e1ab2f7..11f3ba34 100644 --- a/lib/src/setting/download_setting.dart +++ b/lib/src/setting/download_setting.dart @@ -10,7 +10,9 @@ import '../service/storage_service.dart'; class DownloadSetting { static String defaultDownloadPath = join(PathSetting.getVisibleDir().path, 'download'); static RxString downloadPath = defaultDownloadPath.obs; - static RxnBool downloadOriginalImageByDefault = RxnBool(UserSetting.hasLoggedIn() ? false : null); + static RxBool downloadOriginalImageByDefault = false.obs; + static RxnString defaultGalleryGroup = RxnString(); + static RxnString defaultArchiveGroup = RxnString(); static String defaultExtraGalleryScanPath = join(PathSetting.getVisibleDir().path, 'local_gallery'); static RxList extraGalleryScanPath = [defaultExtraGalleryScanPath].obs; static RxString singleImageSavePath = join(PathSetting.getVisibleDir().path, 'save').obs; @@ -28,15 +30,6 @@ class DownloadSetting { } else { Log.debug('init DownloadSetting success: default', false); } - - /// listen to login and logout - ever(UserSetting.ipbMemberId, (v) { - if (UserSetting.hasLoggedIn()) { - saveDownloadOriginalImageByDefault(false); - } else { - saveDownloadOriginalImageByDefault(null); - } - }); } static saveDownloadPath(String downloadPath) { @@ -63,12 +56,24 @@ class DownloadSetting { _save(); } - static saveDownloadOriginalImageByDefault(bool? value) { + static saveDownloadOriginalImageByDefault(bool value) { Log.debug('saveDownloadOriginalImageByDefault:$value'); DownloadSetting.downloadOriginalImageByDefault.value = value; _save(); } + static saveDefaultGalleryGroup(String? group) { + Log.debug('saveDefaultGalleryGroup:$group'); + DownloadSetting.defaultGalleryGroup.value = group; + _save(); + } + + static saveDefaultArchiveGroup(String? group) { + Log.debug('saveDefaultArchiveGroup:$group'); + DownloadSetting.defaultArchiveGroup.value = group; + _save(); + } + static saveDownloadTaskConcurrency(int downloadTaskConcurrency) { Log.debug('saveDownloadTaskConcurrency:$downloadTaskConcurrency'); DownloadSetting.downloadTaskConcurrency.value = downloadTaskConcurrency; @@ -115,6 +120,8 @@ class DownloadSetting { 'extraGalleryScanPath': extraGalleryScanPath.value, 'singleImageSavePath': singleImageSavePath.value, 'downloadOriginalImageByDefault': downloadOriginalImageByDefault.value, + 'defaultGalleryGroup': defaultGalleryGroup.value, + 'defaultArchiveGroup': defaultArchiveGroup.value, 'downloadTaskConcurrency': downloadTaskConcurrency.value, 'maximum': maximum.value, 'period': period.value.inMilliseconds, @@ -133,6 +140,8 @@ class DownloadSetting { } singleImageSavePath.value = map['singleImageSavePath'] ?? singleImageSavePath.value; downloadOriginalImageByDefault.value = map['downloadOriginalImageByDefault'] ?? downloadOriginalImageByDefault.value; + defaultGalleryGroup.value = map['defaultGalleryGroup']; + defaultArchiveGroup.value = map['defaultArchiveGroup']; downloadTaskConcurrency.value = map['downloadTaskConcurrency']; maximum.value = map['maximum']; period.value = Duration(milliseconds: map['period']); diff --git a/lib/src/widget/eh_archive_dialog.dart b/lib/src/widget/eh_archive_dialog.dart index 91070f01..80685c90 100644 --- a/lib/src/widget/eh_archive_dialog.dart +++ b/lib/src/widget/eh_archive_dialog.dart @@ -17,12 +17,14 @@ import '../utils/route_util.dart'; import '../utils/snack_util.dart'; class EHArchiveDialog extends StatefulWidget { + final String title; final String? currentGroup; final List candidates; final String archivePageUrl; const EHArchiveDialog({ Key? key, + required this.title, this.currentGroup, required this.candidates, required this.archivePageUrl, @@ -34,15 +36,18 @@ class EHArchiveDialog extends StatefulWidget { class _EHArchiveDialogState extends State { late String group; + late List candidates; late GalleryArchive archive; LoadingState loadingState = LoadingState.idle; @override void initState() { super.initState(); - group = widget.currentGroup ?? 'default'.tr; - widget.candidates.remove(group); - widget.candidates.insert(0, group); + + group = widget.currentGroup ?? widget.candidates.firstOrNull ?? 'default'.tr; + candidates = List.of(widget.candidates); + candidates.remove(group); + candidates.insert(0, group); _getArchiveInfo(); } @@ -55,7 +60,7 @@ class _EHArchiveDialogState extends State { child: LoadingStateIndicator( loadingState: loadingState, errorTapCallback: _getArchiveInfo, - successWidgetBuilder: () => _buildBody(), + successWidgetBuilder: _buildBody, ), ), ); @@ -65,7 +70,7 @@ class _EHArchiveDialogState extends State { return Column( mainAxisSize: MainAxisSize.min, children: [ - EHGroupNameSelector(candidates: widget.candidates, currentGroup: 'default'.tr, listener: (g) => group = g), + EHGroupNameSelector(candidates: candidates, currentGroup: group, listener: (g) => group = g), if (archive.creditCount != null && archive.gpCount != null) EHAsset(gpCount: archive.gpCount!, creditCount: archive.creditCount!).marginOnly(top: 20), Expanded(child: _buildButtons().marginOnly(top: 12)), ], @@ -82,7 +87,7 @@ class _EHArchiveDialogState extends State { text: 'resample'.tr, callback: _canAffordDownload(isOriginal: false) ? () => backRoute( - result: {'isOriginal': false, 'size': _computeSizeInBytes(isOriginal: false), 'group': group}, + result: (isOriginal: false, size: _computeSizeInBytes(isOriginal: false), group: group), ) : null, ), @@ -92,7 +97,7 @@ class _EHArchiveDialogState extends State { text: 'original'.tr, callback: _canAffordDownload(isOriginal: true) ? () => backRoute( - result: {'isOriginal': true, 'size': _computeSizeInBytes(isOriginal: true), 'group': group}, + result: (isOriginal: true, size: _computeSizeInBytes(isOriginal: true), group: group), ) : null, ), diff --git a/lib/src/widget/eh_download_dialog.dart b/lib/src/widget/eh_download_dialog.dart index f759f9f2..c875fd33 100644 --- a/lib/src/widget/eh_download_dialog.dart +++ b/lib/src/widget/eh_download_dialog.dart @@ -12,6 +12,7 @@ class EHDownloadDialog extends StatefulWidget { final String? currentGroup; final List candidates; final bool showDownloadOriginalImageCheckBox; + final bool downloadOriginalImage; const EHDownloadDialog({ Key? key, @@ -19,6 +20,7 @@ class EHDownloadDialog extends StatefulWidget { this.currentGroup, required this.candidates, this.showDownloadOriginalImageCheckBox = false, + this.downloadOriginalImage = false, }) : super(key: key); @override @@ -28,16 +30,17 @@ class EHDownloadDialog extends StatefulWidget { class _EHDownloadDialogState extends State { late String group; late List candidates; - bool? downloadOriginalImage = DownloadSetting.downloadOriginalImageByDefault.value; + late bool downloadOriginalImage; @override void initState() { - group = widget.currentGroup ?? 'default'.tr; - candidates = List.of(widget.candidates); + super.initState(); + group = widget.currentGroup ?? widget.candidates.firstOrNull ?? 'default'.tr; + candidates = List.of(widget.candidates); candidates.remove(group); candidates.insert(0, group); - super.initState(); + downloadOriginalImage = widget.downloadOriginalImage; } @override @@ -56,7 +59,9 @@ class _EHDownloadDialogState extends State { backRoute(); return; } - backRoute(result: {'group': group, 'downloadOriginalImage': downloadOriginalImage}); + backRoute( + result: (group: group, downloadOriginalImage: downloadOriginalImage), + ); }, child: Text('OK'.tr), ), @@ -75,7 +80,7 @@ class _EHDownloadDialogState extends State { candidates: candidates, listener: (g) => group = g, ), - if (widget.showDownloadOriginalImageCheckBox && downloadOriginalImage != null) _buildDownloadOriginalImageCheckBox().marginOnly(top: 16), + if (widget.showDownloadOriginalImageCheckBox) _buildDownloadOriginalImageCheckBox().marginOnly(top: 16), ], ), );