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/models/common/reply_type.dart';
import 'package:PiliPalaX/pages/common/reply_controller.dart'; import 'package:PiliPalaX/pages/common/reply_controller.dart';
import 'package:PiliPalaX/http/reply.dart'; import 'package:PiliPalaX/http/reply.dart';
import 'package:PiliPalaX/pages/video/detail/controller.dart';
import 'package:PiliPalaX/utils/global_data.dart'; import 'package:PiliPalaX/utils/global_data.dart';
import 'package:fixnum/fixnum.dart' as $fixnum; import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:get/get.dart';
class VideoReplyController extends ReplyController { class VideoReplyController extends ReplyController {
VideoReplyController( VideoReplyController(

View File

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

View File

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

View File

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