diff --git a/lib/pages/video/introduction/ugc/view.dart b/lib/pages/video/introduction/ugc/view.dart index 777b438f9..322a1662c 100644 --- a/lib/pages/video/introduction/ugc/view.dart +++ b/lib/pages/video/introduction/ugc/view.dart @@ -18,6 +18,7 @@ import 'package:PiliPlus/pages/video/introduction/ugc/widgets/season.dart'; import 'package:PiliPlus/pages/video/introduction/ugc/widgets/selectable_text.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/date_utils.dart'; +import 'package:PiliPlus/utils/duration_utils.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/id_utils.dart'; @@ -592,7 +593,7 @@ class _UgcIntroPanelState extends State { } static final RegExp urlRegExp = RegExp( - '${Constants.urlRegex.pattern}|av\\d+|bv[a-z\\d]{10}', + Constants.urlRegex.pattern + r'|av\d+|bv[a-z\d]{10}|(?:\d+[::])?\d+[::]\d+', caseSensitive: false, ); @@ -607,11 +608,12 @@ class _UgcIntroPanelState extends State { switch (currentDesc.type) { case 1: final List spanChildren = []; - (currentDesc.rawText as String).splitMapJoin( + currentDesc.rawText?.splitMapJoin( urlRegExp, onMatch: (Match match) { - String matchStr = match[0]!; - if (matchStr.toLowerCase().startsWith('http')) { + final matchStr = match[0]!; + final matchStrLowerCase = matchStr.toLowerCase(); + if (matchStrLowerCase.startsWith('http')) { spanChildren.add( TextSpan( text: matchStr, @@ -626,7 +628,7 @@ class _UgcIntroPanelState extends State { }, ), ); - } else if (matchStr.startsWith('av')) { + } else if (matchStrLowerCase.startsWith('av')) { try { int aid = int.parse(matchStr.substring(2)); IdUtils.av2bv(aid); @@ -641,7 +643,7 @@ class _UgcIntroPanelState extends State { } catch (e) { spanChildren.add(TextSpan(text: matchStr)); } - } else { + } else if (matchStrLowerCase.startsWith('bv')) { try { IdUtils.bv2av(matchStr); spanChildren.add( @@ -655,6 +657,26 @@ class _UgcIntroPanelState extends State { } catch (e) { spanChildren.add(TextSpan(text: matchStr)); } + } else { + spanChildren.add( + TextSpan( + text: matchStr, + style: TextStyle(color: theme.colorScheme.primary), + recognizer: TapGestureRecognizer() + ..onTap = () { + try { + Get.find( + tag: widget.heroTag, + ).plPlayerController.seekTo( + Duration( + seconds: DurationUtils.parseDuration(matchStr), + ), + isSeek: false, + ); + } catch (_) {} + }, + ), + ); } return ''; }, diff --git a/lib/utils/duration_utils.dart b/lib/utils/duration_utils.dart index 5f0354b4a..81bd03043 100644 --- a/lib/utils/duration_utils.dart +++ b/lib/utils/duration_utils.dart @@ -17,11 +17,12 @@ abstract class DurationUtils { : "${h.toString().padLeft(2, '0')}:${m.toString().padLeft(2, '0')}:$sms"; } + static final _splitRegex = RegExp(r'[::]'); static int parseDuration(String? data) { if (data == null || data.isEmpty) { return 0; } - List split = data.split(':').reversed.map(int.parse).toList(); + List split = data.split(_splitRegex).reversed.map(int.parse).toList(); int duration = 0; for (int i = 0; i < split.length; i++) { duration += split[i] * pow(60, i).toInt();