The app's first patterns. Dependencies (lib/src/core/dependencies) is the composition root, built at startup and handed down by DependenciesScope; it replaces the scaffold's global client and restores a stored session before the first frame, so a restart never creates a second anonymous account. AuthGateway with ServerpodAuthGateway is the boundary to the server's authentication, AuthRepository signs in anonymously when nobody is signed in, and SessionBloc (flutter_bloc) keeps a person signed in, also after signing out or a revoked session. SessionGate shows a spinner while signing in, offers to try again when that fails, and builds the app anew for every person. AccountButton explains that progress is saved on this device and asks before signing out of an anonymous account, which can't be restored. AppBlocObserver logs all blocs. Tests: the repository, the bloc's sequences (a stored session is kept, a failed sign-in is retried, signing out starts anew), and the widgets, including that cancelling the sign-out keeps the account. test/support holds the fake gateway and testDependencies(). AGENTS.md describes the composition root and the test factory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
47 lines
1.8 KiB
Dart
47 lines
1.8 KiB
Dart
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:halkyon_learn_flutter/src/core/bloc/app_bloc_observer.dart';
|
|
import 'package:halkyon_learn_flutter/src/core/dependencies/dependencies.dart';
|
|
import 'package:halkyon_learn_flutter/src/core/dependencies/dependencies_scope.dart';
|
|
import 'package:halkyon_learn_flutter/src/feature/auth/widget/session_gate.dart';
|
|
import 'package:halkyon_learn_flutter/src/feature/editor_playground/widget/editor_playground_screen.dart';
|
|
import 'package:material_ui/material_ui.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
Bloc.observer = const AppBlocObserver();
|
|
final dependencies = await Dependencies.create();
|
|
runApp(
|
|
DependenciesScope(
|
|
dependencies: dependencies,
|
|
child: const HalkyonLearnApp(),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Builds a theme for the given [brightness].
|
|
ThemeData _buildTheme(Brightness brightness) {
|
|
return ThemeData(
|
|
colorScheme: ColorScheme.fromSeed(
|
|
seedColor: Colors.blue,
|
|
brightness: brightness,
|
|
),
|
|
);
|
|
}
|
|
|
|
class const HalkyonLearnApp({super.key}) extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'Halkyon Learn',
|
|
theme: _buildTheme(Brightness.light),
|
|
darkTheme: _buildTheme(Brightness.dark),
|
|
// Packages that still import package:flutter/material.dart (Serverpod's sign-in
|
|
// widgets, the rich-text editor) see this app's theme and localizations only
|
|
// through the bridge, since material_ui is a separate copy of that library. The
|
|
// bridge is deprecated on purpose, as a reminder: remove it once they have moved.
|
|
// ignore: deprecated_member_use
|
|
builder: (context, child) => MaterialUiCompatibilityBridge(child: child!),
|
|
home: const SessionGate(child: EditorPlaygroundScreen()),
|
|
);
|
|
}
|
|
}
|