Add settings page #46
4 changed files with 79 additions and 21 deletions
settings fully working
commit
2bf1e629b7
|
|
@ -96,17 +96,31 @@ class App extends StatelessWidget {
|
|||
navigatorKey: navigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
// Use indigo to work around bugs in theme generation
|
||||
theme: (lightDynamic ?? ColorScheme.fromSeed(seedColor: Colors.indigo))
|
||||
.getTheme(
|
||||
ref
|
||||
.watch(SettingsController.provider)
|
||||
.maybeWhen(
|
||||
orElse: () => true,
|
||||
data: (settings) => settings.useSystemFont,
|
||||
),
|
||||
),
|
||||
theme:
|
||||
(ref
|
||||
.watch(SettingsController.provider)
|
||||
.maybeWhen(
|
||||
orElse: () => lightDynamic,
|
||||
data: (settings) =>
|
||||
settings.useDynamicTheming ? lightDynamic : null,
|
||||
) ??
|
||||
ColorScheme.fromSeed(seedColor: Colors.indigo))
|
||||
.getTheme(
|
||||
ref
|
||||
.watch(SettingsController.provider)
|
||||
.maybeWhen(
|
||||
orElse: () => true,
|
||||
data: (settings) => settings.useSystemFont,
|
||||
),
|
||||
),
|
||||
darkTheme:
|
||||
(darkDynamic ??
|
||||
(ref
|
||||
.watch(SettingsController.provider)
|
||||
.maybeWhen(
|
||||
orElse: () => darkDynamic,
|
||||
data: (settings) =>
|
||||
settings.useDynamicTheming ? darkDynamic : null,
|
||||
) ??
|
||||
ColorScheme.fromSeed(
|
||||
seedColor: Colors.indigo,
|
||||
brightness: Brightness.dark,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ part "settings.g.dart";
|
|||
abstract class Settings with _$Settings {
|
||||
const factory Settings({
|
||||
@Default(ThemeMode.light) ThemeMode theme,
|
||||
@Default(true) bool useDynamicTheming,
|
||||
@Default(false) bool useSystemFont,
|
||||
}) = _Settings;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import "dart:io";
|
||||
|
||||
import "package:collection/collection.dart";
|
||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
|
@ -36,7 +38,7 @@ class SettingsPage extends ConsumerWidget {
|
|||
description:
|
||||
"Toggle between Light Mode, Dark Mode, and System themes.",
|
||||
builder: (title, description) => DialogListTile<ThemeMode>(
|
||||
icon: Icon(Icons.palette),
|
||||
icon: Icon(Icons.contrast),
|
||||
title: title,
|
||||
subtitle: Text(description),
|
||||
initialValue: settings.theme,
|
||||
|
|
@ -48,6 +50,27 @@ class SettingsPage extends ConsumerWidget {
|
|||
.onError(showError),
|
||||
),
|
||||
),
|
||||
Setting(
|
||||
title: "Use Dynamic Theme",
|
||||
description:
|
||||
"Toggle on or off Dynamic Theme. Only available on Android, Linux, Windows, or MacOS.",
|
||||
builder: (title, description) => SwitchListTile(
|
||||
title: Text(title),
|
||||
subtitle: Text(description),
|
||||
secondary: Icon(Icons.palette),
|
||||
value: settings.useDynamicTheming,
|
||||
onChanged:
|
||||
(Platform.isAndroid ||
|
||||
Platform.isLinux ||
|
||||
Platform.isMacOS ||
|
||||
Platform.isWindows)
|
||||
? (value) => ref
|
||||
.watch(SettingsController.provider.notifier)
|
||||
.set(settings.copyWith(useDynamicTheming: value))
|
||||
.onError(showError)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
Setting(
|
||||
title: "Use System Font",
|
||||
description:
|
||||
|
|
@ -118,19 +141,37 @@ class SettingsPage extends ConsumerWidget {
|
|||
context,
|
||||
).colorScheme.primaryContainer,
|
||||
itemCount: categories.length,
|
||||
onTap: (index) =>
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
categories[index].title,
|
||||
),
|
||||
),
|
||||
body: ListView(),
|
||||
onTap: (index) => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
categories[index].title,
|
||||
),
|
||||
),
|
||||
body: SuperListView(
|
||||
padding: .symmetric(
|
||||
vertical: 12,
|
||||
horizontal: 8,
|
||||
),
|
||||
children: buildCategories(settings)
|
||||
.values
|
||||
.flattenedToList[selected.value]
|
||||
.settings
|
||||
.map(
|
||||
(setting) => Padding(
|
||||
padding: .only(bottom: 4),
|
||||
child: setting.builder(
|
||||
setting.title,
|
||||
setting.description,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
itemBuilder: (context, index) => ListTile(
|
||||
leading: Icon(categories[index].icon),
|
||||
title: Text(categories[index].title),
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class DialogListTile<T> extends ConsumerWidget {
|
|||
enabledBorder: InputBorder.none,
|
||||
),
|
||||
child: ListTile(
|
||||
enabled: onChanged != null,
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (context) => RadioDialog<T>(
|
||||
|
|
@ -57,6 +58,7 @@ class DialogListTile<T> extends ConsumerWidget {
|
|||
label: Text(
|
||||
field.value == null ? "None" : getName(field.value as T),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: onChanged == null ? .new(color: Colors.grey) : null,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue