fix: 修正双击点赞与心形联动

This commit is contained in:
Zhou Weidong committed 2026-10-22 22:30:01 +08:00
1 parent 78d0166eb7
commit 68ccfa21c0
8 files changed
+200 -64

No files matched your search

+34 -10
View File
@@ -107,9 +107,12 @@ class HomeFeedOverlay extends StatefulWidget {
}
class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
static const Duration _singleTapDelay = Duration(milliseconds: 280);
bool _scrubbing = false;
bool _wasVisibleBeforeScrub = true;
Offset? _doubleTapPosition;
Timer? _singleTapTimer;
DateTime? _lastTapAt;
int _nextHeartBurstId = 0;
final List<({int id, Offset position})> _heartBursts = [];
@@ -121,6 +124,12 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
}
}
@override
void dispose() {
_singleTapTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
@@ -135,10 +144,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
child: GestureDetector(
key: const Key('home-feed-gesture'),
behavior: HitTestBehavior.opaque,
onTap: _handleSurfaceTap,
onDoubleTapDown: (details) =>
_doubleTapPosition = details.localPosition,
onDoubleTap: _handleDoubleTap,
onTapUp: _handleTapUp,
onLongPressStart: (details) =>
_handleLongPressStart(details, constraints.maxWidth),
onLongPressEnd: (_) => widget.onBoostEnd(),
@@ -242,13 +248,28 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
widget.onScrubEnd?.call(wasVisible);
}
void _handleSurfaceTap() {
widget.onTogglePlay();
void _handleTapUp(TapUpDetails details) {
final now = DateTime.now();
final lastTap = _lastTapAt;
if (_singleTapTimer != null &&
lastTap != null &&
now.difference(lastTap) <= _singleTapDelay) {
_singleTapTimer?.cancel();
_singleTapTimer = null;
_lastTapAt = null;
_showHearts(details.localPosition);
return;
}
_lastTapAt = now;
_singleTapTimer?.cancel();
_singleTapTimer = Timer(_singleTapDelay, () {
_singleTapTimer = null;
_lastTapAt = null;
if (mounted) widget.onTogglePlay();
});
}
void _handleDoubleTap() {
final position = _doubleTapPosition;
if (position == null) return;
void _showHearts(Offset position) {
final id = _nextHeartBurstId++;
setState(() => _heartBursts.add((id: id, position: position)));
widget.onDoubleTapLike?.call(position);
@@ -260,6 +281,9 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
}
void _handleLongPressStart(LongPressStartDetails details, double width) {
_singleTapTimer?.cancel();
_singleTapTimer = null;
_lastTapAt = null;
final third = width / 3;
final dx = details.localPosition.dx;
if (dx < third || dx > width - third) {
@@ -371,6 +371,9 @@ class HomeFeedActionRail extends StatelessWidget {
icon: liked
? Icons.favorite_rounded
: Icons.favorite_border_rounded,
iconColor: liked
? AppColors.doubleTapHeartRed
: AppColors.textPrimary,
label: likeCount == null
? l10n.like
: formatInteractionCount(likeCount!),
@@ -397,6 +400,7 @@ class HomeFeedActionRail extends StatelessWidget {
required String label,
required Key labelKey,
required VoidCallback onTap,
Color iconColor = AppColors.textPrimary,
double labelFontSize = 12,
}) {
return GestureDetector(
@@ -409,7 +413,7 @@ class HomeFeedActionRail extends StatelessWidget {
Icon(
icon,
size: _actionIcon,
color: AppColors.textPrimary,
color: iconColor,
shadows: const [
Shadow(
color: AppColors.shadowSoft,
@@ -19,6 +19,7 @@ class InteractionRailItem {
this.count,
this.countKey,
this.selected = false,
this.selectedColor = AppColors.blue,
});
final Key key;
@@ -28,6 +29,7 @@ class InteractionRailItem {
final int? count;
final Key? countKey;
final bool selected;
final Color selectedColor;
}
/// 播放页与首页 feed 共用的右侧互动栏:收藏/评论/喜欢/分享。
@@ -71,7 +73,7 @@ class _RailButton extends StatelessWidget {
width: _iconSize,
height: _iconSize,
fit: BoxFit.contain,
color: item.selected ? AppColors.blue : AppColors.onPrimary,
color: item.selected ? item.selectedColor : AppColors.onPrimary,
colorBlendMode: BlendMode.srcIn,
),
),
@@ -170,6 +170,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
count: data.likeCount,
countKey: const Key('player-rail-like-count'),
selected: data.liked,
selectedColor: AppColors.doubleTapHeartRed,
onTap: actions.onLike,
),
InteractionRailItem(