diff --git a/ARCH.md b/ARCH.md new file mode 100644 index 0000000..800300c --- /dev/null +++ b/ARCH.md @@ -0,0 +1,12 @@ +# State Management + +We use a MultiProvider to distribute state to the underlying widgets. Right now there are 2 top +level Providers: FlwtchState (the app) and OpaqueTheme. + +## Theme + +OpaqueTheme extends ChangeProvider. SetLight and SetDark are functions that call notifyListeners() + +ChangeNotiferProvider is used to package OpaqueTheme into a provider which is a top level +provider (as every widget in the app needs to be re-rendered on a theme switch). + diff --git a/lib/main.dart b/lib/main.dart index acc5fcc..2ce42d3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -32,17 +32,17 @@ class FlwtchState extends State { // mergenotes: ui stuff ProfileModel selectedProfile; String selectedConversation = ""; - var columns = [1];// default or 'single column' mode + var columns = [1]; // default or 'single column' mode //var columns = [1, 1, 2]; AppModel appStatus; HashMap profiles; - @override initState() { super.initState(); cwtchInit = false; + profiles = new HashMap(); print("FlwtchState.initState()"); @@ -80,32 +80,55 @@ class FlwtchState extends State { }); } + ChangeNotifierProvider getOpaqueProvider() { + return ChangeNotifierProvider(create: (context) => OpaqueTheme(Opaque.dark)); + } + + Provider getFlwtchStateProvider() { + return Provider( + create: (_) => this, + ); + } + @override Widget build(BuildContext context) { appStatus = AppModel(cwtch: cwtch); final newTextTheme = Theme.of(context).textTheme.apply( - bodyColor: Opaque.current().mainTextColor(), - displayColor: Opaque.current().mainTextColor(), - ); + bodyColor: Opaque.current().mainTextColor(), + displayColor: Opaque.current().mainTextColor(), + ); print("FlwtchState.build() cwtchInit: $cwtchInit"); - return Provider( - create: (_) => this, - child: MaterialApp( - title: 'Cwtch', - theme: ThemeData( - visualDensity: VisualDensity.adaptivePlatformDensity, - primarySwatch: Colors.red, - primaryColor: Opaque.current().backgroundMainColor(), - canvasColor: Opaque.current().backgroundPaneColor(), - accentColor: Opaque.current().defaultButtonColor(), - buttonColor: Opaque.current().defaultButtonColor(), - textTheme: newTextTheme, - ), - // from dan: home: cwtchInit == true ? ProfileMgrView(cwtch) : SplashView(), - // from erinn: home: columns.length == 3 ? TripleColumnView() : ProfileMgrView(), - home: cwtchInit == true ? (columns.length == 3 ? TripleColumnView() : ProfileMgrView()) : SplashView(), - )); + return MultiProvider( + providers: [getFlwtchStateProvider(), getOpaqueProvider()], + builder: (context, widget) { return MaterialApp( + title: 'Cwtch', + theme: ThemeData( + visualDensity: VisualDensity.adaptivePlatformDensity, + primarySwatch: Colors.red, + primaryColor: Provider.of(context) + .current() + .backgroundMainColor(), + canvasColor: Provider.of(context) + .current() + .backgroundPaneColor(), + accentColor: Provider.of(context) + .current() + .defaultButtonColor(), + buttonColor: Provider.of(context) + .current() + .defaultButtonColor(), + textTheme: newTextTheme, + ), + // from dan: home: cwtchInit == true ? ProfileMgrView(cwtch) : SplashView(), + // from erinn: home: columns.length == 3 ? TripleColumnView() : ProfileMgrView(), + home: cwtchInit == true + ? (columns.length == 3 + ? TripleColumnView() + : ProfileMgrView()) + : SplashView(), + );}, + ); } -} \ No newline at end of file +} diff --git a/lib/opaque.dart b/lib/opaque.dart index fa81b31..0282dcd 100644 --- a/lib/opaque.dart +++ b/lib/opaque.dart @@ -5,6 +5,8 @@ import 'dart:ui'; import 'dart:core'; + +import 'package:flutter/material.dart'; abstract class OpaqueThemeType { static final Color red = Color(0xFFFF0000); Color backgroundMainColor(){return red;} @@ -421,9 +423,12 @@ class Opaque extends OpaqueThemeType { int chatPaneMinSize() { return chatPaneMinSizeBase[p[scale]]; } int doublePaneMinSize() { return sidePaneMinSize() + chatPaneMinSize(); } + static OpaqueThemeType _current; static final OpaqueThemeType dark = CwtchDark(); static final OpaqueThemeType light = CwtchLight(); - static OpaqueThemeType current() { return dark; } + static void setDark() { _current = dark; } + static void setLight() { _current = light; } + static OpaqueThemeType current() { if (_current == null) {setDark();} return _current; } int scale = 2; @@ -507,3 +512,15 @@ int scale = 2; } + + + +/// TODO: Wire into libCwtch saveSettings / updateTheme etc... +class OpaqueTheme extends ChangeNotifier { + OpaqueThemeType theme; + void setDark() { theme = Opaque.dark; notifyListeners();} + void setLight() { theme = Opaque.light; notifyListeners();} + OpaqueThemeType current() { return theme; } + + OpaqueTheme(this.theme); +} \ No newline at end of file diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index d61a981..bdbe5df 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_app/main.dart'; +import 'package:flutter_app/opaque.dart'; +import 'package:provider/provider.dart'; class GlobalSettingsView extends StatefulWidget { @override @@ -35,7 +38,18 @@ class _GlobalSettingsViewState extends State { }, ), Text("Zoom"), - Text("Theme"), + SwitchListTile( + title: const Text('Theme'), + value: Provider.of(context).current() == Opaque.light, + onChanged: (bool value) { + if (value) { + Provider.of(context, listen: false).setLight(); + } else { + Provider.of(context, listen: false).setDark(); + } + }, + secondary: const Icon(Icons.lightbulb_outline), + ), Text("Experiments enabled"), Text("Text magnification reference"), Text("Acknowledgements"),