diff --git a/lib/pages/danmaku/controller.dart b/lib/pages/danmaku/controller.dart index 868d9be9..6879c24d 100644 --- a/lib/pages/danmaku/controller.dart +++ b/lib/pages/danmaku/controller.dart @@ -1,7 +1,6 @@ import 'package:PiliPlus/grpc/dm/v1/dm.pb.dart'; import 'package:PiliPlus/http/danmaku.dart'; import 'package:PiliPlus/plugin/pl_player/controller.dart'; -import 'package:PiliPlus/utils/storage.dart'; class PlDanmakuController { PlDanmakuController( @@ -19,8 +18,6 @@ class PlDanmakuController { static int segmentLength = 60 * 6 * 1000; - late final mergeDanmaku = GStorage.mergeDanmaku; - void initiate(int videoDuration, int progress) { if (videoDuration <= 0) { return; @@ -50,7 +47,7 @@ class PlDanmakuController { final DmSegMobileReply result = await DanmakaHttp.queryDanmaku( cid: cid, segmentIndex: segmentIndex + 1, - mergeDanmaku: mergeDanmaku, + mergeDanmaku: plPlayerController.mergeDanmaku, ); if (result.elems.isNotEmpty) { for (var element in result.elems) { diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 515aa97e..b17d9574 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -846,24 +846,19 @@ class ReplyItem extends StatelessWidget { if (RegExp(r'^(av|bv)', caseSensitive: false) .hasMatch(matchStr)) { UrlUtils.matchUrlPush(matchStr, ''); - } else if (RegExp(r'^cv\d+$', caseSensitive: false) - .hasMatch(matchStr)) { - String cvid = 'cv${matchStr.substring(2)}'; - Get.toNamed('/htmlRender', parameters: { - 'url': 'https://www.bilibili.com/read/$cvid', - 'title': title, - 'id': cvid, - 'dynamicType': 'read' - }); } else { - String? cvId = RegExp(r'/read/(cv\d+)') - .firstMatch(matchStr) - ?.group(1); - if (cvId != null) { + RegExpMatch? firstMatch = RegExp( + r'^cv(\d+)$|/read/cv(\d+)|note-app/view\?cvid=(\d+)', + caseSensitive: false) + .firstMatch(matchStr); + String? cvid = firstMatch?.group(1) ?? + firstMatch?.group(2) ?? + firstMatch?.group(3); + if (cvid != null) { Get.toNamed('/htmlRender', parameters: { - 'url': matchStr, + 'url': 'https://www.bilibili.com/read/cv$cvid', 'title': title, - 'id': cvId, + 'id': 'cv$cvid', 'dynamicType': 'read' }); return; 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 b4cfe549..213f1757 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart @@ -884,24 +884,19 @@ class ReplyItemGrpc extends StatelessWidget { if (RegExp(r'^(av|bv)', caseSensitive: false) .hasMatch(matchStr)) { UrlUtils.matchUrlPush(matchStr, ''); - } else if (RegExp(r'^cv\d+$', caseSensitive: false) - .hasMatch(matchStr)) { - String cvid = 'cv${matchStr.substring(2)}'; - Get.toNamed('/htmlRender', parameters: { - 'url': 'https://www.bilibili.com/read/$cvid', - 'title': title, - 'id': cvid, - 'dynamicType': 'read' - }); } else { - String? cvId = RegExp(r'/read/(cv\d+)') - .firstMatch(matchStr) - ?.group(1); - if (cvId != null) { + RegExpMatch? firstMatch = RegExp( + r'^cv(\d+)$|/read/cv(\d+)|note-app/view\?cvid=(\d+)', + caseSensitive: false, + ).firstMatch(matchStr); + String? cvid = firstMatch?.group(1) ?? + firstMatch?.group(2) ?? + firstMatch?.group(3); + if (cvid != null) { Get.toNamed('/htmlRender', parameters: { - 'url': matchStr, + 'url': 'https://www.bilibili.com/read/cv$cvid', 'title': title, - 'id': cvId, + 'id': 'cv$cvid', 'dynamicType': 'read' }); return; diff --git a/lib/pages/webview/webview_page.dart b/lib/pages/webview/webview_page.dart index 1b077097..1c895ffd 100644 --- a/lib/pages/webview/webview_page.dart +++ b/lib/pages/webview/webview_page.dart @@ -165,7 +165,8 @@ class _WebviewPageNewState extends State { userAgent: Request().headerUa(type: uaType), mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW, ), - initialUrlRequest: URLRequest(url: WebUri.uri(Uri.parse(_url))), + initialUrlRequest: + URLRequest(url: WebUri.uri(Uri.tryParse(_url) ?? Uri())), onWebViewCreated: (InAppWebViewController controller) { _webViewController = controller; }, @@ -272,7 +273,8 @@ class _WebviewPageNewState extends State { return NavigationActionPolicy.CANCEL; } } catch (_) {} - } else if (url.startsWith('http').not) { + } else if (RegExp(r'^(?!(https?://))\S+://', caseSensitive: false) + .hasMatch(url)) { if (url.startsWith('bilibili://video/')) { String? str = navigationAction.request.url!.pathSegments.getOrNull(0); diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 6d94afcd..59b24547 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -260,6 +260,7 @@ class PlPlayerController { // 关联弹幕控制器 DanmakuController? danmakuController; bool showDanmaku = true; + late final mergeDanmaku = GStorage.mergeDanmaku; // 弹幕相关配置 late List blockTypes; late double showArea; @@ -1611,6 +1612,4 @@ class PlPlayerController { late final RxList dmTrend = [].obs; late final RxBool showDmChart = true.obs; - - late final RxBool showRestoreScaleBtn = false.obs; } diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 361a04f8..d96fb6c0 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -103,6 +103,8 @@ class _PLVideoPlayerState extends State late bool enableQuickDouble; late bool fullScreenGestureReverse; + late final RxBool showRestoreScaleBtn = false.obs; + Offset _initialFocalPoint = Offset.zero; String? _gestureType; //播放器放缩 @@ -702,7 +704,7 @@ class _PLVideoPlayerState extends State }, onInteractionUpdate: (ScaleUpdateDetails details) { - plPlayerController.showRestoreScaleBtn.value = + showRestoreScaleBtn.value = transformationController.value.row0.x != 1.0; if (interacting || _initialFocalPoint == Offset.zero) return; Offset cumulativeDelta = @@ -1145,52 +1147,51 @@ class _PLVideoPlayerState extends State // ), Obx( - () => plPlayerController.showRestoreScaleBtn.value && - plPlayerController.showControls.value - ? Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: const EdgeInsets.only(bottom: 75), - child: FilledButton.tonal( - style: FilledButton.styleFrom( - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - backgroundColor: Theme.of(context) - .colorScheme - .secondaryContainer - .withOpacity(0.8), - visualDensity: - VisualDensity(horizontal: -2, vertical: -2), - padding: const EdgeInsets.symmetric( - horizontal: 15, vertical: 15), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(6), + () => + showRestoreScaleBtn.value && plPlayerController.showControls.value + ? Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.only(bottom: 95), + child: FilledButton.tonal( + style: FilledButton.styleFrom( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + backgroundColor: Theme.of(context) + .colorScheme + .secondaryContainer + .withOpacity(0.8), + visualDensity: + VisualDensity(horizontal: -2, vertical: -2), + padding: const EdgeInsets.all(15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + onPressed: () async { + showRestoreScaleBtn.value = false; + final animController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 255), + ); + final anim = Matrix4Tween( + begin: transformationController.value, + end: Matrix4.identity(), + ).animate( + CurveTween(curve: Curves.easeOut) + .animate(animController), + ); + animController.addListener(() { + transformationController.value = anim.value; + }); + await animController.forward(from: 0); + animController.removeListener(() {}); + animController.dispose(); + }, + child: Text('还原屏幕'), ), ), - onPressed: () async { - plPlayerController.showRestoreScaleBtn.value = false; - final animController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 255), - ); - final anim = Matrix4Tween( - begin: transformationController.value, - end: Matrix4.identity(), - ).animate( - CurveTween(curve: Curves.easeOut) - .animate(animController), - ); - animController.addListener(() { - transformationController.value = anim.value; - }); - await animController.forward(from: 0); - animController.removeListener(() {}); - animController.dispose(); - }, - child: Text('还原屏幕'), - ), - ), - ) - : const SizedBox.shrink(), + ) + : const SizedBox.shrink(), ), /// 进度条 live模式下禁用