From 44a162762cc134ec2b752021d05c89096fd8f2e6 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 9 Feb 2024 23:24:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AF=84=E8=AE=BA=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E8=B7=B3=E8=BD=AC=20issues=20#405?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/reply/widgets/reply_item.dart | 74 +++++++++++++------ lib/utils/url_utils.dart | 61 +++++++++++++++ 2 files changed, 113 insertions(+), 22 deletions(-) create mode 100644 lib/utils/url_utils.dart diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 7991a366..fb76f4d4 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -1,7 +1,6 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/common/widgets/badge.dart'; @@ -12,10 +11,9 @@ import 'package:pilipala/pages/preview/index.dart'; import 'package:pilipala/pages/video/detail/index.dart'; import 'package:pilipala/pages/video/detail/reply_new/index.dart'; import 'package:pilipala/utils/feed_back.dart'; -import 'package:pilipala/utils/id_utils.dart'; import 'package:pilipala/utils/storage.dart'; +import 'package:pilipala/utils/url_utils.dart'; import 'package:pilipala/utils/utils.dart'; - import 'zan.dart'; Box setting = GStrorage.setting; @@ -541,7 +539,6 @@ InlineSpan buildContent( // fReplyItem 父级回复内容,用作二楼回复(回复详情)展示 final content = replyItem.content; final List spanChilds = []; - bool hasMatchMember = false; // 投票 if (content.vote.isNotEmpty) { @@ -591,7 +588,7 @@ InlineSpan buildContent( if (patternStr.isNotEmpty) { patternStr += "|"; } - patternStr += r'(\b\d{1,2}[::]\d{2}\b)'; + patternStr += r'(\b\d{1,2}[::]\d{2}(?:[::]\d{2})?\b)'; final RegExp pattern = RegExp(patternStr); List matchedStrs = []; void addPlainTextSpan(str) { @@ -639,7 +636,9 @@ InlineSpan buildContent( }, ), ); - } else if (RegExp(r'^\b[0-9]{1,2}[::][0-9]{2}\b$').hasMatch(matchStr)) { + } else if (RegExp(r'^\b\d{1,2}[::]\d{2}(?:[::]\d{2})?\b$') + .hasMatch(matchStr)) { + matchStr = matchStr.replaceAll(':', ':'); spanChilds.add( TextSpan( text: ' $matchStr ', @@ -650,7 +649,6 @@ InlineSpan buildContent( ..onTap = () { // 跳转到指定位置 try { - matchStr = matchStr.replaceAll(':', ':'); SmartDialog.showToast('跳转至:$matchStr'); Get.find(tag: Get.arguments['heroTag']) .plPlayerController @@ -692,16 +690,54 @@ InlineSpan buildContent( color: Theme.of(context).colorScheme.primary, ), recognizer: TapGestureRecognizer() - ..onTap = () { + ..onTap = () async { + final String title = content.jumpUrl[matchStr]['title']; if (appUrlSchema == '') { - final String str = Uri.parse(matchStr).pathSegments[0]; - final Map matchRes = IdUtils.matchAvorBv(input: str); - final List matchKeys = matchRes.keys.toList(); - if (matchKeys.isNotEmpty) { - if (matchKeys.first == 'BV') { + final String redirectUrl = + await UrlUtils.parseRedirectUrl(matchStr); + final String pathSegment = Uri.parse(redirectUrl).path; + final String lastPathSegment = + pathSegment.split('/').last; + if (lastPathSegment.startsWith('BV')) { + UrlUtils.matchUrlPush( + lastPathSegment, + title, + redirectUrl, + ); + } else { + Get.toNamed( + '/webview', + parameters: { + 'url': redirectUrl, + 'type': 'url', + 'pageTitle': title + }, + ); + } + } else { + if (appUrlSchema.startsWith('bilibili://search')) { + Get.toNamed('/searchResult', + parameters: {'keyword': title}); + } else if (matchStr.startsWith('https://b23.tv')) { + final String redirectUrl = + await UrlUtils.parseRedirectUrl(matchStr); + final String pathSegment = Uri.parse(redirectUrl).path; + final String lastPathSegment = + pathSegment.split('/').last; + if (lastPathSegment.startsWith('BV')) { + UrlUtils.matchUrlPush( + lastPathSegment, + title, + redirectUrl, + ); + } else { Get.toNamed( - '/searchResult', - parameters: {'keyword': matchRes['BV']}, + '/webview', + parameters: { + 'url': redirectUrl, + 'type': 'url', + 'pageTitle': title + }, ); } } else { @@ -710,16 +746,10 @@ InlineSpan buildContent( parameters: { 'url': matchStr, 'type': 'url', - 'pageTitle': '' + 'pageTitle': title }, ); } - } else { - if (appUrlSchema.startsWith('bilibili://search')) { - Get.toNamed('/searchResult', parameters: { - 'keyword': content.jumpUrl[matchStr]['title'] - }); - } } }, ) diff --git a/lib/utils/url_utils.dart b/lib/utils/url_utils.dart new file mode 100644 index 00000000..bac6cdfa --- /dev/null +++ b/lib/utils/url_utils.dart @@ -0,0 +1,61 @@ +import 'package:dio/dio.dart'; +import 'package:get/get.dart'; + +import '../http/search.dart'; +import 'id_utils.dart'; +import 'utils.dart'; + +class UrlUtils { + // 302重定向路由截取 + static Future parseRedirectUrl(String url) async { + late String redirectUrl; + final dio = Dio(); + dio.options.followRedirects = false; + dio.options.validateStatus = (status) { + return status == 200 || status == 301 || status == 302; + }; + final response = await dio.get(url); + if (response.statusCode == 302) { + redirectUrl = response.headers['location']?.first as String; + if (redirectUrl.endsWith('/')) { + redirectUrl = redirectUrl.substring(0, redirectUrl.length - 1); + } + } else { + if (url.endsWith('/')) { + url = url.substring(0, url.length - 1); + } + return url; + } + return redirectUrl; + } + + // 匹配url路由跳转 + static matchUrlPush( + String pathSegment, + String title, + String redirectUrl, + ) async { + final Map matchRes = IdUtils.matchAvorBv(input: pathSegment); + if (matchRes.containsKey('BV')) { + final String bv = matchRes['BV']; + final int cid = await SearchHttp.ab2c(bvid: bv); + final String heroTag = Utils.makeHeroTag(bv); + await Get.toNamed( + '/video?bvid=$bv&cid=$cid', + arguments: { + 'pic': '', + 'heroTag': heroTag, + }, + ); + } else { + await Get.toNamed( + '/webview', + parameters: { + 'url': redirectUrl, + 'type': 'url', + 'pageTitle': title, + }, + ); + } + } +}