102 lines
2.9 KiB
Dart
102 lines
2.9 KiB
Dart
import 'package:actors/actors.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:signals/signals_flutter.dart' show SignalBuilder;
|
|
|
|
import '../application/actors/fetch_actor.dart';
|
|
import '../application/controllers/browser_controller.dart';
|
|
import '../application/controllers/reader_settings_controller.dart';
|
|
import '../database/database.dart';
|
|
import '../l10n/strings.dart';
|
|
import 'reader/reader_screen.dart';
|
|
/// Wires the app's dependencies together and provides them to the tree.
|
|
/// Everything is local-first: the database is created up front and the fetch
|
|
/// actor is the only path to the network.
|
|
class AppDependencies {
|
|
AppDependencies({MewsDatabase? database})
|
|
: db = database ?? MewsDatabase(),
|
|
fetch = Actor.create(FetchHandler.new) {
|
|
browser = BrowserController(db: db, fetch: fetch);
|
|
settings = ReaderSettingsController(db);
|
|
library = LibraryController(db);
|
|
}
|
|
|
|
final MewsDatabase db;
|
|
final Actor<FetchCommand, FetchResult> fetch;
|
|
late final BrowserController browser;
|
|
late final ReaderSettingsController settings;
|
|
late final LibraryController library;
|
|
|
|
Future<void> start() async {
|
|
await settings.load();
|
|
await library.load();
|
|
await browser.restoreLastSession();
|
|
}
|
|
}
|
|
|
|
class AppScope extends InheritedWidget {
|
|
const AppScope({
|
|
required this.deps,
|
|
required this.strings,
|
|
required super.child,
|
|
super.key,
|
|
});
|
|
|
|
final AppDependencies deps;
|
|
final Strings strings;
|
|
|
|
static AppScope of(BuildContext context) =>
|
|
context.getInheritedWidgetOfExactType<AppScope>()!;
|
|
|
|
@override
|
|
bool updateShouldNotify(AppScope oldWidget) => false;
|
|
}
|
|
|
|
class MewsApp extends StatelessWidget {
|
|
const MewsApp({required this.deps, required this.strings, super.key});
|
|
|
|
final AppDependencies deps;
|
|
final Strings strings;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AppScope(
|
|
deps: deps,
|
|
strings: strings,
|
|
child: StringsScope(
|
|
strings: strings,
|
|
child: const _ThemedApp(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ThemedApp extends StatelessWidget {
|
|
const _ThemedApp();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final deps = AppScope.of(context).deps;
|
|
return SignalBuilder(builder: (context) {
|
|
final mode = switch (deps.settings.themeMode.value) {
|
|
'light' => ThemeMode.light,
|
|
'dark' => ThemeMode.dark,
|
|
_ => ThemeMode.system,
|
|
};
|
|
return MaterialApp(
|
|
title: 'Mews',
|
|
themeMode: mode,
|
|
theme: ThemeData(
|
|
useMaterial3: true,
|
|
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xff1a4f9c)),
|
|
),
|
|
darkTheme: ThemeData(
|
|
useMaterial3: true,
|
|
brightness: Brightness.dark,
|
|
colorScheme: ColorScheme.fromSeed(
|
|
seedColor: const Color(0xff1a4f9c), brightness: Brightness.dark),
|
|
),
|
|
home: const ReaderScreen(),
|
|
);
|
|
});
|
|
}
|
|
}
|