diff --git a/client/lib/widgets/auth_screen.dart b/client/lib/widgets/auth_screen.dart index f22d061..097e1bd 100644 --- a/client/lib/widgets/auth_screen.dart +++ b/client/lib/widgets/auth_screen.dart @@ -154,6 +154,9 @@ class _AuthScreenState extends ConsumerState SafeArea( child: Center( child: SingleChildScrollView( + // 无弹性回弹:内容放得下就不滚(大窗口不出现上下拖动/滚动条), + // 仅窗口太矮放不下时才滚动。 + physics: const ClampingScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), @@ -277,6 +280,7 @@ class _AuthScreenState extends ConsumerState alignment: reg ? Alignment.centerRight : Alignment.centerLeft, child: FractionallySizedBox( widthFactor: 0.5, + heightFactor: 1.0, child: DecoratedBox( decoration: BoxDecoration( color: c.accent, diff --git a/client/test/golden/auth_redesign_golden_test.dart b/client/test/golden/auth_redesign_golden_test.dart new file mode 100644 index 0000000..ab4fcc1 --- /dev/null +++ b/client/test/golden/auth_redesign_golden_test.dart @@ -0,0 +1,52 @@ +// auth_redesign_golden_test.dart — 登录页 Flutter 渲染图(供 design-distill 截图 diff) +// 900x700 @1x,与原型截图同 viewport;明/暗各一张。 +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pangolin_vpn/l10n/strings_zh.dart'; +import 'package:pangolin_vpn/pangolin_theme.dart'; +import 'package:pangolin_vpn/services/token_store.dart'; +import 'package:pangolin_vpn/state/auth_provider.dart'; +import 'package:pangolin_vpn/widgets/auth_screen.dart'; + +class _NullTokenStore implements TokenStore { + const _NullTokenStore(); + @override + Future saveTokens({required String access, required String refresh}) async {} + @override + Future loadAccessToken() async => null; + @override + Future loadRefreshToken() async => null; + @override + Future clear() async {} + @override + Future markOnboarded() async {} + @override + Future isOnboarded() async => true; + @override + Future saveLastEmail(String email) async {} + @override + Future loadLastEmail() async => null; +} + +Future _shoot(WidgetTester tester, ThemeData theme, String name) async { + tester.view.physicalSize = const Size(900, 700); + tester.view.devicePixelRatio = 1.0; + addTearDown(tester.view.resetPhysicalSize); + addTearDown(tester.view.resetDevicePixelRatio); + await tester.pumpWidget(ProviderScope( + overrides: [tokenStoreProvider.overrideWithValue(const _NullTokenStore())], + child: MaterialApp( + debugShowCheckedModeBanner: false, + theme: theme, + home: AuthScreen(t: const StringsZh(), onDone: () {}), + ), + )); + await tester.pumpAndSettle(); + await expectLater(find.byType(AuthScreen), matchesGoldenFile('goldens/$name.png')); +} + +void main() { + testWidgets('auth login light', (t) => _shoot(t, PangolinTheme.light, 'auth_login_light')); + testWidgets('auth login dark', (t) => _shoot(t, PangolinTheme.dark, 'auth_login_dark')); +} diff --git a/client/test/golden/goldens/auth_login_dark.png b/client/test/golden/goldens/auth_login_dark.png new file mode 100644 index 0000000..8dad576 Binary files /dev/null and b/client/test/golden/goldens/auth_login_dark.png differ diff --git a/client/test/golden/goldens/auth_login_light.png b/client/test/golden/goldens/auth_login_light.png new file mode 100644 index 0000000..78b6d95 Binary files /dev/null and b/client/test/golden/goldens/auth_login_light.png differ