feat(flutter): 播放页互动数量与评论面板收紧
This commit is contained in:
1 parent
e39aa766ac
commit
bed6bbb75b
13 files changed
+265
-59
No files matched your search
@@ -106,9 +106,57 @@ void main() {
|
||||
find.byKey(const Key('comment-input')),
|
||||
);
|
||||
expect(field.controller?.text, 'blocked text');
|
||||
// 发送失败时保留输入与焦点,用户可以直接改完再发。
|
||||
expect(field.focusNode?.hasFocus, isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('should_unfocus_input_after_successful_post', (tester) async {
|
||||
final repository = FakeCommentRepository(
|
||||
pages: [const CommentPage()],
|
||||
publishResult: commentFixture(id: '11', content: 'Nice demo', mine: true),
|
||||
);
|
||||
|
||||
await _pumpSheet(tester, repository: repository);
|
||||
final input = find.byKey(const Key('comment-input'));
|
||||
await tester.tap(input);
|
||||
await tester.pump();
|
||||
expect(tester.widget<TextField>(input).focusNode?.hasFocus, isTrue);
|
||||
await tester.enterText(input, 'Nice demo');
|
||||
await tester.tap(find.byKey(const Key('comment-post')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(tester.widget<TextField>(input).focusNode?.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('should_use_compact_comment_sizes', (tester) async {
|
||||
final repository = FakeCommentRepository(
|
||||
pages: [
|
||||
CommentPage(
|
||||
comments: [commentFixture(id: '10', content: 'Great episode')],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await _pumpSheet(tester, repository: repository);
|
||||
|
||||
expect(
|
||||
tester.getSize(find.byKey(const Key('comment-post'))),
|
||||
const Size(32, 32),
|
||||
);
|
||||
expect(tester.getSize(find.byKey(const Key('comment-input'))).height, 40);
|
||||
final avatar = tester.widget<CircleAvatar>(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('comment-item-10')),
|
||||
matching: find.byType(CircleAvatar),
|
||||
),
|
||||
);
|
||||
expect(avatar.radius, 14);
|
||||
final body = tester.widget<Text>(find.text('Great episode'));
|
||||
expect(body.style?.fontSize, 13);
|
||||
expect(body.style?.height, 1.2);
|
||||
});
|
||||
|
||||
testWidgets('should_show_review_badge_and_server_replaced_content', (
|
||||
tester,
|
||||
) async {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/core/formatting/count_format.dart';
|
||||
|
||||
void main() {
|
||||
test('should_keep_raw_number_below_ten_thousand', () {
|
||||
expect(formatInteractionCount(0), '0');
|
||||
expect(formatInteractionCount(96), '96');
|
||||
expect(formatInteractionCount(9999), '9999');
|
||||
});
|
||||
|
||||
test('should_use_one_decimal_wan_from_ten_thousand', () {
|
||||
expect(formatInteractionCount(10000), '1.0万');
|
||||
expect(formatInteractionCount(12400), '1.2万');
|
||||
expect(formatInteractionCount(123456), '12.3万');
|
||||
});
|
||||
}
|
||||
@@ -46,10 +46,18 @@ void main() {
|
||||
});
|
||||
|
||||
test('should_parse_view_count_when_backend_sends_number', () {
|
||||
final drama = Drama.fromCardJson({'id': 5, 'title': 'T', 'viewCount': 1200});
|
||||
final drama = Drama.fromCardJson({
|
||||
'id': 5,
|
||||
'title': 'T',
|
||||
'viewCount': 1200,
|
||||
});
|
||||
|
||||
expect(drama.id, '5');
|
||||
expect(drama.viewCount, 1200);
|
||||
// 卡片没有互动数量时保持未知,界面才回退到文字标签。
|
||||
expect(drama.likeCount, isNull);
|
||||
expect(drama.favoriteCount, isNull);
|
||||
expect(drama.commentCount, isNull);
|
||||
});
|
||||
|
||||
test('should_parse_detail_payload_when_ids_are_strings', () {
|
||||
@@ -59,14 +67,25 @@ void main() {
|
||||
'totalEpisodes': 12,
|
||||
'freeEpisodes': 3,
|
||||
'viewCount': '99',
|
||||
'likeCount': '12400',
|
||||
'favoriteCount': '3200',
|
||||
'commentCount': '96',
|
||||
'episodes': [
|
||||
{'id': '2111012753262120963', 'number': 1, 'title': 'E1', 'isFree': true},
|
||||
{
|
||||
'id': '2111012753262120963',
|
||||
'number': 1,
|
||||
'title': 'E1',
|
||||
'isFree': true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(drama.id, '2111012753262120962');
|
||||
expect(drama.freeEpisodes, 3);
|
||||
expect(drama.viewCount, 99);
|
||||
expect(drama.likeCount, 12400);
|
||||
expect(drama.favoriteCount, 3200);
|
||||
expect(drama.commentCount, 96);
|
||||
expect(drama.episodes.first.id, '2111012753262120963');
|
||||
expect(drama.episodes.first.number, 1);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:shared_preferences_platform_interface/shared_preferences_async_p
|
||||
|
||||
import 'package:fruitshorts/app.dart';
|
||||
import 'package:fruitshorts/core/data/models/drama.dart';
|
||||
import 'package:fruitshorts/core/data/models/interaction.dart';
|
||||
import 'package:fruitshorts/core/data/models/play_ticket.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||
@@ -285,6 +286,43 @@ void main() {
|
||||
expect(find.byKey(const Key('player-interaction-rail')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_show_rail_counts_from_detail_and_follow_server_results', (
|
||||
tester,
|
||||
) async {
|
||||
SharedPreferencesAsyncPlatform.instance =
|
||||
InMemorySharedPreferencesAsync.withData({
|
||||
'auth.accessToken': 'test-access',
|
||||
'auth.refreshToken': 'test-refresh',
|
||||
'auth.user': '{"uid":"9","nickname":"Me","avatarUrl":""}',
|
||||
});
|
||||
await _pumpApp(
|
||||
tester,
|
||||
interactions: FakeInteractionRepository(
|
||||
nextLikeResult: const LikeToggleResult(liked: true, count: 23000),
|
||||
),
|
||||
);
|
||||
await _openSeriesPlayer(tester);
|
||||
|
||||
String railLabel(Key key) => tester
|
||||
.widget<Text>(
|
||||
find.descendant(of: find.byKey(key), matching: find.byType(Text)),
|
||||
)
|
||||
.data!;
|
||||
expect(railLabel(const Key('player-rail-like')), '1.2万');
|
||||
expect(railLabel(const Key('player-rail-save')), '3200');
|
||||
expect(railLabel(const Key('player-rail-comments')), '96');
|
||||
// 分享没有数量,仍是文字标签。
|
||||
expect(railLabel(const Key('player-rail-share')), 'Share');
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-rail-like')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(railLabel(const Key('player-rail-like')), '2.3万');
|
||||
|
||||
await tester.tap(find.byKey(const Key('player-rail-save')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(railLabel(const Key('player-rail-save')), '3201');
|
||||
});
|
||||
|
||||
testWidgets('should_toggle_synopsis_with_inline_text_button', (tester) async {
|
||||
await _pumpApp(tester);
|
||||
await _openSeriesPlayer(tester);
|
||||
@@ -784,6 +822,7 @@ Future<void> _pumpApp(
|
||||
Size size = const Size(390, 844),
|
||||
FakeCatalogRepository? catalog,
|
||||
FakePlaybackRepository? playback,
|
||||
FakeInteractionRepository? interactions,
|
||||
}) async {
|
||||
tester.view.physicalSize = size;
|
||||
tester.view.devicePixelRatio = 1;
|
||||
@@ -799,7 +838,7 @@ Future<void> _pumpApp(
|
||||
favoriteRepository: InMemoryFavoriteRepository(cards: repository.dramas),
|
||||
playbackRepository: playback ?? FakePlaybackRepository(),
|
||||
commentRepository: FakeCommentRepository(),
|
||||
interactionRepository: FakeInteractionRepository(),
|
||||
interactionRepository: interactions ?? FakeInteractionRepository(),
|
||||
noticeRepository: FakeNoticeRepository(),
|
||||
haptics: FakeHaptics(),
|
||||
),
|
||||
|
||||
@@ -50,27 +50,40 @@ final List<Drama> demoDramas = [
|
||||
'City Lights & Velvet Nights',
|
||||
'Urban Romance',
|
||||
format: 8,
|
||||
likeCount: 12400,
|
||||
favoriteCount: 3200,
|
||||
commentCount: 96,
|
||||
),
|
||||
_drama('vengeance-demo', 'Vengeance Rising', 'Action · Thriller', format: 15),
|
||||
];
|
||||
|
||||
Drama _drama(String id, String title, String genre, {required int format}) =>
|
||||
Drama(
|
||||
id: id,
|
||||
title: title,
|
||||
synopsis: '$title synopsis',
|
||||
posterUrl: '/files/$id.png',
|
||||
genre: genre,
|
||||
language: 'id',
|
||||
detailLoaded: true,
|
||||
episodes: [
|
||||
for (var index = 0; index < 7; index++)
|
||||
Episode(
|
||||
id: '$id-${index + 1}',
|
||||
number: index + 1,
|
||||
title: 'Episode ${index + 1}',
|
||||
isFree: true,
|
||||
videoUrl: 'https://example.test/$format-$index.mp4',
|
||||
),
|
||||
],
|
||||
);
|
||||
Drama _drama(
|
||||
String id,
|
||||
String title,
|
||||
String genre, {
|
||||
required int format,
|
||||
int? likeCount,
|
||||
int? favoriteCount,
|
||||
int? commentCount,
|
||||
}) => Drama(
|
||||
id: id,
|
||||
title: title,
|
||||
synopsis: '$title synopsis',
|
||||
posterUrl: '/files/$id.png',
|
||||
genre: genre,
|
||||
language: 'id',
|
||||
detailLoaded: true,
|
||||
likeCount: likeCount,
|
||||
favoriteCount: favoriteCount,
|
||||
commentCount: commentCount,
|
||||
episodes: [
|
||||
for (var index = 0; index < 7; index++)
|
||||
Episode(
|
||||
id: '$id-${index + 1}',
|
||||
number: index + 1,
|
||||
title: 'Episode ${index + 1}',
|
||||
isFree: true,
|
||||
videoUrl: 'https://example.test/$format-$index.mp4',
|
||||
),
|
||||
],
|
||||
);
|
||||
Reference in new issue
Block a user