diff --git a/changelog/v7.4.8+147.md b/changelog/v7.4.8+147.md index 13cf52bb..965dc5d2 100644 --- a/changelog/v7.4.8+147.md +++ b/changelog/v7.4.8+147.md @@ -6,6 +6,7 @@ - 去除自动重定向至表站的是设置,现在会强制优先访问表站画廊链接 - 去除下载超时设置,现在下载图片不会超时中断 - 支持自定义详情页缩略图列数 +- 不再支持自动创建Profile,改为自行选择要在应用内使用的Profile ------------------------------------------------------------------------------------------ @@ -16,4 +17,5 @@ - The search in favorites and following page no longer inherits keywords - Remove the setting of automatically redirecting to the EH site, now it is enabled by default - Remove the download timeout setting, now the download will not be interrupted due to timeout -- Support customizing the number of thumbnail columns in the details page \ No newline at end of file +- Support customizing the number of thumbnail columns in the details page +- No longer support automatically creating Profile, change to select the profile to be used in the application by yourself \ No newline at end of file diff --git a/lib/src/l18n/en_US.dart b/lib/src/l18n/en_US.dart index 9e3585cb..90ccb417 100644 --- a/lib/src/l18n/en_US.dart +++ b/lib/src/l18n/en_US.dart @@ -223,10 +223,11 @@ class en_US { /// eh setting page 'site': 'Site', 'redirect2Eh': 'Redirect to EH if available', + 'profileSetting': 'Profile Setting', + 'chooseProfileHint': 'Choose profile used in JHenTai', 'siteSetting': 'Site Setting', + 'siteSettingHint': 'Edit site setting in e-hentai', 'showCookie': 'Cookie', - 'useSeparateProfile': 'Use Separated Profile', - 'editProfileHint': 'Edit profile', 'redirect2EH': 'Redirect to EH site if Available', 'redirect2Hints': 'Will try to parse EH site first', 'pleaseLogInToOperate': 'Please Log In To Operate', @@ -249,6 +250,9 @@ class en_US { 'deleteTagSetFailed': 'Delete Tag Set Failed', 'addLocalTagHint': 'Search to add new tag', + /// Profile Setting page + 'selectedProfile': 'Selected Profile', + /// add host mapping dialog 'addHostMapping': 'Add Host Mapping', diff --git a/lib/src/l18n/ko_KR.dart b/lib/src/l18n/ko_KR.dart index f3bafc74..13257c73 100644 --- a/lib/src/l18n/ko_KR.dart +++ b/lib/src/l18n/ko_KR.dart @@ -223,10 +223,11 @@ class ko_KR { /// eh setting page 'site': '사이트', 'redirect2Eh': '사용 가능하면 EH로 재요청', + 'profileSetting': 'Profile Setting', + 'chooseProfileHint': 'Choose profile used in JHenTai', 'siteSetting': '사이트 내부 설정', + 'siteSettingHint': 'Edit site setting in e-hentai', 'showCookie': '쿠키 정보', - 'useSeparateProfile': '분리된 프로필 사용', - 'editProfileHint': '프로필 수정', 'redirect2EH': '사용 가능하면 EH 사이트로 재요청', 'redirect2Hints': 'EH 사이트 분석을 먼저 합니다.', 'pleaseLogInToOperate': '실행하려면 로그인하세요', @@ -249,6 +250,9 @@ class ko_KR { 'deleteTagSetFailed': '태그 목록 삭제 실패', 'addLocalTagHint': 'Search to add new tag', + /// Profile Setting page + 'selectedProfile': 'Selected Profile', + /// add host mapping dialog 'addHostMapping': 'Add Host Mapping', diff --git a/lib/src/l18n/pt_BR.dart b/lib/src/l18n/pt_BR.dart index a89d754b..0ffe296b 100644 --- a/lib/src/l18n/pt_BR.dart +++ b/lib/src/l18n/pt_BR.dart @@ -225,10 +225,11 @@ class pt_BR { /// eh setting page 'site': 'Site', 'redirect2Eh': 'Redirecionar para EH, se disponível', + 'profileSetting': 'Profile Setting', + 'chooseProfileHint': 'Choose profile used in JHenTai', 'siteSetting': 'Configuração do site', + 'siteSettingHint': 'Edit site setting in e-hentai', 'showCookie': 'Cookie', - 'useSeparateProfile': 'Usar perfil separado', - 'editProfileHint': 'Editar perfil', 'redirect2EH': 'Redirecionar para o site EH, se disponível', 'redirect2Hints': 'Tentar analisar o site EH primeiro', 'pleaseLogInToOperate': 'Faça login para operar', @@ -251,6 +252,9 @@ class pt_BR { 'deleteTagSetFailed': 'Falha ao excluir conjunto de tags', 'addLocalTagHint': 'Search to add new tag', + /// Profile Setting page + 'selectedProfile': 'Selected Profile', + /// add host mapping dialog 'addHostMapping': 'Add Host Mapping', diff --git a/lib/src/l18n/zh_CN.dart b/lib/src/l18n/zh_CN.dart index e5a79bf7..38df19b4 100644 --- a/lib/src/l18n/zh_CN.dart +++ b/lib/src/l18n/zh_CN.dart @@ -117,8 +117,8 @@ class zh_CN { 'failToGetThumbnails': "获取画廊缩略图数据失败", 'favoriteGallerySuccess': "收藏画廊成功", 'favoriteGalleryFailed': "收藏画廊失败", - 'removeFavoriteSuccess': "取消收藏成功", - 'removeFavoriteFailed': "取消收藏失败", + 'removeFavoriteSuccess': "取消收藏成功", + 'removeFavoriteFailed': "取消收藏失败", 'ratingSuccess': '评分成功', 'ratingFailed': '评分失败', 'voteTagFailed': '投票标签失败', @@ -222,10 +222,11 @@ class zh_CN { /// eh setting page 'site': '站点', 'redirect2Eh': '优先重定向至表站', + 'profileSetting': 'Profile设置', + 'chooseProfileHint': '选择在JHenTai中使用的Profile', 'siteSetting': '站点设置', + 'siteSettingHint': '更改E站个人设置', 'showCookie': '查看 Cookie', - 'useSeparateProfile': '使用单独的 Profile', - 'editProfileHint': '选择并编辑 Profile', 'redirect2EH': '画廊链接重定向至表站(如果可用)', 'redirect2Hints': '会先尝试解析表站', 'pleaseLogInToOperate': '请登陆后操作', @@ -248,6 +249,9 @@ class zh_CN { 'deleteTagSetFailed': '删除标签数据失败', 'addLocalTagHint': '搜索添加新标签', + /// Profile Setting page + 'selectedProfile': '当前使用的Profile', + /// add host mapping dialog 'addHostMapping': '添加自定义Host', diff --git a/lib/src/l18n/zh_TW.dart b/lib/src/l18n/zh_TW.dart index 903e06c7..d55f433f 100644 --- a/lib/src/l18n/zh_TW.dart +++ b/lib/src/l18n/zh_TW.dart @@ -117,8 +117,8 @@ class zh_TW { 'failToGetThumbnails': "獲取畫廊快取圖數據失敗", 'favoriteGallerySuccess': "收藏畫廊成功", 'favoriteGalleryFailed': "收藏畫廊失敗", - 'removeFavoriteSuccess': "取消收藏成功", - 'removeFavoriteFailed': "取消收藏失敗", + 'removeFavoriteSuccess': "取消收藏成功", + 'removeFavoriteFailed': "取消收藏失敗", 'ratingSuccess': '評分成功', 'ratingFailed': '評分失敗', 'voteTagFailed': '投票標籤失敗', @@ -222,10 +222,11 @@ class zh_TW { /// eh setting page 'site': '站點', 'redirect2Eh': '優先重定向至表站', + 'profileSetting': 'Profile設定', + 'chooseProfileHint': '选择在JHenTai中使用的Profile', 'siteSetting': '站點設定', + 'siteSettingHint': '更改E站個人設定', 'showCookie': '查看 Cookie', - 'useSeparateProfile': '使用單獨的 Profile', - 'editProfileHint': '選擇並編輯 Profile', 'redirect2EH': '畫廊鏈接重新導向至表站(如果可用)', 'redirect2Hints': '會先嘗試解析表站', 'pleaseLogInToOperate': '請登入後操作', @@ -248,6 +249,9 @@ class zh_TW { 'deleteTagSetFailed': '刪除標籤數據失敗', 'addLocalTagHint': '搜索添加新标签', + /// Profile Setting page + 'selectedProfile': '當前使用的Profile', + /// add host mapping dialog 'addHostMapping': '添加自定義Host', diff --git a/lib/src/model/profile.dart b/lib/src/model/profile.dart new file mode 100644 index 00000000..b1f4c48c --- /dev/null +++ b/lib/src/model/profile.dart @@ -0,0 +1,9 @@ +class Profile { + int number; + + String name; + + bool selected; + + Profile({required this.number, required this.name, required this.selected}); +} diff --git a/lib/src/pages/setting/eh/profile/setting_eh_profile_page.dart b/lib/src/pages/setting/eh/profile/setting_eh_profile_page.dart new file mode 100644 index 00000000..20e16372 --- /dev/null +++ b/lib/src/pages/setting/eh/profile/setting_eh_profile_page.dart @@ -0,0 +1,111 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:jhentai/src/extension/widget_extension.dart'; +import 'package:jhentai/src/widget/loading_state_indicator.dart'; +import 'package:retry/retry.dart'; + +import '../../../../exception/eh_exception.dart'; +import '../../../../model/profile.dart'; +import '../../../../network/eh_cookie_manager.dart'; +import '../../../../network/eh_request.dart'; +import '../../../../setting/site_setting.dart'; +import '../../../../utils/eh_spider_parser.dart'; +import '../../../../utils/log.dart'; + +class SettingEHProfilePage extends StatefulWidget { + const SettingEHProfilePage({super.key}); + + @override + State createState() => _SettingEHProfilePageState(); +} + +class _SettingEHProfilePageState extends State { + LoadingState loadingState = LoadingState.idle; + late List profiles; + + @override + void initState() { + super.initState(); + _loadProfile(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(centerTitle: true, title: Text('profileSetting'.tr)), + body: _buildProfile(), + ); + } + + Widget _buildProfile() { + if (loadingState != LoadingState.success) { + return LoadingStateIndicator(loadingState: loadingState, errorTapCallback: _loadProfile); + } + + int number = profiles.firstWhere((p) => p.selected).number; + return SafeArea( + child: ListView( + padding: const EdgeInsets.only(top: 16), + children: [ + ListTile( + title: Text('selectedProfile'.tr), + trailing: DropdownButton( + value: number, + elevation: 4, + alignment: AlignmentDirectional.centerEnd, + onChanged: (int? newValue) { + Get.find().storeEhCookiesForAllUri([Cookie('sp', newValue?.toString() ?? '1')]); + setState(() { + for (Profile value in profiles) { + value.selected = value.number == newValue; + } + }); + }, + items: profiles + .map( + (p) => DropdownMenuItem(child: Text(p.name), value: p.number), + ) + .toList(), + ), + ) + ], + ).withListTileTheme(context), + ); + } + + Future _loadProfile() async { + if (loadingState == LoadingState.loading) { + return; + } + + loadingState = LoadingState.loading; + ({List profiles, FrontPageDisplayType frontPageDisplayType, bool isLargeThumbnail, int thumbnailRows}) settings; + try { + settings = await retry( + () => EHRequest.requestSettingPage(EHSpiderParser.settingPage2SiteSetting), + retryIf: (e) => e is DioError, + maxAttempts: 3, + ); + } on DioError catch (e) { + Log.error('Load profile fail', e.message); + setState(() { + loadingState = LoadingState.error; + }); + return; + } on EHException catch (e) { + Log.error('Load profile fail', e.message); + setState(() { + loadingState = LoadingState.error; + }); + return; + } + + setState(() { + profiles = settings.profiles; + loadingState = LoadingState.success; + }); + } +} diff --git a/lib/src/pages/setting/eh/setting_eh_page.dart b/lib/src/pages/setting/eh/setting_eh_page.dart index ad16b52c..4bacf24e 100644 --- a/lib/src/pages/setting/eh/setting_eh_page.dart +++ b/lib/src/pages/setting/eh/setting_eh_page.dart @@ -55,7 +55,7 @@ class _SettingEHPageState extends State { padding: const EdgeInsets.only(top: 16), children: [ _buildSiteSegmentControl(), - _buildUseSeparateProfile(), + _buildProfile(), _buildSiteSetting(), _buildImageLimit(), _buildAssets(), @@ -80,17 +80,19 @@ class _SettingEHPageState extends State { ); } - Widget _buildUseSeparateProfile() { + Widget _buildProfile() { return ListTile( - title: Text('useSeparateProfile'.tr), - trailing: Switch(value: SiteSetting.useSeparateProfile.value, onChanged: SiteSetting.saveUseSeparateProfile), + title: Text('profileSetting'.tr), + subtitle: Text('chooseProfileHint'.tr), + trailing: const Icon(Icons.keyboard_arrow_right), + onTap: () => toRoute(Routes.profile), ); } Widget _buildSiteSetting() { return ListTile( title: Text('siteSetting'.tr), - subtitle: Text('editProfileHint'.tr), + subtitle: Text('siteSettingHint'.tr), trailing: const Icon(Icons.keyboard_arrow_right), onTap: () async { if (GetPlatform.isDesktop) { diff --git a/lib/src/routes/routes.dart b/lib/src/routes/routes.dart index 89ddc775..4c41c33d 100644 --- a/lib/src/routes/routes.dart +++ b/lib/src/routes/routes.dart @@ -17,6 +17,7 @@ import 'package:jhentai/src/pages/setting/account/login/login_page.dart'; import 'package:jhentai/src/pages/setting/advanced/setting_advanced_page.dart'; import 'package:jhentai/src/pages/setting/download/extra_gallery_scan_path/extra_gallery_scan_path_page.dart'; import 'package:jhentai/src/pages/setting/download/setting_download_page.dart'; +import 'package:jhentai/src/pages/setting/eh/profile/setting_eh_profile_page.dart'; import 'package:jhentai/src/pages/setting/eh/setting_eh_page.dart'; import 'package:jhentai/src/pages/setting/eh/tagsets/tag_sets_page.dart'; import 'package:jhentai/src/pages/setting/mousewheel/setting_mouse_wheel_page.dart'; @@ -98,6 +99,7 @@ class Routes { static const String themeColor = "/setting_style/themeColor"; static const String pageListStyle = "/setting_style/pageListStyle"; + static const String profile = "/setting_EH/profile"; static const String tagSets = "/setting_EH/tagSets"; static const String addLocalTag = "/setting_EH/addLocalTag"; @@ -308,6 +310,12 @@ class Routes { transition: defaultTransition, offAllBefore: false, ), + EHPage( + name: profile, + page: () => SettingEHProfilePage(), + transition: defaultTransition, + offAllBefore: false, + ), EHPage( name: tagSets, page: () => TagSetsPage(), diff --git a/lib/src/setting/site_setting.dart b/lib/src/setting/site_setting.dart index a185e785..91c96b54 100644 --- a/lib/src/setting/site_setting.dart +++ b/lib/src/setting/site_setting.dart @@ -1,14 +1,12 @@ -import 'dart:io'; - import 'package:dio/dio.dart'; import 'package:get/get.dart'; -import 'package:jhentai/src/network/eh_cookie_manager.dart'; import 'package:jhentai/src/network/eh_request.dart'; import 'package:jhentai/src/setting/user_setting.dart'; import 'package:jhentai/src/utils/eh_spider_parser.dart'; import 'package:retry/retry.dart'; import '../exception/eh_exception.dart'; +import '../model/profile.dart'; import '../service/storage_service.dart'; import '../utils/log.dart'; @@ -16,7 +14,6 @@ class SiteSetting { /// unused now static Rx frontPageDisplayType = FrontPageDisplayType.compact.obs; - static RxBool useSeparateProfile = false.obs; static RxBool isLargeThumbnail = false.obs; static RxInt thumbnailRows = 4.obs; static RxInt thumbnailsCountPerPage = 40.obs; @@ -47,10 +44,10 @@ class SiteSetting { Log.info('refresh SiteSetting'); - Map settings = {}; + ({List profiles, FrontPageDisplayType frontPageDisplayType, bool isLargeThumbnail, int thumbnailRows}) settings; try { - await retry( - () async => settings = await EHRequest.requestSettingPage(EHSpiderParser.settingPage2SiteSetting), + settings = await retry( + () => EHRequest.requestSettingPage(EHSpiderParser.settingPage2SiteSetting), retryIf: (e) => e is DioError, maxAttempts: 3, ); @@ -62,39 +59,13 @@ class SiteSetting { return; } - frontPageDisplayType.value = settings['frontPageDisplayType']; - isLargeThumbnail.value = settings['isLargeThumbnail']; - thumbnailRows.value = settings['thumbnailRows']; + frontPageDisplayType.value = settings.frontPageDisplayType; + isLargeThumbnail.value = settings.isLargeThumbnail; + thumbnailRows.value = settings.thumbnailRows; thumbnailsCountPerPage.value = thumbnailRows.value * (isLargeThumbnail.value ? 5 : 10); Log.info('refresh SiteSetting success'); _save(); - - if (useSeparateProfile.isFalse) { - Get.find().storeEhCookiesForAllUri([Cookie('sp', '1')]); - return; - } - - String? jHenTaiProfileNo = settings['jHenTaiProfileNo']; - if (jHenTaiProfileNo != null) { - Log.debug('Find JHenTai profile: $jHenTaiProfileNo'); - Get.find().storeEhCookiesForAllUri([Cookie('sp', jHenTaiProfileNo)]); - } else { - Log.debug('Create JHenTai profile'); - retry(EHRequest.createProfile, retryIf: (e) => e is DioError, maxAttempts: 3); - } - } - - static saveUseSeparateProfile(bool value) { - Log.debug('saveUseSeparateProfile:$value'); - useSeparateProfile.value = value; - _save(); - - if (useSeparateProfile.isTrue) { - refresh(); - } else { - Get.find().storeEhCookiesForAllUri([Cookie('sp', '1')]); - } } static Future _save() async { @@ -102,7 +73,6 @@ class SiteSetting { } static Future _clear() async { - useSeparateProfile.value = false; frontPageDisplayType.value = FrontPageDisplayType.compact; isLargeThumbnail.value = false; thumbnailRows.value = 4; @@ -113,7 +83,6 @@ class SiteSetting { static Map _toMap() { return { - 'useSeparateProfile': useSeparateProfile.value, 'frontPageDisplayType': frontPageDisplayType.value.index, 'isLargeThumbnail': isLargeThumbnail.value, 'thumbnailRows': thumbnailRows.value, @@ -122,7 +91,6 @@ class SiteSetting { } static _initFromMap(Map map) { - useSeparateProfile.value = map['useSeparateProfile'] ?? useSeparateProfile.value; frontPageDisplayType.value = FrontPageDisplayType.values[map['frontPageDisplayType']]; isLargeThumbnail.value = map['isLargeThumbnail']; thumbnailRows.value = map['thumbnailRows']; diff --git a/lib/src/utils/eh_spider_parser.dart b/lib/src/utils/eh_spider_parser.dart index c46fdda6..1cb7cac0 100644 --- a/lib/src/utils/eh_spider_parser.dart +++ b/lib/src/utils/eh_spider_parser.dart @@ -21,6 +21,7 @@ import 'package:jhentai/src/model/gallery_stats.dart'; import 'package:jhentai/src/model/gallery_tag.dart'; import 'package:jhentai/src/model/gallery_thumbnail.dart'; import 'package:jhentai/src/model/gallery_torrent.dart'; +import 'package:jhentai/src/model/profile.dart'; import 'package:jhentai/src/model/tag_set.dart'; import 'package:jhentai/src/setting/site_setting.dart'; import 'package:jhentai/src/utils/color_util.dart'; @@ -525,38 +526,53 @@ class EHSpiderParser { ).toList(); } - static Map settingPage2SiteSetting(Headers headers, dynamic data) { + static ({List profiles, FrontPageDisplayType frontPageDisplayType, bool isLargeThumbnail, int thumbnailRows}) settingPage2SiteSetting( + Headers headers, dynamic data) { Document document = parse(data as String); List items = document.querySelectorAll('.optouter'); - Map map = {}; - List profiles = document.querySelectorAll('#profile_form > select > option'); - map['jHenTaiProfileNo'] = profiles.singleWhereOrNull((profile) => profile.text == 'JHenTai')?.attributes['value']; + List profileElements = document.querySelectorAll('#profile_form > select > option'); + List profiles = profileElements + .map((e) => Profile( + number: int.parse(e.attributes['value']!), + name: e.text, + selected: e.attributes['selected'] != null, + )) + .toList(); Element frontPageSetting = items[8]; String type = frontPageSetting.querySelector('div > p > label > input[checked=checked]')!.parent!.text; + FrontPageDisplayType frontPageDisplayType; switch (type) { case ' Minimal': - map['frontPageDisplayType'] = FrontPageDisplayType.minimal; + frontPageDisplayType = FrontPageDisplayType.minimal; break; case ' Minimal+': - map['frontPageDisplayType'] = FrontPageDisplayType.minimalPlus; + frontPageDisplayType = FrontPageDisplayType.minimalPlus; break; case ' Compact': - map['frontPageDisplayType'] = FrontPageDisplayType.compact; + frontPageDisplayType = FrontPageDisplayType.compact; break; case ' Extended': - map['frontPageDisplayType'] = FrontPageDisplayType.extended; + frontPageDisplayType = FrontPageDisplayType.extended; break; case ' Thumbnail': - map['frontPageDisplayType'] = FrontPageDisplayType.thumbnail; + frontPageDisplayType = FrontPageDisplayType.thumbnail; break; + default: + frontPageDisplayType = FrontPageDisplayType.minimal; } - map['isLargeThumbnail'] = document.querySelector('#tssel > div > label > input[checked=checked]')?.parent?.text == ' Large' ? true : false; - map['thumbnailRows'] = int.parse(document.querySelector('#trsel > div > label > input[checked=checked]')?.parent?.text ?? '4'); - return map; + bool isLargeThumbnail = document.querySelector('#tssel > div > label > input[checked=checked]')?.parent?.text == ' Large' ? true : false; + int thumbnailRows = int.parse(document.querySelector('#trsel > div > label > input[checked=checked]')?.parent?.text ?? '4'); + + return ( + profiles: profiles, + frontPageDisplayType: frontPageDisplayType, + isLargeThumbnail: isLargeThumbnail, + thumbnailRows: thumbnailRows, + ); } static Map homePage2ImageLimit(Headers headers, dynamic data) {