Compare commits

..

3 Commits

Author SHA1 Message Date
7ac04707cc mod: 评论b23.tv链接匹配 issue 2024-04-01 23:55:35 +08:00
22e1163b28 fix: 评论投票message重复 2024-03-24 10:59:00 +08:00
ba78b20bfa Merge branch 'main' into feature-replyJumpUrl 2024-03-24 10:49:36 +08:00
2 changed files with 69 additions and 18 deletions

View File

@ -148,14 +148,35 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
floating: true, floating: true,
delegate: _MySliverPersistentHeaderDelegate( delegate: _MySliverPersistentHeaderDelegate(
child: Container( child: Container(
height: 40, height: 45,
padding: const EdgeInsets.fromLTRB(12, 6, 6, 0), padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
border: Border(
bottom: BorderSide(
color: Theme.of(context)
.colorScheme
.outline
.withOpacity(0.1)),
),
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Obx(
'${_videoReplyController.sortTypeLabel.value}评论', () => AnimatedSwitcher(
style: const TextStyle(fontSize: 13), duration: const Duration(milliseconds: 400),
transitionBuilder:
(Widget child, Animation<double> animation) {
return ScaleTransition(
scale: animation, child: child);
},
child: Text(
'${_videoReplyController.count.value}条回复',
key: ValueKey<int>(
_videoReplyController.count.value),
),
),
), ),
SizedBox( SizedBox(
height: 35, height: 35,
@ -163,12 +184,10 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
onPressed: () => onPressed: () =>
_videoReplyController.queryBySort(), _videoReplyController.queryBySort(),
icon: const Icon(Icons.sort, size: 16), icon: const Icon(Icons.sort, size: 16),
label: Obx( label: Obx(() => Text(
() => Text( _videoReplyController.sortTypeLabel.value,
_videoReplyController.sortTypeLabel.value, style: const TextStyle(fontSize: 13),
style: const TextStyle(fontSize: 13), )),
),
),
), ),
) )
], ],
@ -310,8 +329,8 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
class _MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate { class _MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
_MySliverPersistentHeaderDelegate({required this.child}); _MySliverPersistentHeaderDelegate({required this.child});
final double _minExtent = 40; final double _minExtent = 45;
final double _maxExtent = 40; final double _maxExtent = 45;
final Widget child; final Widget child;
@override @override

View File

@ -498,7 +498,7 @@ InlineSpan buildContent(
return str; return str;
}); });
} }
// content.message = content.message.replaceAll(RegExp(r"\{vote:.*?\}"), ' '); content.message = content.message.replaceAll(RegExp(r"\{vote:.*?\}"), ' ');
content.message = content.message content.message = content.message
.replaceAll('&amp;', '&') .replaceAll('&amp;', '&')
.replaceAll('&lt;', '<') .replaceAll('&lt;', '<')
@ -525,14 +525,18 @@ InlineSpan buildContent(
if (jumpUrlKeysList.isNotEmpty) { if (jumpUrlKeysList.isNotEmpty) {
patternStr += '|${jumpUrlKeysList.join('|')}'; patternStr += '|${jumpUrlKeysList.join('|')}';
} }
RegExp bv23Regex = RegExp(r'https://b23\.tv/[a-zA-Z0-9]{7}');
final RegExp pattern = RegExp(patternStr); final RegExp pattern = RegExp(patternStr);
List<String> matchedStrs = []; List<String> matchedStrs = [];
void addPlainTextSpan(str) { void addPlainTextSpan(str) {
spanChilds.add(TextSpan( spanChilds.add(
TextSpan(
text: str, text: str,
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
..onTap = () => ..onTap = () =>
replyReply?.call(replyItem.root == 0 ? replyItem : fReplyItem))); replyReply?.call(replyItem.root == 0 ? replyItem : fReplyItem),
),
);
} }
// 分割文本并处理每个部分 // 分割文本并处理每个部分
@ -734,8 +738,36 @@ InlineSpan buildContent(
return ''; return '';
}, },
onNonMatch: (String nonMatchStr) { onNonMatch: (String nonMatchStr) {
addPlainTextSpan(nonMatchStr); return nonMatchStr.splitMapJoin(
return nonMatchStr; bv23Regex,
onMatch: (Match match) {
String matchStr = match[0]!;
spanChilds.add(
TextSpan(
text: ' $matchStr ',
style: isVideoPage
? TextStyle(
color: Theme.of(context).colorScheme.primary,
)
: null,
recognizer: TapGestureRecognizer()
..onTap = () => Get.toNamed(
'/webview',
parameters: {
'url': matchStr,
'type': 'url',
'pageTitle': matchStr
},
),
),
);
return '';
},
onNonMatch: (String nonMatchOtherStr) {
addPlainTextSpan(nonMatchOtherStr);
return nonMatchOtherStr;
},
);
}, },
); );