126 lines
3.6 KiB
Dart
126 lines
3.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
|
|
import '../core/auth/session_store.dart';
|
|
import '../data/network/api_client.dart';
|
|
import '../data/storage/local_kv_store.dart';
|
|
import '../features/auth/data/apis/auth_api.dart';
|
|
import '../features/auth/data/repositories/auth_repository.dart';
|
|
import '../features/auth/presentation/bloc/auth_bloc.dart';
|
|
import '../features/auth/presentation/bloc/auth_state.dart';
|
|
import '../features/auth/presentation/screens/login_screen.dart';
|
|
import '../features/home/presentation/screens/home_screen.dart';
|
|
import '../l10n/app_localizations.dart';
|
|
import '../shared/widgets/app_loading_indicator.dart';
|
|
import 'app_theme.dart';
|
|
import 'di/injection.dart';
|
|
|
|
class EryaoApp extends StatefulWidget {
|
|
const EryaoApp({super.key});
|
|
|
|
@override
|
|
State<EryaoApp> createState() => _EryaoAppState();
|
|
}
|
|
|
|
class _EryaoAppState extends State<EryaoApp> {
|
|
final SessionStore _sessionStore = SessionStore(LocalKvStore());
|
|
late final AuthBloc _authBloc;
|
|
Locale _locale = const Locale('zh');
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
final apiClient = ApiClient(
|
|
baseUrl: appDependencies.backendUrl,
|
|
tokenProvider: _sessionStore.getToken,
|
|
onUnauthorized: () {
|
|
return _authBloc.handleUnauthorized401();
|
|
},
|
|
);
|
|
final authApi = AuthApi(apiClient: apiClient);
|
|
final authRepository = AuthRepositoryImpl(
|
|
authApi: authApi,
|
|
sessionStore: _sessionStore,
|
|
);
|
|
_authBloc = AuthBloc(repository: authRepository);
|
|
_bootstrap();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_authBloc.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _bootstrap() async {
|
|
final localeCode = await _sessionStore.getLocaleCode();
|
|
if (mounted) {
|
|
setState(() {
|
|
_locale = localeCode == 'en' ? const Locale('en') : const Locale('zh');
|
|
});
|
|
}
|
|
await _authBloc.start();
|
|
}
|
|
|
|
Future<void> _handleLocaleChanged(Locale locale) async {
|
|
await _sessionStore.saveLocaleCode(locale.languageCode);
|
|
if (!mounted) {
|
|
return;
|
|
}
|
|
setState(() {
|
|
_locale = locale;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnimatedBuilder(
|
|
animation: _authBloc,
|
|
builder: (context, _) {
|
|
return MaterialApp(
|
|
debugShowCheckedModeBanner: false,
|
|
onGenerateTitle: (context) => AppLocalizations.of(context)!.appTitle,
|
|
locale: _locale,
|
|
localizationsDelegates: const [
|
|
AppLocalizations.delegate,
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
],
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
theme: AppTheme.light(),
|
|
home: _buildHomeByAuthState(_authBloc.state),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _buildHomeByAuthState(AuthState state) {
|
|
if (state.status == AuthStatus.initial ||
|
|
state.status == AuthStatus.loading) {
|
|
return const Scaffold(
|
|
body: Center(
|
|
child: AppLoadingIndicator(variant: AppLoadingVariant.surface),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (state.status == AuthStatus.authenticated && state.user != null) {
|
|
return HomeScreen(
|
|
account: state.user!.email,
|
|
sessionStore: _sessionStore,
|
|
onLogout: _authBloc.logout,
|
|
);
|
|
}
|
|
|
|
return LoginScreen(
|
|
currentLocale: _locale,
|
|
onLocaleChanged: _handleLocaleChanged,
|
|
onRequestOtp: _authBloc.sendOtp,
|
|
onLoginWithOtp: (email, otp) {
|
|
return _authBloc.loginWithOtp(email: email, otp: otp);
|
|
},
|
|
);
|
|
}
|
|
}
|