Theme switching with ChangeProvider

This commit is contained in:
Sarah Jamie Lewis 2021-01-27 12:18:28 -08:00
parent 5cbc0814f6
commit d45ac78e64
4 changed files with 91 additions and 25 deletions

12
ARCH.md Normal file
View File

@ -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).

View File

@ -32,17 +32,17 @@ class FlwtchState extends State<Flwtch> {
// 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<String, ProfileModel> profiles;
@override
initState() {
super.initState();
cwtchInit = false;
profiles = new HashMap<String, ProfileModel>();
print("FlwtchState.initState()");
@ -80,32 +80,55 @@ class FlwtchState extends State<Flwtch> {
});
}
ChangeNotifierProvider<OpaqueTheme> getOpaqueProvider() {
return ChangeNotifierProvider(create: (context) => OpaqueTheme(Opaque.dark));
}
Provider<FlwtchState> getFlwtchStateProvider() {
return Provider<FlwtchState>(
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<FlwtchState>(
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<OpaqueTheme>(context)
.current()
.backgroundMainColor(),
canvasColor: Provider.of<OpaqueTheme>(context)
.current()
.backgroundPaneColor(),
accentColor: Provider.of<OpaqueTheme>(context)
.current()
.defaultButtonColor(),
buttonColor: Provider.of<OpaqueTheme>(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(),
);},
);
}
}
}

View File

@ -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);
}

View File

@ -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<GlobalSettingsView> {
},
),
Text("Zoom"),
Text("Theme"),
SwitchListTile(
title: const Text('Theme'),
value: Provider.of<OpaqueTheme>(context).current() == Opaque.light,
onChanged: (bool value) {
if (value) {
Provider.of<OpaqueTheme>(context, listen: false).setLight();
} else {
Provider.of<OpaqueTheme>(context, listen: false).setDark();
}
},
secondary: const Icon(Icons.lightbulb_outline),
),
Text("Experiments enabled"),
Text("Text magnification reference"),
Text("Acknowledgements"),