mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-25 00:14:42 +01:00
Refactor: move theme prefs to PrefController
This commit is contained in:
parent
9d7d97b924
commit
f50d7fbf26
26 changed files with 528 additions and 216 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
mixin BlocLogger {
|
mixin BlocLogger {
|
||||||
String? get tag => null;
|
String? get tag => null;
|
||||||
|
|
||||||
|
@ -11,3 +13,15 @@ class StateMessage {
|
||||||
|
|
||||||
final String value;
|
final String value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension EmitterExtension<State> on Emitter<State> {
|
||||||
|
Future<void> forEachIgnoreError<T>(
|
||||||
|
Stream<T> stream, {
|
||||||
|
required State Function(T data) onData,
|
||||||
|
}) =>
|
||||||
|
onEach<T>(
|
||||||
|
stream,
|
||||||
|
onData: (data) => call(onData(data)),
|
||||||
|
onError: (_, __) {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// ignore_for_file: deprecated_member_use_from_same_package
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/pref.dart';
|
import 'package:nc_photos/entity/pref.dart';
|
||||||
|
@ -141,6 +144,41 @@ class PrefController {
|
||||||
value: value,
|
value: value,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ValueStream<bool> get isDarkTheme => _isDarkThemeController.stream;
|
||||||
|
|
||||||
|
Future<void> setDarkTheme(bool value) => _set<bool>(
|
||||||
|
controller: _isDarkThemeController,
|
||||||
|
setter: (pref, value) => pref.setDarkTheme(value),
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
|
||||||
|
ValueStream<bool> get isFollowSystemTheme =>
|
||||||
|
_isFollowSystemThemeController.stream;
|
||||||
|
|
||||||
|
Future<void> setFollowSystemTheme(bool value) => _set<bool>(
|
||||||
|
controller: _isFollowSystemThemeController,
|
||||||
|
setter: (pref, value) => pref.setFollowSystemTheme(value),
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
|
||||||
|
ValueStream<bool> get isUseBlackInDarkTheme =>
|
||||||
|
_isUseBlackInDarkThemeController.stream;
|
||||||
|
|
||||||
|
Future<void> setUseBlackInDarkTheme(bool value) => _set<bool>(
|
||||||
|
controller: _isUseBlackInDarkThemeController,
|
||||||
|
setter: (pref, value) => pref.setUseBlackInDarkTheme(value),
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
|
||||||
|
ValueStream<Color?> get seedColor => _seedColorController.stream;
|
||||||
|
|
||||||
|
Future<void> setSeedColor(Color? value) => _setOrRemove<Color>(
|
||||||
|
controller: _seedColorController,
|
||||||
|
setter: (pref, value) => pref.setSeedColor(value.withAlpha(0xFF).value),
|
||||||
|
remover: (pref) => pref.setSeedColor(null),
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
|
||||||
Future<void> _set<T>({
|
Future<void> _set<T>({
|
||||||
required BehaviorSubject<T> controller,
|
required BehaviorSubject<T> controller,
|
||||||
required Future<bool> Function(Pref pref, T value) setter,
|
required Future<bool> Function(Pref pref, T value) setter,
|
||||||
|
@ -160,6 +198,33 @@ class PrefController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _setOrRemove<T>({
|
||||||
|
required BehaviorSubject<T?> controller,
|
||||||
|
required Future<bool> Function(Pref pref, T value) setter,
|
||||||
|
required Future<bool> Function(Pref pref) remover,
|
||||||
|
required T? value,
|
||||||
|
T? defaultValue,
|
||||||
|
}) async {
|
||||||
|
final backup = controller.value;
|
||||||
|
controller.add(value ?? defaultValue);
|
||||||
|
try {
|
||||||
|
if (value == null) {
|
||||||
|
if (!await remover(_c.pref)) {
|
||||||
|
throw StateError("Unknown error");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!await setter(_c.pref, value)) {
|
||||||
|
throw StateError("Unknown error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
_log.severe("[_set] Failed setting preference", e, stackTrace);
|
||||||
|
controller
|
||||||
|
..addError(e, stackTrace)
|
||||||
|
..add(backup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static language_util.AppLanguage _langIdToAppLanguage(int langId) {
|
static language_util.AppLanguage _langIdToAppLanguage(int langId) {
|
||||||
try {
|
try {
|
||||||
return language_util.supportedLanguages[langId]!;
|
return language_util.supportedLanguages[langId]!;
|
||||||
|
@ -168,6 +233,8 @@ class PrefController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const _seedColorDef = 0xFF2196F3;
|
||||||
|
|
||||||
final DiContainer _c;
|
final DiContainer _c;
|
||||||
late final _languageController =
|
late final _languageController =
|
||||||
BehaviorSubject.seeded(_langIdToAppLanguage(_c.pref.getLanguageOr(0)));
|
BehaviorSubject.seeded(_langIdToAppLanguage(_c.pref.getLanguageOr(0)));
|
||||||
|
@ -197,4 +264,12 @@ class PrefController {
|
||||||
BehaviorSubject.seeded(_c.pref.isSaveEditResultToServerOr(true));
|
BehaviorSubject.seeded(_c.pref.isSaveEditResultToServerOr(true));
|
||||||
late final _enhanceMaxSizeController = BehaviorSubject.seeded(
|
late final _enhanceMaxSizeController = BehaviorSubject.seeded(
|
||||||
SizeInt(_c.pref.getEnhanceMaxWidthOr(), _c.pref.getEnhanceMaxHeightOr()));
|
SizeInt(_c.pref.getEnhanceMaxWidthOr(), _c.pref.getEnhanceMaxHeightOr()));
|
||||||
|
late final _isDarkThemeController =
|
||||||
|
BehaviorSubject.seeded(_c.pref.isDarkThemeOr(false));
|
||||||
|
late final _isFollowSystemThemeController =
|
||||||
|
BehaviorSubject.seeded(_c.pref.isFollowSystemThemeOr(false));
|
||||||
|
late final _isUseBlackInDarkThemeController =
|
||||||
|
BehaviorSubject.seeded(_c.pref.isUseBlackInDarkThemeOr(false));
|
||||||
|
late final _seedColorController = BehaviorSubject<Color?>.seeded(
|
||||||
|
Color(_c.pref.getSeedColorOr(_seedColorDef)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,21 +101,30 @@ extension PrefExtension on Pref {
|
||||||
Future<bool> setLastVersion(int value) => _set<int>(
|
Future<bool> setLastVersion(int value) => _set<int>(
|
||||||
PrefKey.lastVersion, value, (key, value) => provider.setInt(key, value));
|
PrefKey.lastVersion, value, (key, value) => provider.setInt(key, value));
|
||||||
|
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
bool? isDarkTheme() => provider.getBool(PrefKey.darkTheme);
|
bool? isDarkTheme() => provider.getBool(PrefKey.darkTheme);
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
bool isDarkThemeOr(bool def) => isDarkTheme() ?? def;
|
bool isDarkThemeOr(bool def) => isDarkTheme() ?? def;
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
Future<bool> setDarkTheme(bool value) => _set<bool>(
|
Future<bool> setDarkTheme(bool value) => _set<bool>(
|
||||||
PrefKey.darkTheme, value, (key, value) => provider.setBool(key, value));
|
PrefKey.darkTheme, value, (key, value) => provider.setBool(key, value));
|
||||||
|
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
bool? isFollowSystemTheme() => provider.getBool(PrefKey.followSystemTheme);
|
bool? isFollowSystemTheme() => provider.getBool(PrefKey.followSystemTheme);
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
bool isFollowSystemThemeOr(bool def) => isFollowSystemTheme() ?? def;
|
bool isFollowSystemThemeOr(bool def) => isFollowSystemTheme() ?? def;
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
Future<bool> setFollowSystemTheme(bool value) => _set<bool>(
|
Future<bool> setFollowSystemTheme(bool value) => _set<bool>(
|
||||||
PrefKey.followSystemTheme,
|
PrefKey.followSystemTheme,
|
||||||
value,
|
value,
|
||||||
(key, value) => provider.setBool(key, value));
|
(key, value) => provider.setBool(key, value));
|
||||||
|
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
bool? isUseBlackInDarkTheme() =>
|
bool? isUseBlackInDarkTheme() =>
|
||||||
provider.getBool(PrefKey.useBlackInDarkTheme);
|
provider.getBool(PrefKey.useBlackInDarkTheme);
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
bool isUseBlackInDarkThemeOr(bool def) => isUseBlackInDarkTheme() ?? def;
|
bool isUseBlackInDarkThemeOr(bool def) => isUseBlackInDarkTheme() ?? def;
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
Future<bool> setUseBlackInDarkTheme(bool value) => _set<bool>(
|
Future<bool> setUseBlackInDarkTheme(bool value) => _set<bool>(
|
||||||
PrefKey.useBlackInDarkTheme,
|
PrefKey.useBlackInDarkTheme,
|
||||||
value,
|
value,
|
||||||
|
@ -249,8 +258,11 @@ extension PrefExtension on Pref {
|
||||||
value,
|
value,
|
||||||
(key, value) => provider.setBool(key, value));
|
(key, value) => provider.setBool(key, value));
|
||||||
|
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
int? getSeedColor() => provider.getInt(PrefKey.seedColor);
|
int? getSeedColor() => provider.getInt(PrefKey.seedColor);
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
int getSeedColorOr(int def) => getSeedColor() ?? def;
|
int getSeedColorOr(int def) => getSeedColor() ?? def;
|
||||||
|
@Deprecated("Use PrefController")
|
||||||
Future<bool> setSeedColor(int? value) {
|
Future<bool> setSeedColor(int? value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return _remove(PrefKey.seedColor);
|
return _remove(PrefKey.seedColor);
|
||||||
|
|
|
@ -117,8 +117,6 @@ class FavoriteResyncedEvent {
|
||||||
final Account account;
|
final Account account;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThemeChangedEvent {}
|
|
||||||
|
|
||||||
enum MetadataTaskState {
|
enum MetadataTaskState {
|
||||||
/// No work is being done
|
/// No work is being done
|
||||||
idle,
|
idle,
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:nc_photos/entity/pref.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:nc_photos/object_extension.dart';
|
import 'package:nc_photos/controller/pref_controller.dart';
|
||||||
import 'package:nc_photos/theme/dimension.dart';
|
import 'package:nc_photos/theme/dimension.dart';
|
||||||
import 'package:nc_photos/theme/material3.dart';
|
import 'package:nc_photos/theme/material3.dart';
|
||||||
|
|
||||||
const defaultSeedColor = 0xFF2196F3;
|
const defaultSeedColor = Color(0xFF2196F3);
|
||||||
|
|
||||||
extension ThemeExtension on ThemeData {
|
extension ThemeExtension on ThemeData {
|
||||||
double get widthLimitedContentMaxWidth => 550.0;
|
double get widthLimitedContentMaxWidth => 550.0;
|
||||||
|
@ -88,20 +88,20 @@ class DarkModeSwitchTheme extends StatelessWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeData buildTheme(Brightness brightness) {
|
ThemeData buildTheme(BuildContext context, Brightness brightness) {
|
||||||
return (brightness == Brightness.light)
|
return (brightness == Brightness.light)
|
||||||
? buildLightTheme()
|
? buildLightTheme(context)
|
||||||
: buildDarkTheme();
|
: buildDarkTheme(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeData buildLightTheme([ColorScheme? dynamicScheme]) {
|
ThemeData buildLightTheme(BuildContext context, [ColorScheme? dynamicScheme]) {
|
||||||
final colorScheme = _getColorScheme(dynamicScheme, Brightness.light);
|
final colorScheme = _getColorScheme(context, dynamicScheme, Brightness.light);
|
||||||
return _applyColorScheme(colorScheme);
|
return _applyColorScheme(colorScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeData buildDarkTheme([ColorScheme? dynamicScheme]) {
|
ThemeData buildDarkTheme(BuildContext context, [ColorScheme? dynamicScheme]) {
|
||||||
final colorScheme = _getColorScheme(dynamicScheme, Brightness.dark);
|
final colorScheme = _getColorScheme(context, dynamicScheme, Brightness.dark);
|
||||||
if (Pref().isUseBlackInDarkThemeOr(false)) {
|
if (context.read<PrefController>().isUseBlackInDarkTheme.value) {
|
||||||
return _applyColorScheme(colorScheme.copyWith(
|
return _applyColorScheme(colorScheme.copyWith(
|
||||||
background: Colors.black,
|
background: Colors.black,
|
||||||
surface: Colors.grey[900],
|
surface: Colors.grey[900],
|
||||||
|
@ -111,12 +111,13 @@ ThemeData buildDarkTheme([ColorScheme? dynamicScheme]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color? getSeedColor() {
|
Color? getSeedColor(BuildContext context) {
|
||||||
return Pref().getSeedColor()?.run((c) => Color(c).withAlpha(0xFF));
|
return context.read<PrefController>().seedColor.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorScheme _getColorScheme(ColorScheme? dynamicScheme, Brightness brightness) {
|
ColorScheme _getColorScheme(
|
||||||
var seedColor = Pref().getSeedColor();
|
BuildContext context, ColorScheme? dynamicScheme, Brightness brightness) {
|
||||||
|
var seedColor = getSeedColor(context);
|
||||||
if (seedColor == null) {
|
if (seedColor == null) {
|
||||||
if (dynamicScheme != null) {
|
if (dynamicScheme != null) {
|
||||||
return dynamicScheme;
|
return dynamicScheme;
|
||||||
|
@ -125,7 +126,7 @@ ColorScheme _getColorScheme(ColorScheme? dynamicScheme, Brightness brightness) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ColorScheme.fromSeed(
|
return ColorScheme.fromSeed(
|
||||||
seedColor: Color(seedColor),
|
seedColor: seedColor,
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'dart:math';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:clock/clock.dart';
|
import 'package:clock/clock.dart';
|
||||||
import 'package:copy_with/copy_with.dart';
|
import 'package:copy_with/copy_with.dart';
|
||||||
import 'package:event_bus/event_bus.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
|
@ -15,15 +14,16 @@ import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/bloc_util.dart';
|
import 'package:nc_photos/bloc_util.dart';
|
||||||
import 'package:nc_photos/controller/account_controller.dart';
|
import 'package:nc_photos/controller/account_controller.dart';
|
||||||
|
import 'package:nc_photos/controller/pref_controller.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/pref.dart';
|
import 'package:nc_photos/entity/pref.dart';
|
||||||
import 'package:nc_photos/entity/server_status.dart';
|
import 'package:nc_photos/entity/server_status.dart';
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/event/event.dart';
|
|
||||||
import 'package:nc_photos/exception_event.dart';
|
import 'package:nc_photos/exception_event.dart';
|
||||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/help_utils.dart' as help_util;
|
import 'package:nc_photos/help_utils.dart' as help_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/stream_util.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/toast.dart';
|
import 'package:nc_photos/toast.dart';
|
||||||
import 'package:nc_photos/url_launcher_util.dart';
|
import 'package:nc_photos/url_launcher_util.dart';
|
||||||
|
@ -50,6 +50,7 @@ class AccountPickerDialog extends StatelessWidget {
|
||||||
create: (context) => _Bloc(
|
create: (context) => _Bloc(
|
||||||
container: KiwiContainer().resolve(),
|
container: KiwiContainer().resolve(),
|
||||||
accountController: context.read(),
|
accountController: context.read(),
|
||||||
|
prefController: context.read(),
|
||||||
),
|
),
|
||||||
child: const _WrappedAccountPickerDialog(),
|
child: const _WrappedAccountPickerDialog(),
|
||||||
);
|
);
|
||||||
|
@ -112,13 +113,27 @@ class _WrappedAccountPickerDialog extends StatelessWidget {
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!Pref().isFollowSystemThemeOr(false))
|
ValueStreamBuilder<bool>(
|
||||||
Align(
|
stream: context
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
.read<PrefController>()
|
||||||
child: _DarkModeSwitch(
|
.isFollowSystemTheme,
|
||||||
onChanged: _onDarkModeChanged,
|
builder: (_, isFollowSystemTheme) {
|
||||||
),
|
if (!isFollowSystemTheme.requireData) {
|
||||||
),
|
return Align(
|
||||||
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
|
child: _DarkModeSwitch(
|
||||||
|
onChanged: (value) {
|
||||||
|
context
|
||||||
|
.read<_Bloc>()
|
||||||
|
.add(_SetDarkTheme(value));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
@ -192,12 +207,6 @@ class _WrappedAccountPickerDialog extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onDarkModeChanged(bool value) {
|
|
||||||
Pref().setDarkTheme(value).then((_) {
|
|
||||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DarkModeSwitch extends StatelessWidget {
|
class _DarkModeSwitch extends StatelessWidget {
|
||||||
|
|
|
@ -89,6 +89,13 @@ extension _$_DeleteAccountToString on _DeleteAccount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension _$_SetDarkThemeToString on _SetDarkTheme {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "_SetDarkTheme {value: $value}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension _$_SetErrorToString on _SetError {
|
extension _$_SetErrorToString on _SetError {
|
||||||
String _$toString() {
|
String _$toString() {
|
||||||
// ignore: unnecessary_string_interpolations
|
// ignore: unnecessary_string_interpolations
|
||||||
|
|
|
@ -5,6 +5,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
||||||
_Bloc({
|
_Bloc({
|
||||||
required DiContainer container,
|
required DiContainer container,
|
||||||
required this.accountController,
|
required this.accountController,
|
||||||
|
required this.prefController,
|
||||||
}) : _c = container,
|
}) : _c = container,
|
||||||
super(_State.init(
|
super(_State.init(
|
||||||
accounts: container.pref.getAccounts3Or([]),
|
accounts: container.pref.getAccounts3Or([]),
|
||||||
|
@ -12,6 +13,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
||||||
on<_ToggleDropdown>(_onToggleDropdown);
|
on<_ToggleDropdown>(_onToggleDropdown);
|
||||||
on<_SwitchAccount>(_onSwitchAccount);
|
on<_SwitchAccount>(_onSwitchAccount);
|
||||||
on<_DeleteAccount>(_onDeleteAccount);
|
on<_DeleteAccount>(_onDeleteAccount);
|
||||||
|
on<_SetDarkTheme>(_onSetDarkTheme);
|
||||||
|
|
||||||
on<_SetError>(_onSetError);
|
on<_SetError>(_onSetError);
|
||||||
}
|
}
|
||||||
|
@ -86,6 +88,11 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onSetDarkTheme(_SetDarkTheme ev, Emitter<_State> emit) {
|
||||||
|
_log.info(ev);
|
||||||
|
prefController.setDarkTheme(ev.value);
|
||||||
|
}
|
||||||
|
|
||||||
void _onSetError(_SetError ev, Emitter<_State> emit) {
|
void _onSetError(_SetError ev, Emitter<_State> emit) {
|
||||||
_log.info(ev);
|
_log.info(ev);
|
||||||
emit(state.copyWith(error: ExceptionEvent(ev.error, ev.stackTrace)));
|
emit(state.copyWith(error: ExceptionEvent(ev.error, ev.stackTrace)));
|
||||||
|
@ -104,6 +111,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
||||||
|
|
||||||
final DiContainer _c;
|
final DiContainer _c;
|
||||||
final AccountController accountController;
|
final AccountController accountController;
|
||||||
|
final PrefController prefController;
|
||||||
late final Account activeAccount = accountController.account;
|
late final Account activeAccount = accountController.account;
|
||||||
|
|
||||||
final _prefLock = Mutex();
|
final _prefLock = Mutex();
|
||||||
|
|
|
@ -60,6 +60,16 @@ class _DeleteAccount implements _Event {
|
||||||
final Account account;
|
final Account account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class _SetDarkTheme implements _Event {
|
||||||
|
const _SetDarkTheme(this.value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
final bool value;
|
||||||
|
}
|
||||||
|
|
||||||
@toString
|
@toString
|
||||||
class _SetError implements _Event {
|
class _SetError implements _Event {
|
||||||
const _SetError(this.error, [this.stackTrace]);
|
const _SetError(this.error, [this.stackTrace]);
|
||||||
|
|
|
@ -73,7 +73,7 @@ class _ConnectState extends State<Connect> {
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme().copyWith(
|
data: buildDarkTheme(context).copyWith(
|
||||||
scaffoldBackgroundColor: Theme.of(context).nextcloudBlue,
|
scaffoldBackgroundColor: Theme.of(context).nextcloudBlue,
|
||||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
|
|
@ -87,7 +87,7 @@ class _ImageEditorState extends State<ImageEditor> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) => Theme(
|
build(BuildContext context) => Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Builder(
|
body: Builder(
|
||||||
builder: _buildContent,
|
builder: _buildContent,
|
||||||
|
|
|
@ -88,7 +88,7 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) => Theme(
|
build(BuildContext context) => Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Builder(
|
body: Builder(
|
||||||
builder: _buildContent,
|
builder: _buildContent,
|
||||||
|
|
|
@ -53,7 +53,7 @@ class _LocalFileViewerState extends State<LocalFileViewer> {
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Builder(
|
body: Builder(
|
||||||
builder: _buildContent,
|
builder: _buildContent,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:copy_with/copy_with.dart';
|
||||||
import 'package:dynamic_color/dynamic_color.dart';
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -6,18 +7,16 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:nc_photos/bloc_util.dart';
|
||||||
import 'package:nc_photos/controller/account_controller.dart';
|
import 'package:nc_photos/controller/account_controller.dart';
|
||||||
import 'package:nc_photos/controller/pref_controller.dart';
|
import 'package:nc_photos/controller/pref_controller.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/pref.dart';
|
|
||||||
import 'package:nc_photos/event/event.dart';
|
|
||||||
import 'package:nc_photos/language_util.dart' as language_util;
|
import 'package:nc_photos/language_util.dart' as language_util;
|
||||||
import 'package:nc_photos/legacy/connect.dart' as legacy;
|
import 'package:nc_photos/legacy/connect.dart' as legacy;
|
||||||
import 'package:nc_photos/legacy/sign_in.dart' as legacy;
|
import 'package:nc_photos/legacy/sign_in.dart' as legacy;
|
||||||
import 'package:nc_photos/navigation_manager.dart';
|
import 'package:nc_photos/navigation_manager.dart';
|
||||||
import 'package:nc_photos/session_storage.dart';
|
import 'package:nc_photos/session_storage.dart';
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/stream_util.dart';
|
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/widget/album_dir_picker.dart';
|
import 'package:nc_photos/widget/album_dir_picker.dart';
|
||||||
import 'package:nc_photos/widget/album_importer.dart';
|
import 'package:nc_photos/widget/album_importer.dart';
|
||||||
|
@ -51,8 +50,15 @@ import 'package:nc_photos/widget/trashbin_browser.dart';
|
||||||
import 'package:nc_photos/widget/trashbin_viewer.dart';
|
import 'package:nc_photos/widget/trashbin_viewer.dart';
|
||||||
import 'package:nc_photos/widget/viewer.dart';
|
import 'package:nc_photos/widget/viewer.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'my_app.g.dart';
|
part 'my_app.g.dart';
|
||||||
|
part 'my_app/bloc.dart';
|
||||||
|
part 'my_app/state_event.dart';
|
||||||
|
|
||||||
|
typedef _BlocBuilder = BlocBuilder<_Bloc, _State>;
|
||||||
|
// typedef _BlocListener = BlocListener<_Bloc, _State>;
|
||||||
|
// typedef _BlocSelector<T> = BlocSelector<_Bloc, _State, T>;
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
const MyApp({super.key});
|
const MyApp({super.key});
|
||||||
|
@ -69,7 +75,12 @@ class MyApp extends StatelessWidget {
|
||||||
create: (_) => PrefController(_c),
|
create: (_) => PrefController(_c),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: const _WrappedApp(),
|
child: BlocProvider(
|
||||||
|
create: (context) => _Bloc(
|
||||||
|
prefController: context.read(),
|
||||||
|
),
|
||||||
|
child: const _WrappedApp(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,43 +107,48 @@ class _WrappedAppState extends State<_WrappedApp>
|
||||||
super.initState();
|
super.initState();
|
||||||
SnackBarManager().registerHandler(this);
|
SnackBarManager().registerHandler(this);
|
||||||
NavigationManager().setHandler(this);
|
NavigationManager().setHandler(this);
|
||||||
_themeChangedListener =
|
|
||||||
AppEventListener<ThemeChangedEvent>(_onThemeChangedEvent)..begin();
|
_bloc.add(const _Init());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ThemeMode themeMode;
|
return _BlocBuilder(
|
||||||
if (Pref().isFollowSystemThemeOr(false)) {
|
buildWhen: (previous, current) =>
|
||||||
themeMode = ThemeMode.system;
|
previous.language != current.language ||
|
||||||
} else {
|
previous.isDarkTheme != current.isDarkTheme ||
|
||||||
themeMode =
|
previous.isFollowSystemTheme != current.isFollowSystemTheme ||
|
||||||
Pref().isDarkThemeOr(false) ? ThemeMode.dark : ThemeMode.light;
|
previous.isUseBlackInDarkTheme != current.isUseBlackInDarkTheme ||
|
||||||
}
|
previous.seedColor != current.seedColor,
|
||||||
final prefController = context.read<PrefController>();
|
builder: (context, state) => DynamicColorBuilder(
|
||||||
return ValueStreamBuilder<language_util.AppLanguage>(
|
|
||||||
stream: prefController.language,
|
|
||||||
builder: (context, snapshot) => DynamicColorBuilder(
|
|
||||||
builder: (lightDynamic, darkDynamic) {
|
builder: (lightDynamic, darkDynamic) {
|
||||||
if (lightDynamic != null) {
|
if (lightDynamic != null) {
|
||||||
SessionStorage().isSupportDynamicColor = true;
|
SessionStorage().isSupportDynamicColor = true;
|
||||||
}
|
}
|
||||||
|
final ThemeMode themeMode;
|
||||||
|
if (state.isFollowSystemTheme) {
|
||||||
|
themeMode = ThemeMode.system;
|
||||||
|
} else {
|
||||||
|
themeMode = state.isDarkTheme ? ThemeMode.dark : ThemeMode.light;
|
||||||
|
}
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
onGenerateTitle: (context) =>
|
onGenerateTitle: (context) =>
|
||||||
AppLocalizations.of(context)!.appTitle,
|
AppLocalizations.of(context)!.appTitle,
|
||||||
theme: buildLightTheme(lightDynamic),
|
theme: buildLightTheme(context, lightDynamic),
|
||||||
darkTheme: buildDarkTheme(darkDynamic),
|
darkTheme: buildDarkTheme(context, darkDynamic),
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
initialRoute: Splash.routeName,
|
initialRoute: Splash.routeName,
|
||||||
onGenerateRoute: _onGenerateRoute,
|
onGenerateRoute: _onGenerateRoute,
|
||||||
navigatorObservers: <NavigatorObserver>[MyApp.routeObserver],
|
navigatorObservers: [
|
||||||
|
MyApp.routeObserver,
|
||||||
|
],
|
||||||
navigatorKey: _navigatorKey,
|
navigatorKey: _navigatorKey,
|
||||||
scaffoldMessengerKey: _scaffoldMessengerKey,
|
scaffoldMessengerKey: _scaffoldMessengerKey,
|
||||||
locale: snapshot.requireData.locale,
|
locale: state.language.locale,
|
||||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
supportedLocales: const <Locale>[
|
supportedLocales: const [
|
||||||
// the order here doesn't matter, except for the first one, which must
|
// the order here doesn't matter, except for the first one, which
|
||||||
// be en
|
// must be en
|
||||||
Locale("en"),
|
Locale("en"),
|
||||||
Locale("el"),
|
Locale("el"),
|
||||||
Locale("es"),
|
Locale("es"),
|
||||||
|
@ -166,7 +182,6 @@ class _WrappedAppState extends State<_WrappedApp>
|
||||||
super.dispose();
|
super.dispose();
|
||||||
SnackBarManager().unregisterHandler(this);
|
SnackBarManager().unregisterHandler(this);
|
||||||
NavigationManager().unsetHandler(this);
|
NavigationManager().unsetHandler(this);
|
||||||
_themeChangedListener.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -227,10 +242,6 @@ class _WrappedAppState extends State<_WrappedApp>
|
||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onThemeChangedEvent(ThemeChangedEvent ev) {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
Route<dynamic>? _handleBasicRoute(RouteSettings settings) {
|
Route<dynamic>? _handleBasicRoute(RouteSettings settings) {
|
||||||
for (final e in _getRouter().entries) {
|
for (final e in _getRouter().entries) {
|
||||||
if (e.key == settings.name) {
|
if (e.key == settings.name) {
|
||||||
|
@ -578,10 +589,9 @@ class _WrappedAppState extends State<_WrappedApp>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
late final _bloc = context.read<_Bloc>();
|
||||||
final _scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
|
final _scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
|
||||||
final _navigatorKey = GlobalKey<NavigatorState>();
|
final _navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
late AppEventListener<ThemeChangedEvent> _themeChangedListener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ThemedMyApp extends StatelessWidget {
|
class _ThemedMyApp extends StatelessWidget {
|
||||||
|
|
|
@ -2,6 +2,54 @@
|
||||||
|
|
||||||
part of 'my_app.dart';
|
part of 'my_app.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// CopyWithLintRuleGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// ignore_for_file: library_private_types_in_public_api, duplicate_ignore
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// CopyWithGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
abstract class $_StateCopyWithWorker {
|
||||||
|
_State call(
|
||||||
|
{language_util.AppLanguage? language,
|
||||||
|
bool? isDarkTheme,
|
||||||
|
bool? isFollowSystemTheme,
|
||||||
|
bool? isUseBlackInDarkTheme,
|
||||||
|
int? seedColor});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
|
||||||
|
_$_StateCopyWithWorkerImpl(this.that);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_State call(
|
||||||
|
{dynamic language,
|
||||||
|
dynamic isDarkTheme,
|
||||||
|
dynamic isFollowSystemTheme,
|
||||||
|
dynamic isUseBlackInDarkTheme,
|
||||||
|
dynamic seedColor = copyWithNull}) {
|
||||||
|
return _State(
|
||||||
|
language: language as language_util.AppLanguage? ?? that.language,
|
||||||
|
isDarkTheme: isDarkTheme as bool? ?? that.isDarkTheme,
|
||||||
|
isFollowSystemTheme:
|
||||||
|
isFollowSystemTheme as bool? ?? that.isFollowSystemTheme,
|
||||||
|
isUseBlackInDarkTheme:
|
||||||
|
isUseBlackInDarkTheme as bool? ?? that.isUseBlackInDarkTheme,
|
||||||
|
seedColor:
|
||||||
|
seedColor == copyWithNull ? that.seedColor : seedColor as int?);
|
||||||
|
}
|
||||||
|
|
||||||
|
final _State that;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $_StateCopyWith on _State {
|
||||||
|
$_StateCopyWithWorker get copyWith => _$copyWith;
|
||||||
|
$_StateCopyWithWorker get _$copyWith => _$_StateCopyWithWorkerImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// NpLogGenerator
|
// NpLogGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -12,3 +60,28 @@ extension _$_WrappedAppStateNpLog on _WrappedAppState {
|
||||||
|
|
||||||
static final log = Logger("widget.my_app._WrappedAppState");
|
static final log = Logger("widget.my_app._WrappedAppState");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension _$_BlocNpLog on _Bloc {
|
||||||
|
// ignore: unused_element
|
||||||
|
Logger get _log => log;
|
||||||
|
|
||||||
|
static final log = Logger("widget.my_app._Bloc");
|
||||||
|
}
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// ToStringGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
extension _$_StateToString on _State {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "_State {language: $language, isDarkTheme: $isDarkTheme, isFollowSystemTheme: $isFollowSystemTheme, isUseBlackInDarkTheme: $isUseBlackInDarkTheme, seedColor: $seedColor}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$_InitToString on _Init {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "_Init {}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
47
app/lib/widget/my_app/bloc.dart
Normal file
47
app/lib/widget/my_app/bloc.dart
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
part of '../my_app.dart';
|
||||||
|
|
||||||
|
@npLog
|
||||||
|
class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
||||||
|
_Bloc({
|
||||||
|
required this.prefController,
|
||||||
|
}) : super(_State(
|
||||||
|
language: prefController.language.value,
|
||||||
|
isDarkTheme: prefController.isDarkTheme.value,
|
||||||
|
isFollowSystemTheme: prefController.isFollowSystemTheme.value,
|
||||||
|
isUseBlackInDarkTheme: prefController.isUseBlackInDarkTheme.value,
|
||||||
|
seedColor: prefController.seedColor.value?.value,
|
||||||
|
)) {
|
||||||
|
on<_Init>(_onInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tag => _log.fullName;
|
||||||
|
|
||||||
|
Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
|
||||||
|
_log.info(ev);
|
||||||
|
await Future.wait([
|
||||||
|
emit.forEachIgnoreError<language_util.AppLanguage>(
|
||||||
|
prefController.language,
|
||||||
|
onData: (data) => state.copyWith(language: data),
|
||||||
|
),
|
||||||
|
emit.forEachIgnoreError<bool>(
|
||||||
|
prefController.isDarkTheme,
|
||||||
|
onData: (data) => state.copyWith(isDarkTheme: data),
|
||||||
|
),
|
||||||
|
emit.forEachIgnoreError<bool>(
|
||||||
|
prefController.isFollowSystemTheme,
|
||||||
|
onData: (data) => state.copyWith(isFollowSystemTheme: data),
|
||||||
|
),
|
||||||
|
emit.forEachIgnoreError<bool>(
|
||||||
|
prefController.isUseBlackInDarkTheme,
|
||||||
|
onData: (data) => state.copyWith(isUseBlackInDarkTheme: data),
|
||||||
|
),
|
||||||
|
emit.forEachIgnoreError<Color?>(
|
||||||
|
prefController.seedColor,
|
||||||
|
onData: (data) => state.copyWith(seedColor: data?.value),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PrefController prefController;
|
||||||
|
}
|
32
app/lib/widget/my_app/state_event.dart
Normal file
32
app/lib/widget/my_app/state_event.dart
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
part of '../my_app.dart';
|
||||||
|
|
||||||
|
@genCopyWith
|
||||||
|
@toString
|
||||||
|
class _State {
|
||||||
|
const _State({
|
||||||
|
required this.language,
|
||||||
|
required this.isDarkTheme,
|
||||||
|
required this.isFollowSystemTheme,
|
||||||
|
required this.isUseBlackInDarkTheme,
|
||||||
|
required this.seedColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
final language_util.AppLanguage language;
|
||||||
|
final bool isDarkTheme;
|
||||||
|
final bool isFollowSystemTheme;
|
||||||
|
final bool isUseBlackInDarkTheme;
|
||||||
|
final int? seedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Event {}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class _Init implements _Event {
|
||||||
|
const _Init();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ class _ResultViewerState extends State<ResultViewer> {
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
if (_file == null) {
|
if (_file == null) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
|
|
|
@ -1,76 +1,68 @@
|
||||||
part of '../theme_settings.dart';
|
part of '../theme_settings.dart';
|
||||||
|
|
||||||
class _Error {
|
|
||||||
const _Error(this.ev);
|
|
||||||
|
|
||||||
final _Event ev;
|
|
||||||
}
|
|
||||||
|
|
||||||
@npLog
|
@npLog
|
||||||
class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
class _Bloc extends Bloc<_Event, _State> with BlocLogger {
|
||||||
_Bloc(DiContainer c)
|
_Bloc({
|
||||||
: assert(require(c)),
|
required this.prefController,
|
||||||
_c = c,
|
}) : super(_State(
|
||||||
super(_State(
|
isFollowSystemTheme: prefController.isFollowSystemTheme.value,
|
||||||
isFollowSystemTheme: c.pref.isFollowSystemThemeOr(false),
|
isUseBlackInDarkTheme: prefController.isUseBlackInDarkTheme.value,
|
||||||
isUseBlackInDarkTheme: c.pref.isUseBlackInDarkThemeOr(false),
|
seedColor: prefController.seedColor.value?.value,
|
||||||
seedColor: getSeedColor()?.value,
|
|
||||||
)) {
|
)) {
|
||||||
|
on<_Init>(_onInit);
|
||||||
on<_SetFollowSystemTheme>(_onSetFollowSystemTheme);
|
on<_SetFollowSystemTheme>(_onSetFollowSystemTheme);
|
||||||
on<_SetUseBlackInDarkTheme>(_onSetUseBlackInDarkTheme);
|
on<_SetUseBlackInDarkTheme>(_onSetUseBlackInDarkTheme);
|
||||||
on<_SetSeedColor>(_onSetSeedColor);
|
on<_SetSeedColor>(_onSetSeedColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.pref);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tag => _log.fullName;
|
String get tag => _log.fullName;
|
||||||
|
|
||||||
Stream<_Error> errorStream() => _errorStream.stream;
|
Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
|
||||||
|
|
||||||
Future<void> _onSetFollowSystemTheme(
|
|
||||||
_SetFollowSystemTheme ev, Emitter<_State> emit) async {
|
|
||||||
_log.info(ev);
|
_log.info(ev);
|
||||||
final oldValue = state.isFollowSystemTheme;
|
await Future.wait([
|
||||||
emit(state.copyWith(isFollowSystemTheme: ev.value));
|
emit.forEach<bool>(
|
||||||
if (await _c.pref.setFollowSystemTheme(ev.value)) {
|
prefController.isFollowSystemTheme,
|
||||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
onData: (data) => state.copyWith(isFollowSystemTheme: data),
|
||||||
} else {
|
onError: (e, stackTrace) {
|
||||||
_log.severe("[_onSetFollowSystemTheme] Failed writing pref");
|
_log.severe("[_onInit] Uncaught exception", e, stackTrace);
|
||||||
_errorStream.add(_Error(ev));
|
return state.copyWith(error: ExceptionEvent(e, stackTrace));
|
||||||
emit(state.copyWith(isFollowSystemTheme: oldValue));
|
},
|
||||||
}
|
),
|
||||||
|
emit.forEach<bool>(
|
||||||
|
prefController.isUseBlackInDarkTheme,
|
||||||
|
onData: (data) => state.copyWith(isUseBlackInDarkTheme: data),
|
||||||
|
onError: (e, stackTrace) {
|
||||||
|
_log.severe("[_onInit] Uncaught exception", e, stackTrace);
|
||||||
|
return state.copyWith(error: ExceptionEvent(e, stackTrace));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
emit.forEach<Color?>(
|
||||||
|
prefController.seedColor,
|
||||||
|
onData: (data) => state.copyWith(seedColor: data?.value),
|
||||||
|
onError: (e, stackTrace) {
|
||||||
|
_log.severe("[_onInit] Uncaught exception", e, stackTrace);
|
||||||
|
return state.copyWith(error: ExceptionEvent(e, stackTrace));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSetUseBlackInDarkTheme(
|
void _onSetFollowSystemTheme(_SetFollowSystemTheme ev, Emitter<_State> emit) {
|
||||||
_SetUseBlackInDarkTheme ev, Emitter<_State> emit) async {
|
|
||||||
_log.info(ev);
|
_log.info(ev);
|
||||||
final oldValue = state.isUseBlackInDarkTheme;
|
prefController.setFollowSystemTheme(ev.value);
|
||||||
emit(state.copyWith(isUseBlackInDarkTheme: ev.value));
|
|
||||||
if (await _c.pref.setUseBlackInDarkTheme(ev.value)) {
|
|
||||||
if (ev.theme.brightness == Brightness.dark) {
|
|
||||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_log.severe("[_onSetUseBlackInDarkTheme] Failed writing pref");
|
|
||||||
_errorStream.add(_Error(ev));
|
|
||||||
emit(state.copyWith(isUseBlackInDarkTheme: oldValue));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSetSeedColor(_SetSeedColor ev, Emitter<_State> emit) async {
|
void _onSetUseBlackInDarkTheme(
|
||||||
|
_SetUseBlackInDarkTheme ev, Emitter<_State> emit) {
|
||||||
_log.info(ev);
|
_log.info(ev);
|
||||||
final oldValue = state.seedColor;
|
prefController.setUseBlackInDarkTheme(ev.value);
|
||||||
emit(state.copyWith(seedColor: ev.value?.value));
|
|
||||||
if (await _c.pref.setSeedColor(ev.value?.withAlpha(0xFF).value)) {
|
|
||||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
|
||||||
} else {
|
|
||||||
_log.severe("[_onSetSeedColor] Failed writing pref");
|
|
||||||
_errorStream.add(_Error(ev));
|
|
||||||
emit(state.copyWith(seedColor: oldValue));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final DiContainer _c;
|
void _onSetSeedColor(_SetSeedColor ev, Emitter<_State> emit) {
|
||||||
final _errorStream = StreamController<_Error>.broadcast();
|
_log.info(ev);
|
||||||
|
prefController.setSeedColor(ev.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PrefController prefController;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ class _State {
|
||||||
required this.isFollowSystemTheme,
|
required this.isFollowSystemTheme,
|
||||||
required this.isUseBlackInDarkTheme,
|
required this.isUseBlackInDarkTheme,
|
||||||
required this.seedColor,
|
required this.seedColor,
|
||||||
|
this.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -16,12 +17,22 @@ class _State {
|
||||||
final bool isUseBlackInDarkTheme;
|
final bool isUseBlackInDarkTheme;
|
||||||
// workaround analyzer bug where Color type can't be recognized
|
// workaround analyzer bug where Color type can't be recognized
|
||||||
final int? seedColor;
|
final int? seedColor;
|
||||||
|
|
||||||
|
final ExceptionEvent? error;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _Event {
|
abstract class _Event {
|
||||||
const _Event();
|
const _Event();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class _Init implements _Event {
|
||||||
|
const _Init();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
}
|
||||||
|
|
||||||
@toString
|
@toString
|
||||||
class _SetFollowSystemTheme extends _Event {
|
class _SetFollowSystemTheme extends _Event {
|
||||||
const _SetFollowSystemTheme(this.value);
|
const _SetFollowSystemTheme(this.value);
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:copy_with/copy_with.dart';
|
import 'package:copy_with/copy_with.dart';
|
||||||
import 'package:event_bus/event_bus.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/bloc_util.dart';
|
import 'package:nc_photos/bloc_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/controller/pref_controller.dart';
|
||||||
import 'package:nc_photos/entity/pref.dart';
|
import 'package:nc_photos/exception_event.dart';
|
||||||
import 'package:nc_photos/event/event.dart';
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/mobile/android/android_info.dart';
|
import 'package:nc_photos/mobile/android/android_info.dart';
|
||||||
|
import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos/session_storage.dart';
|
import 'package:nc_photos/session_storage.dart';
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
|
import 'package:nc_photos/widget/page_visibility_mixin.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
|
@ -25,7 +25,9 @@ part 'theme/bloc.dart';
|
||||||
part 'theme/state_event.dart';
|
part 'theme/state_event.dart';
|
||||||
part 'theme_settings.g.dart';
|
part 'theme_settings.g.dart';
|
||||||
|
|
||||||
typedef _BlocBuilder = BlocBuilder<_Bloc, _State>;
|
// typedef _BlocBuilder = BlocBuilder<_Bloc, _State>;
|
||||||
|
typedef _BlocListener = BlocListener<_Bloc, _State>;
|
||||||
|
typedef _BlocSelector<T> = BlocSelector<_Bloc, _State, T>;
|
||||||
|
|
||||||
class ThemeSettings extends StatelessWidget {
|
class ThemeSettings extends StatelessWidget {
|
||||||
const ThemeSettings({super.key});
|
const ThemeSettings({super.key});
|
||||||
|
@ -33,7 +35,9 @@ class ThemeSettings extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) => _Bloc(KiwiContainer().resolve<DiContainer>()),
|
create: (_) => _Bloc(
|
||||||
|
prefController: context.read(),
|
||||||
|
),
|
||||||
child: const _WrappedThemeSettings(),
|
child: const _WrappedThemeSettings(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -47,89 +51,86 @@ class _WrappedThemeSettings extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
@npLog
|
@npLog
|
||||||
class _WrappedThemeSettingsState extends State<_WrappedThemeSettings> {
|
class _WrappedThemeSettingsState extends State<_WrappedThemeSettings>
|
||||||
|
with RouteAware, PageVisibilityMixin {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_errorSubscription = _bloc.errorStream().listen((_) {
|
_bloc.add(const _Init());
|
||||||
SnackBarManager().showSnackBar(SnackBar(
|
|
||||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
|
||||||
duration: k.snackBarDurationNormal,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_errorSubscription.cancel();
|
|
||||||
super.dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Builder(
|
body: MultiBlocListener(
|
||||||
builder: (context) => _buildContent(context),
|
listeners: [
|
||||||
|
_BlocListener(
|
||||||
|
listenWhen: (previous, current) => previous.error != current.error,
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state.error != null && isPageVisible()) {
|
||||||
|
SnackBarManager().showSnackBar(SnackBar(
|
||||||
|
content:
|
||||||
|
Text(exception_util.toUserString(state.error!.error)),
|
||||||
|
duration: k.snackBarDurationNormal,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverAppBar(
|
||||||
|
pinned: true,
|
||||||
|
title: Text(L10n.global().settingsThemeTitle),
|
||||||
|
),
|
||||||
|
SliverList(
|
||||||
|
delegate: SliverChildListDelegate(
|
||||||
|
[
|
||||||
|
const _SeedColorOption(),
|
||||||
|
if (platform_k.isAndroid &&
|
||||||
|
AndroidInfo().sdkInt >= AndroidVersion.Q)
|
||||||
|
_BlocSelector<bool>(
|
||||||
|
selector: (state) => state.isFollowSystemTheme,
|
||||||
|
builder: (_, isFollowSystemTheme) {
|
||||||
|
return SwitchListTile(
|
||||||
|
title: Text(
|
||||||
|
L10n.global().settingsFollowSystemThemeTitle),
|
||||||
|
value: isFollowSystemTheme,
|
||||||
|
onChanged: (value) {
|
||||||
|
_bloc.add(_SetFollowSystemTheme(value));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
_BlocSelector<bool>(
|
||||||
|
selector: (state) => state.isUseBlackInDarkTheme,
|
||||||
|
builder: (context, isUseBlackInDarkTheme) {
|
||||||
|
return SwitchListTile(
|
||||||
|
title: Text(
|
||||||
|
L10n.global().settingsUseBlackInDarkThemeTitle),
|
||||||
|
subtitle: Text(isUseBlackInDarkTheme
|
||||||
|
? L10n.global()
|
||||||
|
.settingsUseBlackInDarkThemeTrueDescription
|
||||||
|
: L10n.global()
|
||||||
|
.settingsUseBlackInDarkThemeFalseDescription),
|
||||||
|
value: isUseBlackInDarkTheme,
|
||||||
|
onChanged: (value) {
|
||||||
|
_bloc.add(_SetUseBlackInDarkTheme(
|
||||||
|
value, Theme.of(context)));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContent(BuildContext context) {
|
|
||||||
return CustomScrollView(
|
|
||||||
slivers: [
|
|
||||||
SliverAppBar(
|
|
||||||
pinned: true,
|
|
||||||
title: Text(L10n.global().settingsThemeTitle),
|
|
||||||
),
|
|
||||||
SliverList(
|
|
||||||
delegate: SliverChildListDelegate(
|
|
||||||
[
|
|
||||||
const _SeedColorOption(),
|
|
||||||
if (platform_k.isAndroid &&
|
|
||||||
AndroidInfo().sdkInt >= AndroidVersion.Q)
|
|
||||||
_BlocBuilder(
|
|
||||||
buildWhen: (previous, current) =>
|
|
||||||
previous.isFollowSystemTheme !=
|
|
||||||
current.isFollowSystemTheme,
|
|
||||||
builder: (context, state) {
|
|
||||||
return SwitchListTile(
|
|
||||||
title: Text(L10n.global().settingsFollowSystemThemeTitle),
|
|
||||||
value: state.isFollowSystemTheme,
|
|
||||||
onChanged: (value) {
|
|
||||||
_bloc.add(_SetFollowSystemTheme(value));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
_BlocBuilder(
|
|
||||||
buildWhen: (previous, current) =>
|
|
||||||
previous.isUseBlackInDarkTheme !=
|
|
||||||
current.isUseBlackInDarkTheme,
|
|
||||||
builder: (context, state) {
|
|
||||||
return SwitchListTile(
|
|
||||||
title: Text(L10n.global().settingsUseBlackInDarkThemeTitle),
|
|
||||||
subtitle: Text(state.isUseBlackInDarkTheme
|
|
||||||
? L10n.global()
|
|
||||||
.settingsUseBlackInDarkThemeTrueDescription
|
|
||||||
: L10n.global()
|
|
||||||
.settingsUseBlackInDarkThemeFalseDescription),
|
|
||||||
value: state.isUseBlackInDarkTheme,
|
|
||||||
onChanged: (value) {
|
|
||||||
_bloc.add(
|
|
||||||
_SetUseBlackInDarkTheme(value, Theme.of(context)));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _bloc = context.read<_Bloc>();
|
late final _bloc = context.read<_Bloc>();
|
||||||
late final StreamSubscription _errorSubscription;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SeedColorOption extends StatelessWidget {
|
class _SeedColorOption extends StatelessWidget {
|
||||||
|
@ -137,21 +138,21 @@ class _SeedColorOption extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return _BlocBuilder(
|
return _BlocSelector<int?>(
|
||||||
buildWhen: (previous, current) => previous.seedColor != current.seedColor,
|
selector: (state) => state.seedColor,
|
||||||
builder: (context, state) {
|
builder: (context, seedColor) {
|
||||||
if (SessionStorage().isSupportDynamicColor) {
|
if (SessionStorage().isSupportDynamicColor) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(L10n.global().settingsSeedColorTitle),
|
title: Text(L10n.global().settingsSeedColorTitle),
|
||||||
subtitle: Text(state.seedColor == null
|
subtitle: Text(seedColor == null
|
||||||
? L10n.global().settingsSeedColorSystemColorDescription
|
? L10n.global().settingsSeedColorSystemColorDescription
|
||||||
: L10n.global().settingsSeedColorDescription),
|
: L10n.global().settingsSeedColorDescription),
|
||||||
trailing: state.seedColor == null
|
trailing: seedColor == null
|
||||||
? null
|
? null
|
||||||
: Icon(
|
: Icon(
|
||||||
Icons.circle,
|
Icons.circle,
|
||||||
size: 32,
|
size: 32,
|
||||||
color: Color(state.seedColor!),
|
color: Color(seedColor),
|
||||||
),
|
),
|
||||||
onTap: () => _onSeedColorPressed(context),
|
onTap: () => _onSeedColorPressed(context),
|
||||||
);
|
);
|
||||||
|
@ -162,7 +163,7 @@ class _SeedColorOption extends StatelessWidget {
|
||||||
trailing: Icon(
|
trailing: Icon(
|
||||||
Icons.circle,
|
Icons.circle,
|
||||||
size: 32,
|
size: 32,
|
||||||
color: Color(state.seedColor ?? defaultSeedColor),
|
color: seedColor?.run(Color.new) ?? defaultSeedColor,
|
||||||
),
|
),
|
||||||
onTap: () => _onSeedColorPressed(context),
|
onTap: () => _onSeedColorPressed(context),
|
||||||
);
|
);
|
||||||
|
@ -281,7 +282,7 @@ class _SeedColorCustomPickerState extends State<_SeedColorCustomPicker> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late Color _customColor = getSeedColor() ?? const Color(defaultSeedColor);
|
late var _customColor = getSeedColor(context) ?? defaultSeedColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SeedColorPickerItem extends StatelessWidget {
|
class _SeedColorPickerItem extends StatelessWidget {
|
||||||
|
|
|
@ -14,7 +14,10 @@ part of 'theme_settings.dart';
|
||||||
|
|
||||||
abstract class $_StateCopyWithWorker {
|
abstract class $_StateCopyWithWorker {
|
||||||
_State call(
|
_State call(
|
||||||
{bool? isFollowSystemTheme, bool? isUseBlackInDarkTheme, int? seedColor});
|
{bool? isFollowSystemTheme,
|
||||||
|
bool? isUseBlackInDarkTheme,
|
||||||
|
int? seedColor,
|
||||||
|
ExceptionEvent? error});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
|
class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
|
||||||
|
@ -24,14 +27,16 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
|
||||||
_State call(
|
_State call(
|
||||||
{dynamic isFollowSystemTheme,
|
{dynamic isFollowSystemTheme,
|
||||||
dynamic isUseBlackInDarkTheme,
|
dynamic isUseBlackInDarkTheme,
|
||||||
dynamic seedColor = copyWithNull}) {
|
dynamic seedColor = copyWithNull,
|
||||||
|
dynamic error = copyWithNull}) {
|
||||||
return _State(
|
return _State(
|
||||||
isFollowSystemTheme:
|
isFollowSystemTheme:
|
||||||
isFollowSystemTheme as bool? ?? that.isFollowSystemTheme,
|
isFollowSystemTheme as bool? ?? that.isFollowSystemTheme,
|
||||||
isUseBlackInDarkTheme:
|
isUseBlackInDarkTheme:
|
||||||
isUseBlackInDarkTheme as bool? ?? that.isUseBlackInDarkTheme,
|
isUseBlackInDarkTheme as bool? ?? that.isUseBlackInDarkTheme,
|
||||||
seedColor:
|
seedColor:
|
||||||
seedColor == copyWithNull ? that.seedColor : seedColor as int?);
|
seedColor == copyWithNull ? that.seedColor : seedColor as int?,
|
||||||
|
error: error == copyWithNull ? that.error : error as ExceptionEvent?);
|
||||||
}
|
}
|
||||||
|
|
||||||
final _State that;
|
final _State that;
|
||||||
|
@ -68,7 +73,14 @@ extension _$_BlocNpLog on _Bloc {
|
||||||
extension _$_StateToString on _State {
|
extension _$_StateToString on _State {
|
||||||
String _$toString() {
|
String _$toString() {
|
||||||
// ignore: unnecessary_string_interpolations
|
// ignore: unnecessary_string_interpolations
|
||||||
return "_State {isFollowSystemTheme: $isFollowSystemTheme, isUseBlackInDarkTheme: $isUseBlackInDarkTheme, seedColor: $seedColor}";
|
return "_State {isFollowSystemTheme: $isFollowSystemTheme, isUseBlackInDarkTheme: $isUseBlackInDarkTheme, seedColor: $seedColor, error: $error}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$_InitToString on _Init {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "_Init {}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class _SignInState extends State<SignIn> {
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme().copyWith(
|
data: buildDarkTheme(context).copyWith(
|
||||||
scaffoldBackgroundColor: Colors.transparent,
|
scaffoldBackgroundColor: Colors.transparent,
|
||||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
|
|
@ -100,7 +100,7 @@ class _SlideshowViewerState extends State<SlideshowViewer>
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Builder(
|
body: Builder(
|
||||||
builder: _buildContent,
|
builder: _buildContent,
|
||||||
|
|
|
@ -65,7 +65,7 @@ class _TrashbinViewerState extends State<TrashbinViewer> {
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Builder(
|
body: Builder(
|
||||||
builder: _buildContent,
|
builder: _buildContent,
|
||||||
|
|
|
@ -120,7 +120,7 @@ class _ViewerState extends State<Viewer>
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
final originalBrightness = Theme.of(context).brightness;
|
final originalBrightness = Theme.of(context).brightness;
|
||||||
return Theme(
|
return Theme(
|
||||||
data: buildDarkTheme(),
|
data: buildDarkTheme(context),
|
||||||
child: AnnotatedRegion<SystemUiOverlayStyle>(
|
child: AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
value: const SystemUiOverlayStyle(
|
value: const SystemUiOverlayStyle(
|
||||||
systemNavigationBarColor: Colors.black,
|
systemNavigationBarColor: Colors.black,
|
||||||
|
@ -299,7 +299,7 @@ class _ViewerState extends State<Viewer>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Theme(
|
child: Theme(
|
||||||
data: buildTheme(originalBrightness),
|
data: buildTheme(context, originalBrightness),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
|
Loading…
Add table
Reference in a new issue