chore(release): 发布 v1.0.1 客户端 UI 优化
flutter-ci / test (push) Canceled after 0s

This commit is contained in:
Zhou Weidong committed 2026-10-31 14:39:52 +08:00
commit c4adbd0665
12 files changed
+585 -71

No files matched your search

+17 -14
View File
@@ -11,6 +11,7 @@ import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart
import 'package:fruitshorts/core/theme/app_colors.dart';
import 'package:fruitshorts/core/theme/app_dimens.dart';
import 'package:fruitshorts/core/widgets/app_bottom_nav.dart';
import 'package:fruitshorts/core/widgets/root_nav_glyph.dart';
import 'package:fruitshorts/pages/following/following_page.dart';
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
@@ -138,18 +139,20 @@ void main() {
.duration,
lessThanOrEqualTo(const Duration(milliseconds: 200)),
);
final selectedHomeIcon = tester.widget<Icon>(
final selectedHomeIcon = tester.widget<RootNavGlyph>(
find.descendant(
of: find.byKey(const Key('tab-home')),
matching: find.byIcon(Icons.home_rounded),
matching: find.byType(RootNavGlyph),
),
);
expect(selectedHomeIcon.color, AppColors.navSelected);
expect(selectedHomeIcon.kind, RootNavGlyphKind.home);
expect(selectedHomeIcon.selected, isTrue);
expect(selectedHomeIcon.size, AppDimens.navIcon);
expect(
tester.getSize(
find.descendant(
of: find.byKey(const Key('tab-home')),
matching: find.byIcon(Icons.home_rounded),
matching: find.byType(RootNavGlyph),
),
),
const Size.square(AppDimens.navIcon),
@@ -157,21 +160,21 @@ void main() {
expect(
find.descendant(
of: find.byKey(const Key('tab-recommend')),
matching: find.byIcon(Icons.smart_display_outlined),
matching: find.byType(RootNavGlyph),
),
findsOneWidget,
);
expect(
find.descendant(
of: find.byKey(const Key('tab-follow')),
matching: find.byIcon(Icons.bookmark_border_rounded),
matching: find.byType(RootNavGlyph),
),
findsOneWidget,
);
expect(
find.descendant(
of: find.byKey(const Key('tab-mine')),
matching: find.byIcon(Icons.person_outline_rounded),
matching: find.byType(RootNavGlyph),
),
findsOneWidget,
);
@@ -188,7 +191,7 @@ void main() {
expect(
find.descendant(
of: find.byKey(const Key('tab-recommend')),
matching: find.byIcon(Icons.smart_display_rounded),
matching: find.byType(RootNavGlyph),
),
findsOneWidget,
);
@@ -219,20 +222,20 @@ void main() {
expect(
find.descendant(
of: find.byKey(const Key('tab-home')),
matching: find.byIcon(Icons.home_outlined),
matching: find.byType(RootNavGlyph),
),
findsOneWidget,
);
expect(
tester
.widget<Icon>(
.widget<RootNavGlyph>(
find.descendant(
of: find.byKey(const Key('tab-home')),
matching: find.byIcon(Icons.home_outlined),
matching: find.byType(RootNavGlyph),
),
)
.color,
AppColors.navUnselected,
.selected,
isFalse,
);
});
@@ -270,7 +273,7 @@ void main() {
expect(
find.descendant(
of: find.byKey(const Key('tab-follow')),
matching: find.byIcon(Icons.bookmark_rounded),
matching: find.byType(RootNavGlyph),
),
findsOneWidget,
);
+38
View File
@@ -0,0 +1,38 @@
// Author: fruit.com.cn
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/core/widgets/app_root_tab.dart';
import 'package:fruitshorts/core/widgets/root_nav_glyph.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
void main() {
testWidgets(
'should_render_four_ordered_glyphs_with_home_selected_when_root_nav_builds',
(tester) async {
await tester.pumpWidget(
MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: Scaffold(
bottomNavigationBar: AppRootBottomNav(
selected: AppRootTab.home,
onSelected: (_) {},
),
),
),
);
final glyphs = tester
.widgetList<RootNavGlyph>(find.byType(RootNavGlyph))
.toList();
expect(glyphs.map((glyph) => glyph.kind), RootNavGlyphKind.values);
expect(glyphs.map((glyph) => glyph.selected), [
true,
false,
false,
false,
]);
},
);
}
+15 -12
View File
@@ -313,7 +313,7 @@ void main() {
.first;
expect(loadingOverlay, findsOneWidget);
expect(tester.widget<IgnorePointer>(loadingOverlay).ignoring, isTrue);
expect(tester.getSize(loadingOverlay), const Size(40, 40));
expect(tester.getSize(loadingOverlay), const Size(56, 36));
expect(
tester
.widget<AnimatedOpacity>(
@@ -327,26 +327,29 @@ void main() {
);
expect(
tester.getSize(find.byKey(const Key('player-loading-surface'))),
const Size(40, 40),
const Size(56, 36),
);
expect(
tester.getSize(find.byKey(const Key('player-entry-loading'))),
const Size(20, 20),
const Size(48, 29),
);
expect(
tester
.widget<CircularProgressIndicator>(
find.byKey(const Key('player-entry-loading')),
)
.color,
Colors.white,
find.descendant(
of: loadingOverlay,
matching: find.byType(CircularProgressIndicator),
),
findsNothing,
);
expect(find.text('Loading'), findsNothing);
expect(find.byKey(const Key('player-entry-loading-track')), findsNothing);
expect(
find.byKey(const Key('player-entry-loading-highlight')),
findsNothing,
);
final loadingSurface = tester.widget<Container>(
find.byKey(const Key('player-loading-surface')),
);
final decoration = loadingSurface.decoration! as BoxDecoration;
expect(decoration.color, AppColors.refreshIndicatorSurface);
expect(decoration.borderRadius, BorderRadius.circular(20));
expect(loadingSurface.decoration, isNull);
expect(
find.descendant(of: loadingOverlay, matching: find.byType(ColoredBox)),
findsNothing,
@@ -0,0 +1,73 @@
// Author: fruit.com.cn
// 职责:验证剧集播放页 YMB 入场 loading 的品牌视觉、运动和减少动画行为。
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/player/widgets/player_loading_overlay.dart';
const _surface = Key('player-loading-surface');
const _logo = Key('player-entry-loading');
const _motion = Key('player-entry-loading-motion');
void main() {
testWidgets('should_show_ymb_motion_without_circular_spinner', (
tester,
) async {
await _pump(tester);
expect(find.byType(CircularProgressIndicator), findsNothing);
expect(find.byKey(_surface), findsOneWidget);
expect(find.byKey(_logo), findsOneWidget);
expect(find.text('Loading'), findsNothing);
expect(find.byKey(const Key('player-entry-loading-track')), findsNothing);
expect(
find.byKey(const Key('player-entry-loading-highlight')),
findsNothing,
);
expect(find.byType(ShaderMask), findsOneWidget);
expect(tester.getSize(find.byKey(_surface)), const Size(56, 36));
expect(tester.getSize(find.byKey(_logo)), const Size(48, 29));
expect(tester.widget<Container>(find.byKey(_surface)).decoration, isNull);
final initialScale = _scaleOf(tester);
await tester.pump(const Duration(milliseconds: 300));
expect(_scaleOf(tester), isNot(initialScale));
});
testWidgets('should_keep_loading_static_when_motion_is_disabled', (
tester,
) async {
await _pump(tester, disableAnimations: true);
final initialScale = _scaleOf(tester);
await tester.pump(const Duration(milliseconds: 300));
expect(_scaleOf(tester), initialScale);
expect(find.byKey(_logo), findsOneWidget);
expect(find.text('Loading'), findsNothing);
});
}
double _scaleOf(WidgetTester tester) {
return tester.widget<Transform>(find.byKey(_motion)).transform.storage.first;
}
Future<void> _pump(
WidgetTester tester, {
bool disableAnimations = false,
}) async {
await tester.pumpWidget(
MaterialApp(
locale: const Locale('en'),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: MediaQuery(
data: MediaQueryData(disableAnimations: disableAnimations),
child: Scaffold(
body: Center(
child: PlayerLoadingOverlay(opacity: 1, onFadeEnd: () {}),
),
),
),
),
);
}