seek from ugc intro

Closes #1303

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-09-24 10:36:33 +08:00
parent ec1bdb243f
commit 6ced89f30b
2 changed files with 30 additions and 7 deletions

View File

@@ -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<UgcIntroPanel> {
}
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<UgcIntroPanel> {
switch (currentDesc.type) {
case 1:
final List<InlineSpan> spanChildren = <InlineSpan>[];
(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<UgcIntroPanel> {
},
),
);
} 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<UgcIntroPanel> {
} 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<UgcIntroPanel> {
} 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<VideoDetailController>(
tag: widget.heroTag,
).plPlayerController.seekTo(
Duration(
seconds: DurationUtils.parseDuration(matchStr),
),
isSeek: false,
);
} catch (_) {}
},
),
);
}
return '';
},

View File

@@ -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<int> split = data.split(':').reversed.map(int.parse).toList();
List<int> 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();