From 2d338450f4bb6e3bb67b99ff9c4a8e2227b05def Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sat, 11 Jan 2025 10:05:01 +0800 Subject: [PATCH] feat: open in browser Closes #140 Signed-off-by: bggRGjQaUbCoE --- lib/common/widgets/video_card_v.dart | 9 +--- .../widgets/video_card_v_member_home.dart | 9 +--- lib/pages/dynamics/controller.dart | 9 +--- lib/pages/dynamics/widgets/forward_panel.dart | 6 +-- .../dynamics/widgets/rich_node_panel.dart | 13 ++---- lib/pages/html/view.dart | 15 ++----- lib/pages/live_room/view.dart | 18 ++------ lib/pages/setting/widgets/model.dart | 7 ++++ lib/pages/video/detail/introduction/view.dart | 5 +-- .../introduction/widgets/intro_detail.dart | 9 +--- .../detail/reply/widgets/reply_item.dart | 42 +++---------------- .../detail/reply/widgets/reply_item_grpc.dart | 41 +++--------------- lib/pages/video/detail/widgets/ai_detail.dart | 9 +--- .../whisper_detail/widget/chat_item.dart | 3 +- lib/utils/storage.dart | 4 ++ lib/utils/url_utils.dart | 9 +--- lib/utils/utils.dart | 18 ++++++++ 17 files changed, 60 insertions(+), 166 deletions(-) diff --git a/lib/common/widgets/video_card_v.dart b/lib/common/widgets/video_card_v.dart index f7eb2d21..4f4641a8 100644 --- a/lib/common/widgets/video_card_v.dart +++ b/lib/common/widgets/video_card_v.dart @@ -134,14 +134,7 @@ class VideoCardV extends StatelessWidget { break; default: SmartDialog.showToast(videoItem.goto); - Get.toNamed( - '/webview', - parameters: { - 'url': videoItem.uri, - 'type': 'url', - 'pageTitle': videoItem.title, - }, - ); + Utils.handleWebview(videoItem.uri); } } diff --git a/lib/common/widgets/video_card_v_member_home.dart b/lib/common/widgets/video_card_v_member_home.dart index ca7b5f54..88a943b8 100644 --- a/lib/common/widgets/video_card_v_member_home.dart +++ b/lib/common/widgets/video_card_v_member_home.dart @@ -123,14 +123,7 @@ class VideoCardVMemberHome extends StatelessWidget { // break; default: SmartDialog.showToast(goto); - Get.toNamed( - '/webview', - parameters: { - 'url': videoItem.uri ?? '', - 'type': 'url', - 'pageTitle': videoItem.title ?? '', - }, - ); + Utils.handleWebview(videoItem.uri ?? ''); } } diff --git a/lib/pages/dynamics/controller.dart b/lib/pages/dynamics/controller.dart index cf4ba301..9b497e15 100644 --- a/lib/pages/dynamics/controller.dart +++ b/lib/pages/dynamics/controller.dart @@ -138,14 +138,7 @@ class DynamicsController extends GetxController 'dynamicType': url.split('//').last.split('/')[1] }); } else { - Utils.toDupNamed( - '/webview', - parameters: { - 'url': 'https:$url', - 'type': 'note', - 'pageTitle': title - }, - ); + Utils.handleWebview('https:$url'); } break; diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index 2d0fc142..ac0e2e48 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -286,11 +286,7 @@ Widget forWard(item, context, ctr, source, callback, {floor = 1}) { final Map music = item.modules.moduleDynamic.major.music; return InkWell( onTap: () { - Get.toNamed('/webview', parameters: { - 'url': "https:${music['jump_url']}", - 'type': 'url', - 'pageTitle': music['title'] - }); + Utils.handleWebview("https:${music['jump_url']}"); }, child: Container( width: double.infinity, diff --git a/lib/pages/dynamics/widgets/rich_node_panel.dart b/lib/pages/dynamics/widgets/rich_node_panel.dart index ccdbe51d..a8107126 100644 --- a/lib/pages/dynamics/widgets/rich_node_panel.dart +++ b/lib/pages/dynamics/widgets/rich_node_panel.dart @@ -108,16 +108,9 @@ InlineSpan? richNode(item, context) { PiliScheme.routePush(Uri.parse(url)); return; } - Get.toNamed( - '/webview', - parameters: { - 'url': url.startsWith('//') - ? "https://${url.split('//').last}" - : url, - 'type': 'url', - 'pageTitle': '' - }, - ); + Utils.handleWebview(url.startsWith('//') + ? "https://${url.split('//').last}" + : url); }, child: Text( i.text ?? '', diff --git a/lib/pages/html/view.dart b/lib/pages/html/view.dart index 08b19e22..c1fb8e34 100644 --- a/lib/pages/html/view.dart +++ b/lib/pages/html/view.dart @@ -224,11 +224,7 @@ class _HtmlRenderPageState extends State IconButton( tooltip: '用内置浏览器打开', onPressed: () { - Get.toNamed('/webview', parameters: { - 'url': url.startsWith('http') ? url : 'https:$url', - 'type': 'url', - 'pageTitle': title, - }); + Utils.handleWebview(url.startsWith('http') ? url : 'https:$url'); }, icon: const Icon(Icons.open_in_browser_outlined, size: 19), ), @@ -250,18 +246,15 @@ class _HtmlRenderPageState extends State ), PopupMenuItem( onTap: () => { - Get.toNamed('/webview', parameters: { - 'url': url.startsWith('http') ? url : 'https:$url', - 'type': 'url', - 'pageTitle': title, - }), + Utils.handleWebview( + url.startsWith('http') ? url : 'https:$url') }, child: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.open_in_new, size: 19), SizedBox(width: 10), - Text('内置浏览器打开'), + Text('浏览器打开'), ], ), ), diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index de48d824..88da9669 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -292,21 +292,11 @@ class _LiveRoomPageState extends State ), //内置浏览器打开 IconButton( - tooltip: '内置浏览器打开', + tooltip: '浏览器打开', onPressed: () { - Get.offNamed( - '/webview', - parameters: { - 'url': - 'https://live.bilibili.com/h5/${_liveRoomController.roomId}', - 'type': 'liveRoom', - 'pageTitle': _liveRoomController - .roomInfoH5 - .value - .anchorInfo! - .baseInfo! - .uname!, - }, + Utils.handleWebview( + 'https://live.bilibili.com/h5/${_liveRoomController.roomId}', + off: true, ); }, icon: const Icon(Icons.open_in_browser)), diff --git a/lib/pages/setting/widgets/model.dart b/lib/pages/setting/widgets/model.dart index f60811b9..733e0810 100644 --- a/lib/pages/setting/widgets/model.dart +++ b/lib/pages/setting/widgets/model.dart @@ -1645,6 +1645,13 @@ List get extraSettings => [ key: SettingBoxKey.banWordForReply, getBanWord: () => GStorage.banWordForReply, ), + SettingsModel( + settingsType: SettingsType.sw1tch, + title: '使用外部浏览器打开链接', + leading: Icon(Icons.open_in_browser), + setKey: SettingBoxKey.openInBrowser, + defaultVal: false, + ), SettingsModel( settingsType: SettingsType.sw1tch, enableFeedback: true, diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index cf8235f5..e673cb1a 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -1035,10 +1035,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { recognizer: TapGestureRecognizer() ..onTap = () { try { - Get.toNamed( - '/webview', - parameters: {'url': matchStr}, - ); + Utils.handleWebview(matchStr); } catch (err) { SmartDialog.showToast(err.toString()); } diff --git a/lib/pages/video/detail/introduction/widgets/intro_detail.dart b/lib/pages/video/detail/introduction/widgets/intro_detail.dart index 00758ded..b6d69eea 100644 --- a/lib/pages/video/detail/introduction/widgets/intro_detail.dart +++ b/lib/pages/video/detail/introduction/widgets/intro_detail.dart @@ -167,14 +167,7 @@ class IntroDetail extends StatelessWidget { ..onTap = () { // 处理点击事件 try { - Get.toNamed( - '/webview', - parameters: { - 'url': match.group(0)!, - 'type': 'url', - 'pageTitle': match.group(0)!, - }, - ); + Utils.handleWebview(match.group(0)!); } catch (err) { SmartDialog.showToast(err.toString()); } diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 8339a85a..d00df4ad 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -838,24 +838,10 @@ class ReplyItem extends StatelessWidget { redirectUrl, ); } else { - Get.toNamed( - '/webview', - parameters: { - 'url': redirectUrl, - 'type': 'url', - 'pageTitle': title - }, - ); + Utils.handleWebview(redirectUrl); } } else { - Get.toNamed( - '/webview', - parameters: { - 'url': matchStr, - 'type': 'url', - 'pageTitle': title - }, - ); + Utils.handleWebview(matchStr); } } }, @@ -890,10 +876,7 @@ class ReplyItem extends StatelessWidget { color: Theme.of(context).colorScheme.primary, ), recognizer: TapGestureRecognizer() - ..onTap = () => Get.toNamed( - '/webview', - parameters: {'url': matchStr}, - ), + ..onTap = () => Utils.handleWebview(matchStr), ), ); } else { @@ -935,14 +918,7 @@ class ReplyItem extends StatelessWidget { ), recognizer: TapGestureRecognizer() ..onTap = () { - Get.toNamed( - '/webview', - parameters: { - 'url': patternStr, - 'type': 'url', - 'pageTitle': content.jumpUrl[patternStr]['title'] - }, - ); + Utils.handleWebview(patternStr); }, ) ], @@ -997,14 +973,8 @@ class ReplyItem extends StatelessWidget { color: Theme.of(context).colorScheme.primary, ), recognizer: TapGestureRecognizer() - ..onTap = () => Get.toNamed( - '/webview', - parameters: { - 'url': content.richText['note']['click_url'], - 'type': 'note', - 'pageTitle': '笔记预览' - }, - ), + ..onTap = () => + Utils.handleWebview(content.richText['note']['click_url']), ), ); } diff --git a/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart b/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart index 02b9b836..f8d7c433 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart @@ -870,24 +870,10 @@ class ReplyItemGrpc extends StatelessWidget { redirectUrl, ); } else { - Get.toNamed( - '/webview', - parameters: { - 'url': redirectUrl, - 'type': 'url', - 'pageTitle': title - }, - ); + Utils.handleWebview(redirectUrl); } } else { - Get.toNamed( - '/webview', - parameters: { - 'url': matchStr, - 'type': 'url', - 'pageTitle': title - }, - ); + Utils.handleWebview(matchStr); } } }, @@ -922,10 +908,7 @@ class ReplyItemGrpc extends StatelessWidget { color: Theme.of(context).colorScheme.primary, ), recognizer: TapGestureRecognizer() - ..onTap = () => Get.toNamed( - '/webview', - parameters: {'url': matchStr}, - ), + ..onTap = () => Utils.handleWebview(matchStr), ), ); } else { @@ -966,14 +949,7 @@ class ReplyItemGrpc extends StatelessWidget { ), recognizer: TapGestureRecognizer() ..onTap = () { - Get.toNamed( - '/webview', - parameters: { - 'url': patternStr, - 'type': 'url', - 'pageTitle': content.url[patternStr]!.title - }, - ); + Utils.handleWebview(patternStr); }, ) ], @@ -1028,14 +1004,7 @@ class ReplyItemGrpc extends StatelessWidget { color: Theme.of(context).colorScheme.primary, ), recognizer: TapGestureRecognizer() - ..onTap = () => Get.toNamed( - '/webview', - parameters: { - 'url': content.richText.note.clickUrl, - 'type': 'note', - 'pageTitle': '笔记预览' - }, - ), + ..onTap = () => Utils.handleWebview(content.richText.note.clickUrl), ), ); } diff --git a/lib/pages/video/detail/widgets/ai_detail.dart b/lib/pages/video/detail/widgets/ai_detail.dart index f3732fd5..fb13e146 100644 --- a/lib/pages/video/detail/widgets/ai_detail.dart +++ b/lib/pages/video/detail/widgets/ai_detail.dart @@ -190,14 +190,7 @@ class AiDetail extends StatelessWidget { ..onTap = () { // 处理点击事件 try { - Get.toNamed( - '/webview', - parameters: { - 'url': match.group(0)!, - 'type': 'url', - 'pageTitle': match.group(0)!, - }, - ); + Utils.handleWebview(match.group(0)!); } catch (err) { SmartDialog.showToast(err.toString()); } diff --git a/lib/pages/whisper_detail/widget/chat_item.dart b/lib/pages/whisper_detail/widget/chat_item.dart index 74817df1..122b3d77 100644 --- a/lib/pages/whisper_detail/widget/chat_item.dart +++ b/lib/pages/whisper_detail/widget/chat_item.dart @@ -313,8 +313,7 @@ class ChatItem extends StatelessWidget { } } else { SmartDialog.showToast('未匹配到 BV 号'); - Get.toNamed('/webview', - arguments: {'url': i['jump_url']}); + Utils.handleWebview(i['jump_url']); } }, child: Row( diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index f638fcd8..cb2337f1 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -318,6 +318,9 @@ class GStorage { static bool get horizontalPreview => GStorage.setting .get(SettingBoxKey.horizontalPreview, defaultValue: false); + static bool get openInBrowser => + GStorage.setting.get(SettingBoxKey.openInBrowser, defaultValue: false); + static bool get savedRcmdTip => GStorage.setting.get(SettingBoxKey.savedRcmdTip, defaultValue: true); @@ -534,6 +537,7 @@ class SettingBoxKey { banWordForReply = 'banWordForReply', banWordForZone = 'banWordForZone', savedRcmdTip = 'savedRcmdTip', + openInBrowser = 'openInBrowser', // Sponsor Block enableSponsorBlock = 'enableSponsorBlock', diff --git a/lib/utils/url_utils.dart b/lib/utils/url_utils.dart index 85fab38c..b3a8f380 100644 --- a/lib/utils/url_utils.dart +++ b/lib/utils/url_utils.dart @@ -66,14 +66,7 @@ class UrlUtils { preventDuplicates: false, ); } else { - await Get.toNamed( - '/webview', - parameters: { - 'url': redirectUrl, - 'type': 'url', - 'pageTitle': title, - }, - ); + Utils.handleWebview(redirectUrl); } } } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 8be3b3c2..35021de3 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -40,6 +40,24 @@ class Utils { static const channel = MethodChannel("PiliPlus"); + static void handleWebview(String url, {bool off = false}) { + if (GStorage.openInBrowser) { + launchURL(url); + } else { + if (off) { + Get.offNamed( + '/webview', + parameters: {'url': url}, + ); + } else { + toDupNamed( + '/webview', + parameters: {'url': url}, + ); + } + } + } + static bool viewPgcFromUri(String uri) { String? id = RegExp(r'(ep|ss)\d+').firstMatch(uri)?.group(0); if (id != null) {