fix: 修正双击点赞与心形联动
This commit is contained in:
1 parent
78d0166eb7
commit
68ccfa21c0
8 files changed
+200
-64
No files matched your search
@@ -0,0 +1,142 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/core/data/services/interaction_controller.dart';
|
||||
import 'package:fruitshorts/core/theme/app_theme.dart';
|
||||
import 'package:fruitshorts/l10n/app_localizations.dart';
|
||||
import 'package:fruitshorts/pages/player/widgets/home_feed_overlay.dart';
|
||||
|
||||
import '../support/fake_catalog.dart';
|
||||
import '../support/fake_haptics.dart';
|
||||
import '../support/fake_interaction_repositories.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('quick double tap likes without pausing', (tester) async {
|
||||
final repository = FakeInteractionRepository();
|
||||
final haptics = FakeHaptics();
|
||||
final key = GlobalKey<_HarnessState>();
|
||||
await _pumpHarness(tester, repository, haptics, key);
|
||||
|
||||
final gesture = find.byKey(const Key('home-feed-gesture'));
|
||||
final center = tester.getCenter(gesture);
|
||||
|
||||
await tester.tapAt(center);
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
await tester.tapAt(center);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(key.currentState!.pauseToggles, 0);
|
||||
expect(repository.likeTargets, hasLength(1));
|
||||
expect(haptics.lightImpacts, 1);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('rail-like')),
|
||||
matching: find.byIcon(Icons.favorite_rounded),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('single tap toggles playback after 280ms', (tester) async {
|
||||
final key = GlobalKey<_HarnessState>();
|
||||
await _pumpHarness(tester, FakeInteractionRepository(), FakeHaptics(), key);
|
||||
|
||||
await tester.tapAt(
|
||||
tester.getCenter(find.byKey(const Key('home-feed-gesture'))),
|
||||
);
|
||||
await tester.pump(const Duration(milliseconds: 279));
|
||||
expect(key.currentState!.pauseToggles, 0);
|
||||
|
||||
await tester.pump(const Duration(milliseconds: 2));
|
||||
expect(key.currentState!.pauseToggles, 1);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _pumpHarness(
|
||||
WidgetTester tester,
|
||||
FakeInteractionRepository repository,
|
||||
FakeHaptics haptics,
|
||||
GlobalKey<_HarnessState> key,
|
||||
) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: AppTheme.dark(),
|
||||
locale: const Locale('en'),
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
home: _Harness(key: key, repository: repository, haptics: haptics),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
class _Harness extends StatefulWidget {
|
||||
const _Harness({super.key, required this.repository, required this.haptics});
|
||||
|
||||
final FakeInteractionRepository repository;
|
||||
final FakeHaptics haptics;
|
||||
|
||||
@override
|
||||
State<_Harness> createState() => _HarnessState();
|
||||
}
|
||||
|
||||
class _HarnessState extends State<_Harness> {
|
||||
late final InteractionController interactions = InteractionController(
|
||||
widget.repository,
|
||||
);
|
||||
int pauseToggles = 0;
|
||||
|
||||
Future<void> _like({bool likeOnly = false}) async {
|
||||
await widget.haptics.lightImpact();
|
||||
final episodeId = demoDramas.first.episodes.first.id;
|
||||
if (interactions.isEpisodeBusy(episodeId) ||
|
||||
(likeOnly && interactions.isEpisodeLiked(episodeId))) {
|
||||
return;
|
||||
}
|
||||
await interactions.toggleEpisodeLike(episodeId);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
interactions.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
body: ListenableBuilder(
|
||||
listenable: interactions,
|
||||
builder: (context, _) {
|
||||
final episode = demoDramas.first.episodes.first;
|
||||
return HomeFeedOverlay(
|
||||
l10n: l10n,
|
||||
drama: demoDramas.first,
|
||||
episode: episode,
|
||||
controller: null,
|
||||
locked: false,
|
||||
liked: interactions.isEpisodeLiked(episode.id),
|
||||
likeCount: interactions.episodeLikeCount(episode.id),
|
||||
saved: false,
|
||||
visible: true,
|
||||
boosting: false,
|
||||
onLike: () => _like(),
|
||||
onDoubleTapLike: (_) => _like(likeOnly: true),
|
||||
onSave: () {},
|
||||
onComments: () {},
|
||||
onShare: () {},
|
||||
onDetail: () {},
|
||||
onOpenFullPlayer: () {},
|
||||
onTogglePlay: () => setState(() => pauseToggles++),
|
||||
onBoostStart: () {},
|
||||
onBoostEnd: () {},
|
||||
onMore: () {},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user