opt: replyitem: seek time

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-12-12 15:32:37 +08:00
parent 5d8b42a928
commit c7fef4e998
4 changed files with 51 additions and 29 deletions

View File

@@ -3,10 +3,8 @@ import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/models/common/reply_type.dart';
import 'package:PiliPalaX/pages/common/reply_controller.dart';
import 'package:PiliPalaX/http/reply.dart';
import 'package:PiliPalaX/pages/video/detail/controller.dart';
import 'package:PiliPalaX/utils/global_data.dart';
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:get/get.dart';
class VideoReplyController extends ReplyController {
VideoReplyController(

View File

@@ -271,6 +271,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
onDelete: _videoReplyController.onMDelete,
onViewImage: widget.onViewImage,
onDismissed: widget.onDismissed,
getTag: () => heroTag,
);
}
},

View File

@@ -1,3 +1,5 @@
import 'dart:math';
import 'package:PiliPalaX/common/widgets/imageview.dart';
import 'package:PiliPalaX/http/video.dart';
import 'package:PiliPalaX/utils/extension.dart';
@@ -34,6 +36,7 @@ class ReplyItem extends StatelessWidget {
this.onDelete,
this.onViewImage,
this.onDismissed,
this.getTag,
});
final ReplyItemModel? replyItem;
final String? replyLevel;
@@ -45,6 +48,7 @@ class ReplyItem extends StatelessWidget {
final Function(dynamic rpid, dynamic frpid)? onDelete;
final VoidCallback? onViewImage;
final ValueChanged<int>? onDismissed;
final Function? getTag;
@override
Widget build(BuildContext context) {
@@ -315,6 +319,7 @@ class ReplyItem extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(top: 5, bottom: 12),
child: replyItemRow(
context: context,
replies: replyItem!.replies,
replyControl: replyItem!.replyControl,
// f_rpid: replyItem!.rpid,
@@ -635,7 +640,7 @@ class ReplyItem extends StatelessWidget {
if (patternStr.isNotEmpty) {
patternStr += "|";
}
patternStr += r'(\b(?:\d+[:])?[0-5]?[0-9][:][0-5]?[0-9]\b)';
patternStr += r'(\b(?:\d+[:])?\d+[:]\d+\b)';
if (jumpUrlKeysList.isNotEmpty) {
patternStr += '|${jumpUrlKeysList.map(RegExp.escape).join('|')}';
}
@@ -692,33 +697,55 @@ class ReplyItem extends StatelessWidget {
},
),
);
} else if (RegExp(r'^\b(?:\d+[:])?[0-5]?[0-9][:][0-5]?[0-9]\b$')
.hasMatch(matchStr)) {
} else if (RegExp(r'^\b(?:\d+[:])?\d+[:]\d+\b$').hasMatch(matchStr)) {
matchStr = matchStr.replaceAll('', ':');
bool isValid = false;
try {
List<int> split = matchStr
.split(':')
.map((item) => int.parse(item))
.toList()
.reversed
.toList();
int seek = 0;
for (int i = 0; i < split.length; i++) {
seek += split[i] * pow(60, i).toInt();
}
int duration = Get.find<VideoDetailController>(
tag: getTag?.call() ?? Get.arguments['heroTag'],
).data.timeLength ??
0;
isValid = seek * 1000 <= duration;
} catch (e) {
debugPrint('failed to validate: $e');
}
spanChildren.add(
TextSpan(
text: ' $matchStr ',
style: isVideoPage
text: isValid ? ' $matchStr ' : matchStr,
style: isValid && isVideoPage
? TextStyle(
color: Theme.of(context).colorScheme.primary,
)
: null,
recognizer: TapGestureRecognizer()
..onTap = () {
// 跳转到指定位置
if (isVideoPage) {
try {
SmartDialog.showToast('跳转至:$matchStr');
Get.find<VideoDetailController>(
tag: Get.arguments['heroTag'])
.plPlayerController
.seekTo(Duration(seconds: Utils.duration(matchStr)),
type: 'slider');
} catch (e) {
SmartDialog.showToast('跳转失败: $e');
}
}
},
recognizer: isValid
? (TapGestureRecognizer()
..onTap = () {
// 跳转到指定位置
if (isVideoPage) {
try {
SmartDialog.showToast('跳转至:$matchStr');
Get.find<VideoDetailController>(
tag: Get.arguments['heroTag'])
.plPlayerController
.seekTo(
Duration(seconds: Utils.duration(matchStr)),
type: 'slider');
} catch (e) {
SmartDialog.showToast('跳转失败: $e');
}
}
})
: null,
),
);
} else {

View File

@@ -299,7 +299,6 @@ class ReplyItemGrpc extends StatelessWidget {
null,
textPainter,
didExceedMaxLines,
getTag,
),
],
),
@@ -531,7 +530,6 @@ class ReplyItemGrpc extends StatelessWidget {
replyItem,
null,
null,
getTag,
),
],
),
@@ -589,7 +587,6 @@ class ReplyItemGrpc extends StatelessWidget {
fReplyItem,
textPainter,
didExceedMaxLines,
getTag,
) {
final String routePath = Get.currentRoute;
bool isVideoPage = routePath.startsWith('/video');
@@ -665,7 +662,7 @@ class ReplyItemGrpc extends StatelessWidget {
if (patternStr.isNotEmpty) {
patternStr += "|";
}
patternStr += r'(\b(?:\d+[:])?[0-5]?[0-9][:][0-5]?[0-9]\b)';
patternStr += r'(\b(?:\d+[:])?\d+[:]\d+\b)';
if (jumpUrlKeysList.isNotEmpty) {
patternStr += '|${jumpUrlKeysList.map(RegExp.escape).join('|')}';
}
@@ -723,8 +720,7 @@ class ReplyItemGrpc extends StatelessWidget {
},
),
);
} else if (RegExp(r'^\b(?:\d+[:])?[0-5]?[0-9][:][0-5]?[0-9]\b$')
.hasMatch(matchStr)) {
} else if (RegExp(r'^\b(?:\d+[:])?\d+[:]\d+\b$').hasMatch(matchStr)) {
matchStr = matchStr.replaceAll('', ':');
bool isValid = false;
try {