diff --git a/lib/pages/about/index.dart b/lib/pages/about/index.dart index c5d4d6200..7a15d7f75 100644 --- a/lib/pages/about/index.dart +++ b/lib/pages/about/index.dart @@ -71,7 +71,7 @@ class _AboutPageState extends State { onSubmitted: (value) { Get.back(); if (value.isNotEmpty) { - Get.toNamed('/webview', parameters: {'url': value}); + Utils.handleWebview(value, inApp: true); } }, ), diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index 6e1d6e0c2..3a8502b52 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -310,10 +310,7 @@ Widget forWard(item, context, source, callback, {floor = 1}) { if (url.contains('bangumi/play') && Utils.viewPgcFromUri(url)) { return; } - Get.toNamed( - '/webview', - parameters: {'url': url}, - ); + Utils.handleWebview(url, inApp: true); } catch (_) {} }, child: Container( diff --git a/lib/pages/search_panel/controller.dart b/lib/pages/search_panel/controller.dart index d2a4015a3..b9e58b43e 100644 --- a/lib/pages/search_panel/controller.dart +++ b/lib/pages/search_panel/controller.dart @@ -1,11 +1,11 @@ import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/pages/common/common_controller.dart'; import 'package:PiliPlus/pages/search_result/controller.dart'; +import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:get/get.dart'; import 'package:PiliPlus/http/search.dart'; import 'package:PiliPlus/models/common/search_type.dart'; import 'package:PiliPlus/utils/id_utils.dart'; -import 'package:PiliPlus/utils/utils.dart'; class SearchPanelController extends CommonController { SearchPanelController({ @@ -61,39 +61,17 @@ class SearchPanelController extends CommonController { void onPushDetail(resultList) async { // 匹配输入内容,如果是AV、BV号且有结果 直接跳转详情页 Map matchRes = IdUtils.matchAvorBv(input: keyword); - List matchKeys = matchRes.keys.toList(); - String? bvid; - try { - bvid = resultList.first.bvid; - } catch (_) { - bvid = null; + if (matchRes.isNotEmpty) { + PiliScheme.videoPush(matchRes['AV'], matchRes['BV'], false); + return; } // keyword 可能输入纯数字 - int? aid; try { - aid = resultList.first.aid; - } catch (_) { - aid = null; - } - if (matchKeys.isNotEmpty && searchType == SearchType.video || - aid.toString() == keyword) { - int cid = await SearchHttp.ab2c(aid: aid, bvid: bvid); - if (matchKeys.isNotEmpty && - matchKeys.first == 'BV' && - matchRes[matchKeys.first] == bvid || - matchKeys.isNotEmpty && - matchKeys.first == 'AV' && - matchRes[matchKeys.first] == aid || - aid.toString() == keyword) { - Get.toNamed( - '/video?bvid=$bvid&cid=$cid', - arguments: { - 'videoItem': resultList.first, - 'heroTag': Utils.makeHeroTag(bvid), - }, - ); + int? aid = int.tryParse(keyword); + if (aid != null && resultList.first.aid == aid) { + PiliScheme.videoPush(aid, null, false); } - } + } catch (_) {} } @override diff --git a/lib/pages/webview/webview_page.dart b/lib/pages/webview/webview_page.dart index 6f6af0a00..f2ee70305 100644 --- a/lib/pages/webview/webview_page.dart +++ b/lib/pages/webview/webview_page.dart @@ -221,7 +221,9 @@ class _WebviewPageNewState extends State { return NavigationActionPolicy.CANCEL; } } catch (_) {} - } else if (url.startsWith('http://m.bilibili.com/playlist/')) { + } else if (RegExp( + r'^(https?://)?((www|m).)?(bilibili|b23).(com|tv)/playlist') + .hasMatch(url)) { try { String? bvid = RegExp(r'bvid=(BV[a-zA-Z\d]+)').firstMatch(url)?.group(1); @@ -230,9 +232,10 @@ class _WebviewPageNewState extends State { return NavigationActionPolicy.CANCEL; } } catch (_) {} - } else { + } else if (url.startsWith('http').not) { if (url.startsWith('bilibili://video/')) { - String? str = Uri.parse(url).pathSegments.getOrNull(0); + String? str = + navigationAction.request.url!.pathSegments.getOrNull(0); Get.offAndToNamed( '/searchResult', parameters: {'keyword': str ?? ''}, diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index 3a953a18e..33dcf9bad 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -225,13 +225,18 @@ class PiliScheme { } // 投稿跳转 - static Future videoPush(int? aid, String? bvid) async { + static Future videoPush(int? aid, String? bvid, + [bool showDialog = true]) async { try { aid ??= IdUtils.bv2av(bvid!); bvid ??= IdUtils.av2bv(aid); - SmartDialog.showLoading(msg: '获取中...'); + if (showDialog) { + SmartDialog.showLoading(msg: '获取中...'); + } final int cid = await SearchHttp.ab2c(bvid: bvid, aid: aid); - SmartDialog.dismiss(); + if (showDialog) { + SmartDialog.dismiss(); + } Utils.toDupNamed( '/video?bvid=$bvid&cid=$cid', arguments: { diff --git a/lib/utils/id_utils.dart b/lib/utils/id_utils.dart index fc479f242..e7591fe60 100644 --- a/lib/utils/id_utils.dart +++ b/lib/utils/id_utils.dart @@ -68,10 +68,11 @@ class IdUtils { if (input == null || input.isEmpty) { return result; } - final RegExp bvRegex = RegExp(r'bv([0-9A-Za-z]+)', caseSensitive: false); + final RegExp bvRegex = + RegExp(r'^bv([0-9A-Za-z]{10})', caseSensitive: false); String? bvid = bvRegex.firstMatch(input)?.group(1); - late final RegExp avRegex = RegExp(r'av(\d+)', caseSensitive: false); + late final RegExp avRegex = RegExp(r'^av(\d+)', caseSensitive: false); late String? aid = avRegex.firstMatch(input)?.group(1); if (bvid != null) { diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 5ce8f7cd9..5ceb8c752 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -21,6 +21,7 @@ import 'package:PiliPlus/models/user/fav_folder.dart'; import 'package:PiliPlus/pages/later/controller.dart'; import 'package:PiliPlus/pages/video/detail/introduction/widgets/fav_panel.dart'; import 'package:PiliPlus/pages/video/detail/introduction/widgets/group_panel.dart'; +import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/id_utils.dart'; @@ -367,19 +368,46 @@ class Utils { ); } + static bool _handleInAppWebview(String url) { + 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) { + PiliScheme.videoPush(null, bvid); + return true; + } + } catch (_) {} + } else if (RegExp( + r'^(https?://)?((www|m).)?(bilibili|b23).(com|tv)/playlist') + .hasMatch(url)) { + try { + String? bvid = + RegExp(r'bvid=(BV[a-zA-Z\d]+)').firstMatch(url)?.group(1); + if (bvid != null) { + PiliScheme.videoPush(null, bvid); + return true; + } + } catch (_) {} + } else if (RegExp(r'^(https?://)?((www|m).)?(bilibili|b23).(com|tv)') + .hasMatch(url)) { + toDupNamed( + '/webview', + parameters: {'url': url}, + ); + return true; + } + return false; + } + static void handleWebview( String url, { bool off = false, bool inApp = false, }) { if (inApp.not && GStorage.openInBrowser) { - if (RegExp(r'^(https?://)?((www|m).)?(bilibili|b23).(com|tv)') - .hasMatch(url)) { - toDupNamed( - '/webview', - parameters: {'url': url}, - ); - } else { + if (_handleInAppWebview(url).not) { launchURL(url); } } else { @@ -389,10 +417,12 @@ class Utils { parameters: {'url': url}, ); } else { - toDupNamed( - '/webview', - parameters: {'url': url}, - ); + if (_handleInAppWebview(url).not) { + toDupNamed( + '/webview', + parameters: {'url': url}, + ); + } } } }