feat(apps): update UI screens and shared components

- Update home screen with new composer and interactions
- Update settings screens with new profile flow
- Update calendar share dialog
- Update contacts screen
- Add new shared widgets: confirm_sheet, phone_prefix_selector
- Add new formatters: phone_display_formatter
- Update tests for modified components
This commit is contained in:
qzl
2026-03-19 18:43:08 +08:00
parent f0af44d840
commit 8d4a14150b
24 changed files with 868 additions and 989 deletions
@@ -1,82 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:social_app/core/di/injection.dart';
import 'package:social_app/features/auth/data/auth_repository.dart';
import 'package:social_app/features/auth/presentation/bloc/auth_bloc.dart';
import 'package:social_app/features/auth/presentation/bloc/auth_event.dart';
import 'package:social_app/features/auth/presentation/bloc/auth_state.dart';
import 'package:social_app/features/settings/ui/screens/change_password_screen.dart';
class MockAuthRepository extends Mock implements AuthRepository {}
void main() {
late MockAuthRepository mockAuthRepository;
late AuthBloc authBloc;
setUp(() async {
mockAuthRepository = MockAuthRepository();
await sl.reset();
sl.registerSingleton<AuthRepository>(mockAuthRepository);
authBloc = AuthBloc(mockAuthRepository);
authBloc.add(
const AuthLoggedIn(
user: AuthUser(id: 'user-1', email: 'tester@example.com'),
),
);
});
tearDown(() async {
await authBloc.close();
await sl.reset();
});
Future<void> pumpScreen(WidgetTester tester) async {
await tester.pumpWidget(
BlocProvider<AuthBloc>.value(
value: authBloc,
child: const MaterialApp(home: ChangePasswordScreen()),
),
);
await tester.pump();
}
testWidgets('确认修改按钮在验证码发送前不可点击', (tester) async {
when(
() => mockAuthRepository.requestPasswordReset(any()),
).thenAnswer((_) async {});
await pumpScreen(tester);
final confirmButton = tester.widget<ElevatedButton>(
find.widgetWithText(ElevatedButton, '确认修改'),
);
expect(confirmButton.onPressed, isNull);
expect(find.text('设置新密码'), findsNothing);
});
testWidgets('发送验证码倒计时期间不会重复触发请求', (tester) async {
final completer = Completer<void>();
when(
() => mockAuthRepository.requestPasswordReset(any()),
).thenAnswer((_) => completer.future);
await pumpScreen(tester);
await tester.tap(find.widgetWithText(ElevatedButton, '发送验证码'));
await tester.pump();
expect(find.text('60 秒后可重发'), findsOneWidget);
expect(find.text('设置新密码'), findsOneWidget);
verify(
() => mockAuthRepository.requestPasswordReset('tester@example.com'),
).called(1);
completer.complete();
});
}