diff --git a/lib/main.dart b/lib/main.dart index e94c8cd..dcef430 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,19 +1,41 @@ import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:provider/provider.dart'; + +import 'stores/config_store.dart'; void main() { - runApp(MyApp()); + runApp( + MultiProvider( + providers: [ + Provider( + create: (_) => ConfigStore()..load(), + dispose: (_, store) => store.dispose(), + ), + ], + child: MyApp(), + ), + ); } class MyApp extends StatelessWidget { @override - Widget build(BuildContext context) => MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); + Widget build(BuildContext context) { + return Observer( + builder: (ctx) { + return MaterialApp( + title: 'Flutter Demo', + themeMode: ctx.watch().theme, + darkTheme: ThemeData.dark(), + theme: ThemeData( + primarySwatch: ctx.watch().accentColor, + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: MyHomePage(title: 'Flutter Demo Home Page'), + ); + }, + ); + } } class MyHomePage extends StatefulWidget { diff --git a/lib/stores/config_store.dart b/lib/stores/config_store.dart new file mode 100644 index 0000000..8153973 --- /dev/null +++ b/lib/stores/config_store.dart @@ -0,0 +1,44 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:mobx/mobx.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +part 'config_store.g.dart'; + +class ConfigStore extends _ConfigStore with _$ConfigStore {} + +abstract class _ConfigStore with Store { + ReactionDisposer _saveReactionDisposer; + + _ConfigStore() { + // persitently save settings each time they are changed + _saveReactionDisposer = reaction((_) => theme, (_) { + save(); + }); + } + + void dispose() { + _saveReactionDisposer(); + } + + void load() async { + var prefs = await SharedPreferences.getInstance(); + // set saved settings or create defaults + theme = _themeModeFromString(prefs.getString('theme') ?? 'dark'); + } + + void save() async { + var prefs = await SharedPreferences.getInstance(); + + await prefs.setString('theme', describeEnum(theme)); + } + + @observable + ThemeMode theme = ThemeMode.dark; + + @observable + MaterialColor accentColor = Colors.green; +} + +ThemeMode _themeModeFromString(String theme) => + ThemeMode.values.firstWhere((e) => describeEnum(e) == theme); diff --git a/lib/stores/config_store.g.dart b/lib/stores/config_store.g.dart new file mode 100644 index 0000000..ca7a423 --- /dev/null +++ b/lib/stores/config_store.g.dart @@ -0,0 +1,49 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'config_store.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$ConfigStore on _ConfigStore, Store { + final _$themeAtom = Atom(name: '_ConfigStore.theme'); + + @override + ThemeMode get theme { + _$themeAtom.reportRead(); + return super.theme; + } + + @override + set theme(ThemeMode value) { + _$themeAtom.reportWrite(value, super.theme, () { + super.theme = value; + }); + } + + final _$accentColorAtom = Atom(name: '_ConfigStore.accentColor'); + + @override + MaterialColor get accentColor { + _$accentColorAtom.reportRead(); + return super.accentColor; + } + + @override + set accentColor(MaterialColor value) { + _$accentColorAtom.reportWrite(value, super.accentColor, () { + super.accentColor = value; + }); + } + + @override + String toString() { + return ''' +theme: ${theme}, +accentColor: ${accentColor} + '''; + } +} diff --git a/pubspec.lock b/pubspec.lock index 5da9ea7..228e882 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -244,11 +244,23 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.2" + flutter_mobx: + dependency: "direct main" + description: + name: flutter_mobx + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0+2" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" glob: dependency: transitive description: @@ -354,6 +366,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.9.6+3" + mobx: + dependency: "direct main" + description: + name: mobx + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1+2" + mobx_codegen: + dependency: "direct dev" + description: + name: mobx_codegen + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0+1" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" node_interop: dependency: transitive description: @@ -452,6 +485,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.13" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.2+1" pub_semver: dependency: transitive description: @@ -480,6 +520,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.24.1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.10" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2+2" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+10" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+7" shelf: dependency: transitive description: @@ -499,6 +574,13 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6" source_span: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 690eed9..e4a03a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,6 +27,12 @@ dependencies: timeago: ^2.0.27 lemmy_api_client: ^0.1.3 + mobx: ^1.2.1 + flutter_mobx: ^1.1.0 + provider: ^4.3.1 + + shared_preferences: '>=0.5.0 <2.0.0' + flutter: sdk: flutter @@ -39,6 +45,7 @@ dev_dependencies: sdk: flutter effective_dart: ^1.0.0 build_runner: ^1.10.0 + mobx_codegen: ^1.1.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec