opt gesture

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-01-20 14:04:44 +08:00
parent 33278a74b2
commit bd97f9a500
12 changed files with 78 additions and 75 deletions

View File

@@ -5,53 +5,60 @@ class ImmediateTapGestureRecognizer extends OneSequenceGestureRecognizer {
ImmediateTapGestureRecognizer({
super.debugOwner,
super.supportedDevices,
super.allowedButtonsFilter,
super.allowedButtonsFilter = _defaultButtonAcceptBehavior,
this.onTapDown,
required this.onTapUp,
this.onTapUp,
this.onTapCancel,
this.onTap,
});
static bool _defaultButtonAcceptBehavior(int buttons) =>
buttons == kPrimaryButton;
GestureTapDownCallback? onTapDown;
final GestureTapUpCallback onTapUp;
GestureTapUpCallback? onTapUp;
final GestureTapCancelCallback? onTapCancel;
GestureTapCancelCallback? onTapCancel;
final GestureTapCallback? onTap;
GestureTapCallback? onTap;
PointerUpEvent? _up;
int _activePointer = 0;
int? _activePointer;
bool _sentTapDown = false;
bool _wonArena = false;
Offset? _initialPosition;
@override
bool isPointerPanZoomAllowed(PointerPanZoomStartEvent event) => false;
@override
bool isPointerAllowed(PointerDownEvent event) =>
_activePointer == 0 && super.isPointerAllowed(event);
_activePointer == null && super.isPointerAllowed(event);
@override
void addAllowedPointer(PointerDownEvent event) {
super.addAllowedPointer(event);
_reset(event.pointer);
_handleTapDown(event);
_initialPosition = event.position;
}
@override
void handleEvent(PointerEvent event) {
if (event.pointer != _activePointer) {
resolvePointer(event.pointer, GestureDisposition.rejected);
stopTrackingPointer(event.pointer);
return;
}
if (event is PointerDownEvent) {
_handleTapDown(event);
} else if (event is PointerMoveEvent) {
if (event is PointerMoveEvent) {
_handlePointerMove(event);
} else if (event is PointerUpEvent) {
_up = event;
_handlePointerUp(event);
} else if (event is PointerCancelEvent) {
resolve(GestureDisposition.rejected);
}
stopTrackingIfPointerNoLongerDown(event);
@@ -59,9 +66,9 @@ class ImmediateTapGestureRecognizer extends OneSequenceGestureRecognizer {
void _handleTapDown(PointerDownEvent event) {
if (_sentTapDown) return;
_sentTapDown = true;
if (onTapDown != null) {
_sentTapDown = true;
final details = TapDownDetails(
globalPosition: event.position,
localPosition: event.localPosition,
@@ -72,8 +79,8 @@ class ImmediateTapGestureRecognizer extends OneSequenceGestureRecognizer {
}
void _handlePointerMove(PointerMoveEvent event) {
if (event.delta.distanceSquared > 2.0) {
_cancelGesture('pointer moved');
if ((event.position - _initialPosition!).distance > 2.0) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(event.pointer);
}
}
@@ -85,12 +92,14 @@ class ImmediateTapGestureRecognizer extends OneSequenceGestureRecognizer {
}
void _handleTapUp(PointerUpEvent event) {
final details = TapUpDetails(
globalPosition: event.position,
localPosition: event.localPosition,
kind: event.kind,
);
invokeCallback<void>('onTapUp', () => onTapUp(details));
if (onTapUp != null) {
final details = TapUpDetails(
globalPosition: event.position,
localPosition: event.localPosition,
kind: event.kind,
);
invokeCallback<void>('onTapUp', () => onTapUp!(details));
}
if (onTap != null) {
invokeCallback<void>('onTap', onTap!);
@@ -106,7 +115,7 @@ class ImmediateTapGestureRecognizer extends OneSequenceGestureRecognizer {
_reset();
}
void _reset([int pointer = 0]) {
void _reset([int? pointer]) {
_activePointer = pointer;
_up = null;
_sentTapDown = false;
@@ -138,13 +147,7 @@ class ImmediateTapGestureRecognizer extends OneSequenceGestureRecognizer {
@override
void didStopTrackingLastPointer(int pointer) {
// wait for arena
}
@override
void dispose() {
_cancelGesture('disposed');
super.dispose();
_initialPosition = null;
}
@override

View File

@@ -1,5 +1,6 @@
import 'dart:math' as math;
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/cached_network_svg_image.dart';
import 'package:PiliPlus/common/widgets/image/custom_grid_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
@@ -18,7 +19,6 @@ import 'package:PiliPlus/utils/image_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_navigation/src/extension_navigation.dart';
@@ -69,7 +69,7 @@ class OpusContent extends StatelessWidget {
? null
: colorScheme.primary,
),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
switch (rich.type) {
case 'RICH_TEXT_NODE_TYPE_AT':
@@ -293,7 +293,7 @@ class OpusContent extends StatelessWidget {
return TextSpan(
text: '${hasUrl ? '\u{1F517}' : ''}$text',
recognizer: hasUrl
? (TapGestureRecognizer()
? (ImmediateTapGestureRecognizer()
..onTap = () =>
PiliScheme.routePushFromUrl(jumpUrl))
: null,

View File

@@ -3,6 +3,7 @@ import 'dart:math' show min;
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart';
import 'package:PiliPlus/grpc/bilibili/app/listener/v1.pb.dart';
@@ -24,7 +25,6 @@ import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/gestures.dart' show TapGestureRecognizer;
import 'package:flutter/material.dart' hide DraggableScrollableSheet;
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
@@ -919,7 +919,7 @@ class _AudioPageState extends State<AudioPage> {
TextSpan(
text: audioItem.arc.displayedOid,
style: TextStyle(color: colorScheme.secondary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => Utils.copyText(
audioItem.arc.displayedOid,
),

View File

@@ -1,5 +1,6 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/flutter/dyn/ink_well.dart';
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/http/dynamics.dart';
import 'package:PiliPlus/http/loading_state.dart';
@@ -8,7 +9,6 @@ import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/num_utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart' hide InkWell;
import 'package:get/get.dart';
@@ -125,7 +125,7 @@ Widget addWidget(
),
recognizer: reserve.desc3!.jumpUrl == null
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTap = () {
Get.toNamed(
'/webview',
@@ -261,7 +261,7 @@ Widget addWidget(
),
recognizer: content.desc!.jumpUrl == null
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTap = () {
Get.toNamed(
'/webview',

View File

@@ -1,6 +1,6 @@
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get_core/src/get_main.dart';
@@ -78,7 +78,7 @@ Widget _item(
? null
: TextStyle(color: theme.colorScheme.onSurfaceVariant),
recognizer: isAt
? (TapGestureRecognizer()
? (ImmediateTapGestureRecognizer()
..onTap = () => Get.toNamed('/member?mid=${e.rid}'))
: null,
);

View File

@@ -1,5 +1,6 @@
import 'dart:io' show Platform;
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/custom_grid_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/http/dynamics.dart';
@@ -12,7 +13,6 @@ import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -70,7 +70,7 @@ TextSpan? richNode(
TextSpan(
text: ' ${i.text}',
style: style,
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => Get.toNamed('/member?mid=${i.rid}'),
),
);
@@ -81,7 +81,7 @@ TextSpan? richNode(
TextSpan(
text: i.origText,
style: style,
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => Get.toNamed(
'/searchResult',
parameters: {
@@ -113,7 +113,7 @@ TextSpan? richNode(
style: style,
recognizer: i.origText == null
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTap = () => PageUtils.handleWebview(i.origText!)),
),
);
@@ -135,7 +135,7 @@ TextSpan? richNode(
TextSpan(
text: '投票:${i.text}',
style: style,
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
final dynIdStr = item.basic?.commentIdStr;
final dynId = dynIdStr != null
@@ -177,7 +177,7 @@ TextSpan? richNode(
TextSpan(
text: '${i.origText} ',
style: style,
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => Get.toNamed(
'/webview',
parameters: {
@@ -207,7 +207,7 @@ TextSpan? richNode(
style: style,
recognizer: i.jumpUrl == null
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTap = () => PageUtils.handleWebview(i.jumpUrl!)),
),
);
@@ -229,7 +229,7 @@ TextSpan? richNode(
TextSpan(
text: '${i.text} ',
style: style,
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () async {
try {
int? cid = await SearchHttp.ab2c(bvid: i.rid);
@@ -272,7 +272,7 @@ TextSpan? richNode(
TextSpan(
text: i.text,
style: style,
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
void onView(List<OpusPicModel> list) {
PageUtils.imageView(
@@ -328,7 +328,7 @@ TextSpan? richNode(
style: style,
recognizer: i.jumpUrl == null
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTap = () => PageUtils.handleWebview(i.jumpUrl!)),
),
);
@@ -340,7 +340,7 @@ TextSpan? richNode(
style: style,
recognizer: i.jumpUrl == null
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTap = () => PageUtils.handleWebview(i.jumpUrl!)),
),
);

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/flutter/popup_menu.dart';
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/http/live.dart';
import 'package:PiliPlus/models/common/image_type.dart';
@@ -11,7 +12,6 @@ import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -84,7 +84,7 @@ class LiveRoomChatPanel extends StatelessWidget {
),
recognizer: item.uid == 0
? null
: (TapGestureRecognizer()
: (ImmediateTapGestureRecognizer()
..onTapUp = (e) => _showMsgMenu(
context,
itemContext,
@@ -99,7 +99,7 @@ class LiveRoomChatPanel extends StatelessWidget {
color: primary,
fontSize: 14,
),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () =>
Get.toNamed('/member?mid=${reply.mid}'),
),

View File

@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/skeleton/msg_feed_sys_msg_.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/flutter/list_tile.dart';
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models_new/msg/msg_sys/data.dart';
@@ -10,7 +11,6 @@ import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -145,7 +145,7 @@ class _SysMsgPageState extends State<SysMsgPage> {
TextSpan(
text: match[1],
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
try {
PiliScheme.routePushFromUrl(url);
@@ -176,7 +176,7 @@ class _SysMsgPageState extends State<SysMsgPage> {
TextSpan(
text: match[3],
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
PiliScheme.videoPush(validAv, validBv);
},
@@ -195,7 +195,7 @@ class _SysMsgPageState extends State<SysMsgPage> {
TextSpan(
text: '查看动态',
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
PageUtils.pushDynFromId(id: dynId).catchError(
(err) => SmartDialog.showToast(err.toString()),
@@ -212,7 +212,7 @@ class _SysMsgPageState extends State<SysMsgPage> {
TextSpan(
text: '\u{1F517}网页链接',
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
PiliScheme.routePushFromUrl(matchStr);
},

View File

@@ -1,10 +1,10 @@
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/models_new/video/video_ai_conclusion/model_result.dart';
import 'package:PiliPlus/pages/common/slide/common_slide_page.dart';
import 'package:PiliPlus/pages/video/controller.dart';
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/selectable_text.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -99,7 +99,7 @@ class AiConclusionPanel extends CommonSlidePage {
)
: null,
recognizer: tap
? (TapGestureRecognizer()
? (ImmediateTapGestureRecognizer()
..onTap = () {
try {
Get.find<VideoDetailController>(

View File

@@ -1,5 +1,6 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
@@ -35,7 +36,6 @@ import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/request_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:expandable/expandable.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@@ -639,7 +639,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel> {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () async {
if (videoDetailCtr
.plPlayerController
@@ -702,7 +702,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel> {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => PiliScheme.videoPush(aid, null),
),
);
@@ -716,7 +716,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel> {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => PiliScheme.videoPush(null, matchStr),
),
);
@@ -728,7 +728,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel> {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
try {
Get.find<VideoDetailController>(
@@ -757,7 +757,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel> {
return TextSpan(
text: '@${currentDesc.rawText}',
style: TextStyle(color: colorSchemePrimary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => Get.toNamed('/member?mid=${currentDesc.bizId}'),
);
default:

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/dialog/report.dart';
import 'package:PiliPlus/common/widgets/flutter/text/text.dart' as custom_text;
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/custom_grid_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
@@ -33,7 +34,6 @@ import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -483,7 +483,7 @@ class ReplyItemGrpc extends StatelessWidget {
style: TextStyle(
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
feedBack();
Get.toNamed(
@@ -616,7 +616,7 @@ class ReplyItemGrpc extends StatelessWidget {
style: TextStyle(
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
if (url.appUrlSchema.isEmpty) {
if (RegExp(
@@ -695,7 +695,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () =>
Get.toNamed('/member?mid=${content.atNameToMid[name]}'),
),
@@ -705,7 +705,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: '投票: ${content.vote.title}',
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () =>
showVoteDialog(context, content.vote.id.toInt()),
),
@@ -730,7 +730,7 @@ class ReplyItemGrpc extends StatelessWidget {
? TextStyle(color: theme.colorScheme.primary)
: null,
recognizer: isValid
? (TapGestureRecognizer()
? (ImmediateTapGestureRecognizer()
..onTap = () {
// 跳转到指定位置
try {
@@ -761,7 +761,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () {
Get.toNamed(
'/searchResult',
@@ -775,7 +775,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: matchStr,
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => PageUtils.handleWebview(matchStr),
),
);
@@ -816,7 +816,7 @@ class ReplyItemGrpc extends StatelessWidget {
: theme.colorScheme.secondary,
),
recognizer: hasClickUrl
? (TapGestureRecognizer()
? (ImmediateTapGestureRecognizer()
..onTap = () =>
PageUtils.handleWebview(content.richText.note.clickUrl))
: null,

View File

@@ -3,6 +3,7 @@ import 'dart:math';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/grpc/bilibili/im/interfaces/v1.pb.dart'
show EmotionInfo;
@@ -19,7 +20,6 @@ import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/image_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -662,7 +662,7 @@ class ChatItem extends StatelessWidget {
TextSpan(
text: matchStr,
style: style.copyWith(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
recognizer: ImmediateTapGestureRecognizer()
..onTap = () => PiliScheme.routePushFromUrl(matchStr),
),
);