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, Actor? fetch}) : db = database ?? MewsDatabase(), fetch = fetch ?? Actor.create(FetchHandler.new) { browser = BrowserController(db: db, fetch: this.fetch); settings = ReaderSettingsController(db); library = LibraryController(db); } final MewsDatabase db; final Actor fetch; late final BrowserController browser; late final ReaderSettingsController settings; late final LibraryController library; Future 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()!; @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(), ); }); } }