From 9a3766e7b7b7616b146c57c0786827baa164a975 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sat, 8 Feb 2025 21:09:59 +0800 Subject: [PATCH] opt: webview to video Closes #209 Signed-off-by: bggRGjQaUbCoE --- lib/pages/search_panel/controller.dart | 6 +-- lib/pages/search_panel/view.dart | 4 +- .../search_panel/widgets/article_panel.dart | 4 +- .../search_panel/widgets/user_panel.dart | 4 +- .../search_panel/widgets/video_panel.dart | 8 +-- lib/pages/search_result/controller.dart | 10 +--- lib/pages/search_result/view.dart | 4 +- lib/pages/webview/webview_page.dart | 49 ++++++++++--------- lib/utils/app_scheme.dart | 14 ++---- lib/utils/id_utils.dart | 23 +++------ 10 files changed, 54 insertions(+), 72 deletions(-) diff --git a/lib/pages/search_panel/controller.dart b/lib/pages/search_panel/controller.dart index ddcd261e..d2a4015a 100644 --- a/lib/pages/search_panel/controller.dart +++ b/lib/pages/search_panel/controller.dart @@ -9,11 +9,11 @@ import 'package:PiliPlus/utils/utils.dart'; class SearchPanelController extends CommonController { SearchPanelController({ - this.keyword, + required this.keyword, required this.searchType, required this.tag, }); - String? keyword; + String keyword; SearchType searchType; // 结果排序方式 搜索类型为视频、专栏及相簿时 RxString order = ''.obs; @@ -99,7 +99,7 @@ class SearchPanelController extends CommonController { @override Future customGetData() => SearchHttp.searchByType( searchType: searchType, - keyword: keyword!, + keyword: keyword, page: currentPage, order: order.value, duration: searchType.name != 'video' ? null : duration.value, diff --git a/lib/pages/search_panel/view.dart b/lib/pages/search_panel/view.dart index 03153662..d1c83f8d 100644 --- a/lib/pages/search_panel/view.dart +++ b/lib/pages/search_panel/view.dart @@ -16,7 +16,7 @@ import 'widgets/media_bangumi_panel.dart'; import 'widgets/user_panel.dart'; class SearchPanel extends StatefulWidget { - final String? keyword; + final String keyword; final SearchType searchType; final String tag; const SearchPanel({ @@ -46,7 +46,7 @@ class _SearchPanelState extends State searchType: widget.searchType, tag: widget.tag, ), - tag: widget.searchType.name + widget.keyword!, + tag: widget.searchType.name + widget.keyword, ); } diff --git a/lib/pages/search_panel/widgets/article_panel.dart b/lib/pages/search_panel/widgets/article_panel.dart index 704c01d5..4870caad 100644 --- a/lib/pages/search_panel/widgets/article_panel.dart +++ b/lib/pages/search_panel/widgets/article_panel.dart @@ -287,7 +287,7 @@ class ArticlePanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'article${searchPanelCtr.keyword!}'); + tag: 'article${searchPanelCtr.keyword}'); ctr.order.value = item['order']; SmartDialog.showLoading(msg: 'loading'); await ctr.onRefresh(); @@ -321,7 +321,7 @@ class ArticlePanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'article${searchPanelCtr.keyword!}'); + tag: 'article${searchPanelCtr.keyword}'); ctr.categoryId = item['categoryId']; SmartDialog.showLoading(msg: 'loading'); await ctr.onRefresh(); diff --git a/lib/pages/search_panel/widgets/user_panel.dart b/lib/pages/search_panel/widgets/user_panel.dart index a0f608d3..3dbe8147 100644 --- a/lib/pages/search_panel/widgets/user_panel.dart +++ b/lib/pages/search_panel/widgets/user_panel.dart @@ -214,7 +214,7 @@ class UserPanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'bili_user${searchPanelCtr.keyword!}'); + tag: 'bili_user${searchPanelCtr.keyword}'); ctr.orderSort = item['orderSort']; ctr.order.value = item['order']; SmartDialog.showLoading(msg: 'loading'); @@ -249,7 +249,7 @@ class UserPanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'bili_user${searchPanelCtr.keyword!}'); + tag: 'bili_user${searchPanelCtr.keyword}'); ctr.userType = item['userType']; SmartDialog.showLoading(msg: 'loading'); await ctr.onRefresh(); diff --git a/lib/pages/search_panel/widgets/video_panel.dart b/lib/pages/search_panel/widgets/video_panel.dart index f1c878e9..46b09084 100644 --- a/lib/pages/search_panel/widgets/video_panel.dart +++ b/lib/pages/search_panel/widgets/video_panel.dart @@ -277,7 +277,7 @@ class VideoPanelController extends GetxController { SmartDialog.dismiss(); // SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'video${searchPanelCtr.keyword!}'); + tag: 'video${searchPanelCtr.keyword}'); ctr.pubBegin = DateTime( pubBegin.year, pubBegin.month, @@ -345,7 +345,7 @@ class VideoPanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'video${searchPanelCtr.keyword!}'); + tag: 'video${searchPanelCtr.keyword}'); DateTime now = DateTime.now(); if (item['value'] == 0) { ctr.pubBegin = null; @@ -424,7 +424,7 @@ class VideoPanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'video${searchPanelCtr.keyword!}'); + tag: 'video${searchPanelCtr.keyword}'); ctr.duration.value = item['value']; SmartDialog.showLoading(msg: 'loading'); await ctr.onRefresh(); @@ -462,7 +462,7 @@ class VideoPanelController extends GetxController { SmartDialog.showToast("「${item['label']}」的筛选结果"); SearchPanelController ctr = Get.find( - tag: 'video${searchPanelCtr.keyword!}'); + tag: 'video${searchPanelCtr.keyword}'); ctr.tids = item['tids']; SmartDialog.showLoading(msg: 'loading'); await ctr.onRefresh(); diff --git a/lib/pages/search_result/controller.dart b/lib/pages/search_result/controller.dart index 6e9d8bc6..104330c7 100644 --- a/lib/pages/search_result/controller.dart +++ b/lib/pages/search_result/controller.dart @@ -2,16 +2,8 @@ import 'package:PiliPlus/models/common/search_type.dart'; import 'package:get/get.dart'; class SearchResultController extends GetxController { - String? keyword; + String keyword = Get.parameters['keyword'] ?? ''; RxList count = List.generate(SearchType.values.length, (_) => -1).toList().obs; - - @override - void onInit() { - super.onInit(); - if (Get.parameters.keys.isNotEmpty) { - keyword = Get.parameters['keyword']; - } - } } diff --git a/lib/pages/search_result/view.dart b/lib/pages/search_result/view.dart index b1206578..ed3f20b3 100644 --- a/lib/pages/search_result/view.dart +++ b/lib/pages/search_result/view.dart @@ -60,7 +60,7 @@ class _SearchResultPageState extends State child: SizedBox( width: double.infinity, child: Text( - '${_searchResultController.keyword}', + _searchResultController.keyword, style: Theme.of(context).textTheme.titleMedium, ), ), @@ -110,7 +110,7 @@ class _SearchResultPageState extends State if (_tabController.indexIsChanging.not) { Get.find( tag: SearchType.values[index].name + - _searchResultController.keyword!) + _searchResultController.keyword) .animateToTop(); } }, diff --git a/lib/pages/webview/webview_page.dart b/lib/pages/webview/webview_page.dart index d7146ca8..6f6af0a0 100644 --- a/lib/pages/webview/webview_page.dart +++ b/lib/pages/webview/webview_page.dart @@ -198,35 +198,38 @@ class _WebviewPageNewState extends State { shouldOverrideUrlLoading: (controller, navigationAction) async { final String? str = navigationAction.request.url!.pathSegments.getOrNull(0); - final Map matchRes = IdUtils.matchAvorBv(input: str); - final List matchKeys = matchRes.keys.toList(); - if (matchKeys.isNotEmpty) { - if (matchKeys.first == 'BV') { - Get.offAndToNamed( - '/searchResult', - parameters: {'keyword': matchRes['BV']}, - ); + if (str != null) { + final Map matchRes = IdUtils.matchAvorBv(input: str); + if (matchRes.isNotEmpty) { + Get.back(); + PiliScheme.videoPush(matchRes['AV'], matchRes['BV']); return NavigationActionPolicy.CANCEL; } } var url = navigationAction.request.url!.toString(); - if (url.startsWith('http')) { - if (RegExp(r'https://www.bilibili.com/video/BV[a-zA-Z\d]+') - .hasMatch(url)) { - PiliScheme.routePush(Uri.parse(url)); - return NavigationActionPolicy.CANCEL; - } else if (url.startsWith('http://m.bilibili.com/playlist/')) { - try { - String? bvid = - RegExp(r'bvid=(BV[a-zA-Z\d]+)').firstMatch(url)?.group(1); - if (bvid != null) { - PiliScheme.videoPush(null, bvid); - return NavigationActionPolicy.CANCEL; - } - } catch (_) {} - } + if (RegExp( + r'^(https?://)?((www|m).)?(bilibili|b23).(com|tv)/video/BV[a-zA-Z\d]+') + .hasMatch(url)) { + try { + String? bvid = + RegExp(r'BV[a-zA-Z\d]+').firstMatch(url)?.group(0); + if (bvid != null) { + Get.back(); + PiliScheme.videoPush(null, bvid); + return NavigationActionPolicy.CANCEL; + } + } catch (_) {} + } else if (url.startsWith('http://m.bilibili.com/playlist/')) { + try { + String? bvid = + RegExp(r'bvid=(BV[a-zA-Z\d]+)').firstMatch(url)?.group(1); + if (bvid != null) { + PiliScheme.videoPush(null, bvid); + return NavigationActionPolicy.CANCEL; + } + } catch (_) {} } else { if (url.startsWith('bilibili://video/')) { String? str = Uri.parse(url).pathSegments.getOrNull(0); diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index 5656d0c8..3a953a18 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -225,18 +225,12 @@ class PiliScheme { } // 投稿跳转 - static Future videoPush(int? aidVal, String? bvidVal) async { + static Future videoPush(int? aid, String? bvid) async { try { - int? aid = aidVal; - String? bvid = bvidVal; - if (aidVal == null) { - aid = IdUtils.bv2av(bvidVal!); - } - if (bvidVal == null) { - bvid = IdUtils.av2bv(aidVal!); - } + aid ??= IdUtils.bv2av(bvid!); + bvid ??= IdUtils.av2bv(aid); SmartDialog.showLoading(msg: '获取中...'); - final int cid = await SearchHttp.ab2c(bvid: bvidVal, aid: aidVal); + final int cid = await SearchHttp.ab2c(bvid: bvid, aid: aid); SmartDialog.dismiss(); Utils.toDupNamed( '/video?bvid=$bvid&cid=$cid', diff --git a/lib/utils/id_utils.dart b/lib/utils/id_utils.dart index 7fefc268..fc479f24 100644 --- a/lib/utils/id_utils.dart +++ b/lib/utils/id_utils.dart @@ -68,23 +68,16 @@ class IdUtils { if (input == null || input.isEmpty) { return result; } - final RegExp bvRegex = - RegExp(r'[bB][vV][0-9A-Za-z]{10}', caseSensitive: false); - final RegExp avRegex = RegExp(r'[aA][vV]\d+', caseSensitive: false); + final RegExp bvRegex = RegExp(r'bv([0-9A-Za-z]+)', caseSensitive: false); + String? bvid = bvRegex.firstMatch(input)?.group(1); - final Iterable bvMatches = bvRegex.allMatches(input); - final Iterable avMatches = avRegex.allMatches(input); + late final RegExp avRegex = RegExp(r'av(\d+)', caseSensitive: false); + late String? aid = avRegex.firstMatch(input)?.group(1); - final List bvs = - bvMatches.map((Match match) => match.group(0)!).toList(); - final List avs = - avMatches.map((Match match) => match.group(0)!).toList(); - - if (bvs.isNotEmpty) { - result['BV'] = bvs[0].substring(0, 2).toUpperCase() + bvs[0].substring(2); - } - if (avs.isNotEmpty) { - result['AV'] = int.parse(avs[0].substring(2)); + if (bvid != null) { + result['BV'] = 'BV$bvid'; + } else if (aid != null) { + result['AV'] = int.parse(aid); } return result; }