From 244ef22f54551aa22dca6a3a82f77907c1cbc1f6 Mon Sep 17 00:00:00 2001 From: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com> Date: Tue, 9 Dec 2025 22:09:57 +0800 Subject: [PATCH] feat: load config from text (#1772) * feat: load config from text * opt: login utils * update Signed-off-by: bggRGjQaUbCoE --------- Co-authored-by: bggRGjQaUbCoE --- lib/http/fav.dart | 4 +- lib/http/init.dart | 20 +-- lib/models/user/stat.dart | 18 +-- lib/pages/about/view.dart | 72 +++++++++++ lib/pages/dynamics/controller.dart | 17 ++- lib/pages/dynamics/widgets/up_panel.dart | 3 +- lib/pages/dynamics_tab/controller.dart | 7 +- lib/pages/fav/pgc/controller.dart | 2 - lib/pages/live/controller.dart | 6 +- lib/pages/main/controller.dart | 21 +++- lib/pages/member_profile/view.dart | 5 +- lib/pages/mine/controller.dart | 24 ++-- lib/pages/pgc/controller.dart | 18 ++- lib/pages/search/view.dart | 14 +-- lib/pages/sponsor_block/view.dart | 33 +++-- lib/plugin/pl_player/view.dart | 7 +- lib/services/account_service.dart | 40 ++++-- lib/utils/accounts.dart | 4 +- lib/utils/login_utils.dart | 149 ++++++----------------- lib/utils/storage.dart | 8 +- 20 files changed, 264 insertions(+), 208 deletions(-) diff --git a/lib/http/fav.dart b/lib/http/fav.dart index 43004ec57..66ede9dec 100644 --- a/lib/http/fav.dart +++ b/lib/http/fav.dart @@ -367,15 +367,15 @@ class FavHttp { } static Future> favPgc({ - required dynamic mid, required int type, required int pn, int? followStatus, + Object? mid, }) async { var res = await Request().get( Api.favPgc, queryParameters: { - 'vmid': mid, + 'vmid': mid ?? Accounts.main.mid, 'type': type, 'follow_status': ?followStatus, 'pn': pn, diff --git a/lib/http/init.dart b/lib/http/init.dart index f700af408..536931d32 100644 --- a/lib/http/init.dart +++ b/lib/http/init.dart @@ -61,14 +61,20 @@ class Request { // final html = await Request().get(Api.dynamicSpmPrefix, // options: Options(extra: {'account': account})); // final String spmPrefix = _spmPrefixExp.firstMatch(html.data)!.group(1)!; - final String randPngEnd = base64.encode( - List.generate(32, (_) => Utils.random.nextInt(256)) + - List.filled(4, 0) + - [73, 69, 78, 68] + - List.generate(4, (_) => Utils.random.nextInt(256)), - ); + final String randPngEnd = base64.encode([ + ...Iterable.generate(32, (_) => Utils.random.nextInt(256)), + 0, + 0, + 0, + 0, + 73, + 69, + 78, + 68, + ...Iterable.generate(4, (_) => Utils.random.nextInt(256)), + ]); - String jsonData = json.encode({ + final jsonData = json.encode({ '3064': 1, '39c8': '333.1387.fp.risk', '3c43': { diff --git a/lib/models/user/stat.dart b/lib/models/user/stat.dart index 3b09acb11..e45fb9950 100644 --- a/lib/models/user/stat.dart +++ b/lib/models/user/stat.dart @@ -4,22 +4,22 @@ part 'stat.g.dart'; @HiveType(typeId: 1) class UserStat { - UserStat({ + const UserStat({ this.following, this.follower, this.dynamicCount, }); @HiveField(0) - int? following; + final int? following; @HiveField(1) - int? follower; + final int? follower; @HiveField(2) - int? dynamicCount; + final int? dynamicCount; - UserStat.fromJson(Map json) { - following = json['following']; - follower = json['follower']; - dynamicCount = json['dynamic_count']; - } + factory UserStat.fromJson(Map json) => UserStat( + following: json['following'], + follower: json['follower'], + dynamicCount: json['dynamic_count'], + ); } diff --git a/lib/pages/about/view.dart b/lib/pages/about/view.dart index 8d0c46752..ace77d84a 100644 --- a/lib/pages/about/view.dart +++ b/lib/pages/about/view.dart @@ -434,6 +434,78 @@ Future showImportExportDialog( ); }, ), + ListTile( + dense: true, + title: Text('输入$title', style: style), + onTap: () { + Get.back(); + final key = GlobalKey>(); + late T json; + String? forceErrorText; + + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('输入$title'), + constraints: const BoxConstraints( + minWidth: 420, + maxWidth: 420, + ), + content: TextFormField( + key: key, + minLines: 4, + maxLines: 12, + autofocus: true, + decoration: const InputDecoration( + border: OutlineInputBorder(), + errorMaxLines: 3, + ), + validator: (value) { + if (forceErrorText != null) return forceErrorText; + try { + json = jsonDecode(value!) as T; + return null; + } catch (e) { + if (e is FormatException) {} + return '解析json失败:$e'; + } + }, + ), + actions: [ + TextButton( + onPressed: Get.back, + child: Text( + '取消', + style: TextStyle( + color: Theme.of(context).colorScheme.outline, + ), + ), + ), + TextButton( + onPressed: () async { + if (key.currentState?.validate() == true) { + try { + if (await fromJson(json)) { + Get.back(); + SmartDialog.showToast('导入成功'); + return; + } + } catch (e) { + forceErrorText = '导入失败:$e'; + } + key.currentState?.validate(); + forceErrorText = null; + } + }, + child: const Text('确定'), + ), + ], + ); + }, + ); + }, + ), ], ); }, diff --git a/lib/pages/dynamics/controller.dart b/lib/pages/dynamics/controller.dart index 1710e842f..ad8d74443 100644 --- a/lib/pages/dynamics/controller.dart +++ b/lib/pages/dynamics/controller.dart @@ -9,6 +9,7 @@ import 'package:PiliPlus/models_new/follow/data.dart'; import 'package:PiliPlus/pages/common/common_controller.dart'; import 'package:PiliPlus/pages/dynamics_tab/controller.dart'; import 'package:PiliPlus/services/account_service.dart'; +import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:easy_debounce/easy_throttle.dart'; @@ -16,7 +17,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; class DynamicsController extends GetxController - with GetSingleTickerProviderStateMixin, ScrollOrRefreshMixin { + with GetSingleTickerProviderStateMixin, ScrollOrRefreshMixin, AccountMixin { @override final ScrollController scrollController = ScrollController(); late final TabController tabController = TabController( @@ -40,7 +41,8 @@ class DynamicsController extends GetxController final upPanelPosition = Pref.upPanelPosition; - AccountService accountService = Get.find(); + @override + final AccountService accountService = Get.find(); DynamicsTabController? get controller { try { @@ -95,7 +97,7 @@ class DynamicsController extends GetxController isQuerying = true; final res = await FollowHttp.followings( - vmid: accountService.mid, + vmid: Accounts.main.mid, pn: _upPage, orderType: 'attention', ps: 50, @@ -136,7 +138,7 @@ class DynamicsController extends GetxController DynamicsHttp.followUp(), if (_showAllUp) FollowHttp.followings( - vmid: accountService.mid, + vmid: Accounts.main.mid, pn: _upPage, orderType: 'attention', ps: 50, @@ -188,13 +190,13 @@ class DynamicsController extends GetxController } @override - Future onRefresh() async { + Future onRefresh() { if (_showAllUp) { _upPage = 1; _cacheUpList = null; } queryFollowUp(); - await controller?.onRefresh(); + return controller!.onRefresh(); } @override @@ -231,4 +233,7 @@ class DynamicsController extends GetxController scrollController.dispose(); super.onClose(); } + + @override + void onChangeAccount(bool isLogin) => onRefresh(); } diff --git a/lib/pages/dynamics/widgets/up_panel.dart b/lib/pages/dynamics/widgets/up_panel.dart index e79ee6e90..486480c30 100644 --- a/lib/pages/dynamics/widgets/up_panel.dart +++ b/lib/pages/dynamics/widgets/up_panel.dart @@ -5,6 +5,7 @@ import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/dynamics/up.dart'; import 'package:PiliPlus/pages/dynamics/controller.dart'; import 'package:PiliPlus/pages/live_follow/view.dart'; +import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/utils.dart'; @@ -112,7 +113,7 @@ class _UpPanelState extends State { UpItem( uname: '我', face: accountService.face.value, - mid: accountService.mid, + mid: Accounts.main.mid, ), ), ), diff --git a/lib/pages/dynamics_tab/controller.dart b/lib/pages/dynamics_tab/controller.dart index bc3bcf642..63b47ae2e 100644 --- a/lib/pages/dynamics_tab/controller.dart +++ b/lib/pages/dynamics_tab/controller.dart @@ -6,12 +6,14 @@ import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/dynamics/controller.dart'; import 'package:PiliPlus/pages/main/controller.dart'; +import 'package:PiliPlus/services/account_service.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class DynamicsTabController - extends CommonListController { + extends CommonListController + with AccountMixin { DynamicsTabController({required this.dynamicsType}); final DynamicsTabType dynamicsType; String offset = ''; @@ -87,4 +89,7 @@ class DynamicsTabController loadingState.refresh(); } catch (_) {} } + + @override + void onChangeAccount(bool isLogin) => onRefresh(); } diff --git a/lib/pages/fav/pgc/controller.dart b/lib/pages/fav/pgc/controller.dart index 49e69d8a6..59bf9f5d2 100644 --- a/lib/pages/fav/pgc/controller.dart +++ b/lib/pages/fav/pgc/controller.dart @@ -4,7 +4,6 @@ import 'package:PiliPlus/http/video.dart'; import 'package:PiliPlus/models_new/fav/fav_pgc/data.dart'; import 'package:PiliPlus/models_new/fav/fav_pgc/list.dart'; import 'package:PiliPlus/pages/common/multi_select/multi_select_controller.dart'; -import 'package:PiliPlus/utils/accounts.dart'; import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -39,7 +38,6 @@ class FavPgcController @override Future> customGetData() => FavHttp.favPgc( - mid: Accounts.main.mid, type: type, followStatus: followStatus, pn: page, diff --git a/lib/pages/live/controller.dart b/lib/pages/live/controller.dart index 79c343fcb..f04de2731 100644 --- a/lib/pages/live/controller.dart +++ b/lib/pages/live/controller.dart @@ -7,9 +7,10 @@ import 'package:PiliPlus/models_new/live/live_feed_index/data.dart'; import 'package:PiliPlus/models_new/live/live_second_list/data.dart'; import 'package:PiliPlus/models_new/live/live_second_list/tag.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart'; +import 'package:PiliPlus/services/account_service.dart'; import 'package:get/get.dart'; -class LiveController extends CommonListController { +class LiveController extends CommonListController with AccountMixin { @override void onInit() { super.onInit(); @@ -140,4 +141,7 @@ class LiveController extends CommonListController { isEnd = false; queryData(); } + + @override + void onChangeAccount(bool isLogin) => onRefresh(); } diff --git a/lib/pages/main/controller.dart b/lib/pages/main/controller.dart index fc47655ef..0e5873b47 100644 --- a/lib/pages/main/controller.dart +++ b/lib/pages/main/controller.dart @@ -19,22 +19,24 @@ import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/update.dart'; +import 'package:collection/collection.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; class MainController extends GetxController - with GetSingleTickerProviderStateMixin { - AccountService accountService = Get.find(); + with GetSingleTickerProviderStateMixin, AccountMixin { + @override + final AccountService accountService = Get.find(); List navigationBars = []; StreamController? bottomBarStream; late bool hideTabBar = Pref.hideTabBar; late dynamic controller; - RxInt selectedIndex = 0.obs; + final RxInt selectedIndex = 0.obs; - RxInt dynCount = 0.obs; + final RxInt dynCount = 0.obs; late DynamicBadgeMode dynamicBadgeMode; late bool checkDynamic = Pref.checkDynamic; late int dynamicPeriod = Pref.dynamicPeriod * 60 * 1000; @@ -165,7 +167,7 @@ class MainController extends GetxController var res = await Future.wait([_msgUnread(), _msgFeedUnread()]); - int count = res.fold(0, (prev, e) => prev + e); + final count = res.sum; final countStr = count == 0 ? '' @@ -332,4 +334,13 @@ class MainController extends GetxController controller.dispose(); super.onClose(); } + + @override + void onChangeAccount(bool isLogin) { + if (isLogin) { + getUnreadDynamic(); + } else { + setDynCount(); + } + } } diff --git a/lib/pages/member_profile/view.dart b/lib/pages/member_profile/view.dart index 27756e57e..bb3b6bc4a 100644 --- a/lib/pages/member_profile/view.dart +++ b/lib/pages/member_profile/view.dart @@ -89,9 +89,7 @@ class _EditProfilePageState extends State { res.data['data'], ); _loadingState = Success(data); - accountService - ..name.value = data.name! - ..face.value = data.face!; + accountService.face.value = data.face!; try { UserInfoData userInfo = Pref.userInfoCache! ..uname = data.name @@ -388,7 +386,6 @@ class _EditProfilePageState extends State { data ..name = _textController.text ..coins = data.coins! - 6; - accountService.name.value = _textController.text; try { UserInfoData userInfo = Pref.userInfoCache! ..uname = _textController.text; diff --git a/lib/pages/mine/controller.dart b/lib/pages/mine/controller.dart index 00f51b227..9c388c0a4 100644 --- a/lib/pages/mine/controller.dart +++ b/lib/pages/mine/controller.dart @@ -19,16 +19,17 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; -class MineController - extends CommonDataController { +class MineController extends CommonDataController + with AccountMixin { + @override AccountService accountService = Get.find(); int? favFolderCount; // 用户信息 头像、昵称、lv - Rx userInfo = UserInfoData().obs; + final Rx userInfo = UserInfoData().obs; // 用户状态 动态、关注、粉丝 - Rx userStat = UserStat().obs; + final Rx userStat = const UserStat().obs; Rx themeType = Pref.themeType.obs; @@ -107,8 +108,6 @@ class MineController GStorage.userInfo.put('userInfoCache', data); } accountService - ..mid = data.mid! - ..name.value = data.uname! ..face.value = data.face! ..isLogin.value = true; } else { @@ -145,7 +144,7 @@ class MineController return FavHttp.userfavFolder( pn: 1, ps: 20, - mid: accountService.mid, + mid: Accounts.main.mid, ); } @@ -293,4 +292,15 @@ class MineController queryUserInfo(); return super.onRefresh(); } + + @override + void onChangeAccount(bool isLogin) { + if (isLogin) { + onRefresh(); + } else { + userInfo.value = UserInfoData(); + userStat.value = const UserStat(); + loadingState.value = LoadingState.loading(); + } + } } diff --git a/lib/pages/pgc/controller.dart b/lib/pages/pgc/controller.dart index 2607804f9..943d9ec62 100644 --- a/lib/pages/pgc/controller.dart +++ b/lib/pages/pgc/controller.dart @@ -14,14 +14,16 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; class PgcController - extends CommonListController?, PgcIndexItem> { + extends CommonListController?, PgcIndexItem> + with AccountMixin { PgcController({required this.tabType}); final HomeTabType tabType; late final showPgcTimeline = tabType == HomeTabType.bangumi && Pref.showPgcTimeline; - AccountService accountService = Get.find(); + @override + final accountService = Get.find(); @override void onInit() { @@ -92,7 +94,6 @@ class PgcController } followLoading = true; var res = await FavHttp.favPgc( - mid: accountService.mid, type: tabType == HomeTabType.bangumi ? 1 : 2, pn: followPage, ); @@ -142,4 +143,15 @@ class PgcController followController?.dispose(); super.onClose(); } + + @override + void onChangeAccount(bool isLogin) { + if (isLogin) { + followPage = 1; + followEnd = false; + queryPgcFollow(); + } else { + followState.value = LoadingState.loading(); + } + } } diff --git a/lib/pages/search/view.dart b/lib/pages/search/view.dart index aa41346eb..2c009c6dc 100644 --- a/lib/pages/search/view.dart +++ b/lib/pages/search/view.dart @@ -14,7 +14,6 @@ import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart' hide ContextExtensionss; class SearchPage extends StatefulWidget { @@ -397,15 +396,10 @@ class _SearchPageState extends State { title: '历史记录', toJson: () => jsonEncode(_searchController.historyList), fromJson: (json) { - try { - final list = List.from(json); - _searchController.historyList.value = list; - GStorage.historyWord.put('cacheList', list); - return true; - } catch (e) { - SmartDialog.showToast(e.toString()); - return false; - } + final list = List.from(json); + _searchController.historyList.value = list; + GStorage.historyWord.put('cacheList', list); + return true; }, ), ), diff --git a/lib/pages/sponsor_block/view.dart b/lib/pages/sponsor_block/view.dart index f5711cfe5..4a62cf8f8 100644 --- a/lib/pages/sponsor_block/view.dart +++ b/lib/pages/sponsor_block/view.dart @@ -151,30 +151,29 @@ class _SponsorBlockPageState extends State { title: Text('用户ID', style: titleStyle), subtitle: Text(_userId, style: subTitleStyle), onTap: () { - final key = GlobalKey(); + final key = GlobalKey>(); _textController.text = _userId; showDialog( context: context, builder: (_) { return AlertDialog( title: Text('用户ID', style: titleStyle), - content: Form( + content: TextFormField( key: key, - child: TextFormField( - minLines: 1, - maxLines: 4, - autofocus: true, - controller: _textController, - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z\d]+')), - ], - validator: (value) { - if ((value?.length ?? -1) < 30) { - return '用户ID要求至少为30个字符长度的纯字符串'; - } - return null; - }, - ), + minLines: 1, + maxLines: 4, + autofocus: true, + controller: _textController, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z\d]+')), + ], + decoration: const InputDecoration(errorMaxLines: 2), + validator: (value) { + if ((value?.length ?? -1) < 30) { + return '用户ID要求至少为30个字符长度的纯字符串'; + } + return null; + }, ), actions: [ TextButton( diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 8dc368059..7f8376e1c 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -57,6 +57,7 @@ import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:canvas_danmaku/canvas_danmaku.dart'; +import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:fl_chart/fl_chart.dart'; @@ -2132,9 +2133,7 @@ class _PLVideoPlayerState extends State Future screenshotWebp() async { final videoInfo = videoDetailController.data; final ids = videoInfo.dash!.video!.map((i) => i.id!).toSet(); - final video = videoDetailController.findVideoByQa( - ids.reduce((p, n) => p < n ? p : n), - ); + final video = videoDetailController.findVideoByQa(ids.min); VideoQuality qa = video.quality; String? url = video.baseUrl; @@ -2513,7 +2512,7 @@ Widget buildDmChart( minX: 0, maxX: (dmTrend.length - 1).toDouble(), minY: 0, - maxY: dmTrend.reduce((a, b) => a > b ? a : b).toDouble(), + maxY: dmTrend.max, lineBarsData: [ LineChartBarData( spots: List.generate( diff --git a/lib/services/account_service.dart b/lib/services/account_service.dart index 4d766bc13..59972132e 100644 --- a/lib/services/account_service.dart +++ b/lib/services/account_service.dart @@ -1,20 +1,44 @@ +import 'dart:async'; + import 'package:PiliPlus/models/user/info.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:get/get.dart'; class AccountService extends GetxService { - late int mid; - late final RxString name; - late final RxString face; - late final RxBool isLogin; + final RxString face = ''.obs; + final RxBool isLogin = false.obs; @override void onInit() { super.onInit(); UserInfoData? userInfo = Pref.userInfoCache; - mid = userInfo?.mid ?? 0; - name = (userInfo?.uname ?? '').obs; - face = (userInfo?.face ?? '').obs; - isLogin = (userInfo != null).obs; + if (userInfo != null) { + face.value = userInfo.face ?? ''; + isLogin.value = true; + } else { + face.value = ''; + isLogin.value = false; + } + } +} + +mixin AccountMixin on GetLifeCycleBase { + StreamSubscription? _listener; + + AccountService get accountService => Get.find(); + + void onChangeAccount(bool isLogin); + + @override + void onInit() { + super.onInit(); + _listener = accountService.isLogin.listen(onChangeAccount); + } + + @override + void onClose() { + _listener?.cancel(); + _listener = null; + super.onClose(); } } diff --git a/lib/utils/accounts.dart b/lib/utils/accounts.dart index e865ffaaa..6179e948b 100644 --- a/lib/utils/accounts.dart +++ b/lib/utils/accounts.dart @@ -106,9 +106,9 @@ abstract class Accounts { } static Future set(AccountType key, Account account) async { - await (accountMode[key.index]..type.remove(key)).onChange(); + final oldAccount = accountMode[key.index]..type.remove(key); accountMode[key.index] = account..type.add(key); - await account.onChange(); + await Future.wait([account.onChange(), oldAccount.onChange()]); if (!account.activated) await Request.buvidActive(account); switch (key) { case AccountType.main: diff --git a/lib/utils/login_utils.dart b/lib/utils/login_utils.dart index 041a4bb55..f4104bebe 100644 --- a/lib/utils/login_utils.dart +++ b/lib/utils/login_utils.dart @@ -2,19 +2,9 @@ import 'dart:async' show FutureOr; import 'dart:io' show Platform; import 'package:PiliPlus/grpc/grpc_req.dart'; -import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/user.dart'; import 'package:PiliPlus/main.dart'; -import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart'; -import 'package:PiliPlus/models/common/home_tab_type.dart'; import 'package:PiliPlus/models/user/info.dart'; -import 'package:PiliPlus/models/user/stat.dart'; -import 'package:PiliPlus/pages/dynamics/controller.dart'; -import 'package:PiliPlus/pages/dynamics_tab/controller.dart'; -import 'package:PiliPlus/pages/live/controller.dart'; -import 'package:PiliPlus/pages/main/controller.dart'; -import 'package:PiliPlus/pages/mine/controller.dart'; -import 'package:PiliPlus/pages/pgc/controller.dart'; import 'package:PiliPlus/services/account_service.dart'; import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/accounts/account.dart'; @@ -22,11 +12,13 @@ import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/utils.dart'; +import 'package:collection/collection.dart'; +import 'package:crypto/crypto.dart' show Digest; import 'package:flutter_inappwebview/flutter_inappwebview.dart' as web; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -abstract class LoginUtils { +abstract final class LoginUtils { static FutureOr setWebCookie([Account? account]) { if (Platform.isLinux) { return null; @@ -62,48 +54,19 @@ abstract class LoginUtils { if (result.isSuccess) { final UserInfoData data = result.data; if (data.isLogin == true) { - Get.find() - ..mid = data.mid! - ..name.value = data.uname! - ..face.value = data.face! - ..isLogin.value = true; + final accountService = Get.find() + ..face.value = data.face!; + + if (accountService.isLogin.value) { + accountService.isLogin.refresh(); + } else { + accountService.isLogin.value = true; + } SmartDialog.showToast('main登录成功'); if (data != Pref.userInfoCache) { await GStorage.userInfo.put('userInfoCache', data); } - - try { - Get.find().onRefresh(); - } catch (_) {} - - try { - Get.find().onRefresh(); - } catch (_) {} - - for (var item in DynamicsTabType.values) { - try { - Get.find(tag: item.name).onRefresh(); - } catch (_) {} - } - - try { - Get.find().onRefresh(); - } catch (_) {} - - try { - Get.find(tag: HomeTabType.bangumi.name) - ..followPage = 1 - ..followEnd = false - ..queryPgcFollow(); - } catch (_) {} - - try { - Get.find(tag: HomeTabType.cinema.name) - ..followPage = 1 - ..followEnd = false - ..queryPgcFollow(); - } catch (_) {} } } else { // 获取用户信息失败 @@ -115,65 +78,26 @@ abstract class LoginUtils { } } - static Future onLogoutMain() async { + static Future onLogoutMain() { Get.find() - ..mid = 0 - ..name.value = '' ..face.value = '' ..isLogin.value = false; GrpcReq.updateHeaders(null); - await Future.wait([ + return Future.wait([ if (!Platform.isLinux) web.CookieManager.instance( webViewEnvironment: webViewEnvironment, ).deleteAllCookies(), GStorage.userInfo.delete('userInfoCache'), ]); - - try { - Get.find().setDynCount(); - } catch (_) {} - - try { - Get.find() - ..userInfo.value = UserInfoData() - ..userStat.value = UserStat() - ..loadingState.value = LoadingState.loading(); - // MineController.anonymity.value = false; - } catch (_) {} - - try { - Get.find().onRefresh(); - } catch (_) {} - - try { - Get.find().onRefresh(); - } catch (_) {} - - for (var item in DynamicsTabType.values) { - try { - Get.find(tag: item.name).onRefresh(); - } catch (_) {} - } - - try { - Get.find(tag: HomeTabType.bangumi.name).followState.value = - LoadingState.loading(); - } catch (_) {} - - try { - Get.find(tag: HomeTabType.cinema.name).followState.value = - LoadingState.loading(); - } catch (_) {} } static String generateBuvid() { - var md5Str = Iterable.generate( - 32, - (_) => Utils.random.nextInt(16).toRadixString(16), - ).join().toUpperCase(); + var md5Str = Digest( + List.generate(16, (_) => Utils.random.nextInt(256)), + ).toString(); return 'XY${md5Str[2]}${md5Str[12]}${md5Str[22]}$md5Str'; } @@ -190,31 +114,26 @@ abstract class LoginUtils { static String genDeviceId() { // https://github.com/bilive/bilive_client/blob/2873de0532c54832f5464a4c57325ad9af8b8698/bilive/lib/app_client.ts#L62 - final String yyyyMMddHHmmss = DateTime.now() - .toIso8601String() - .replaceAll(RegExp(r'[-:TZ]'), '') - .substring(0, 14); + final time = DateTime.now(); - final String randomHex32 = List.generate( - 32, - (index) => Utils.random.nextInt(16).toRadixString(16), - ).join(); - final String randomHex16 = List.generate( - 16, - (index) => Utils.random.nextInt(16).toRadixString(16), - ).join(); + final List bytes = [ + ...Iterable.generate(16, (_) => Utils.random.nextInt(256)), + _dec2bcd(time.year ~/ 100), + _dec2bcd(time.year % 100), + _dec2bcd(time.month), + _dec2bcd(time.day), + _dec2bcd(time.hour), + _dec2bcd(time.minute), + _dec2bcd(time.second), + ...Iterable.generate(8, (_) => Utils.random.nextInt(256)), + ]; + final check = (bytes.sum & 0xFF).toRadixString(16).padLeft(2, '0'); - final String deviceID = randomHex32 + yyyyMMddHHmmss + randomHex16; + return Digest(bytes).toString() + check; + } - final List bytes = RegExp(r'\w{2}') - .allMatches(deviceID) - .map((match) => int.parse(match.group(0)!, radix: 16)) - .toList(); - final int checksumValue = bytes.reduce((a, b) => a + b); - final String check = checksumValue - .toRadixString(16) - .substring(checksumValue.toRadixString(16).length - 2); - - return deviceID + check; + static int _dec2bcd(int dec) { + assert(0 <= dec && dec < 100); + return ((dec ~/ 10) << 4) | (dec % 10); } } diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index dd839d57f..8986adb85 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -72,10 +72,10 @@ abstract class GStorage { importAllJsonSettings(jsonDecode(data)); static Future importAllJsonSettings(Map map) async { - await setting.clear(); - await video.clear(); - await setting.putAll(map[setting.name]); - await video.putAll(map[video.name]); + await Future.wait([ + setting.clear().then((_) => setting.putAll(map[setting.name])), + video.clear().then((_) => video.putAll(map[video.name])), + ]); return true; }