Files
Prisma/lib/app/app.dart
T
2026-05-23 11:46:52 +03:00

115 lines
3.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../backend/backend.dart';
import 'router.dart';
import 'theme.dart';
class GelRuleApp extends ConsumerWidget {
const GelRuleApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final database = ref.watch(appDatabaseProvider);
final settings = ref.watch(appSettingsProvider);
final router = ref.watch(appRouterProvider);
return database.when(
loading: () => const MaterialApp(
debugShowCheckedModeBanner: false,
home: _StartupLoadingScreen(),
),
error: (error, _) => MaterialApp(
debugShowCheckedModeBanner: false,
theme: buildTheme(Brightness.light),
darkTheme: buildTheme(Brightness.dark),
themeMode: ThemeMode.dark,
home: _StartupErrorScreen(error: error),
),
data: (_) => MaterialApp.router(
title: 'GelRule',
debugShowCheckedModeBanner: false,
theme: buildTheme(Brightness.light),
darkTheme: buildTheme(Brightness.dark),
themeMode: settings.maybeWhen(
data: (value) => parseThemeMode(value.themeMode),
orElse: () => ThemeMode.dark,
),
routerConfig: router,
),
);
}
}
final appSettingsProvider = FutureProvider<AppSettings>((ref) {
return ref.watch(settingsServiceProvider).getSettings().then(
(result) => result.fold(
onSuccess: (settings) => settings,
onError: (_) => AppSettings.defaults,
),
);
});
class _StartupLoadingScreen extends StatelessWidget {
const _StartupLoadingScreen();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF101114),
body: Center(
child: CircularProgressIndicator(
color: ColorScheme.fromSeed(
seedColor: const Color(0xFFE84D8A),
brightness: Brightness.dark,
).primary,
),
),
);
}
}
class _StartupErrorScreen extends ConsumerWidget {
const _StartupErrorScreen({required this.error});
final Object error;
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
body: SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.storage_rounded, size: 48),
const SizedBox(height: 16),
Text(
'Could not start local database',
style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'$error',
textAlign: TextAlign.center,
maxLines: 5,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 18),
FilledButton.icon(
onPressed: () => ref.invalidate(appDatabaseProvider),
icon: const Icon(Icons.refresh_rounded),
label: const Text('Retry'),
),
],
),
),
),
),
);
}
}