Refactor: Introduce LocaleController and ScaleController, unify text and language settings, and simplify AppSettingsView structure.
This commit is contained in:
@@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:fluttery/fluttery.dart';
|
import 'package:fluttery/fluttery.dart';
|
||||||
import 'package:fluttery/preferences.dart';
|
import 'package:fluttery/preferences.dart';
|
||||||
|
|
||||||
/// Controls the current app language (system, de, en, ...).
|
|
||||||
/// Loads the locale from Preferences or falls back to system default.
|
|
||||||
class LocaleController extends ChangeNotifier {
|
class LocaleController extends ChangeNotifier {
|
||||||
final Preferences _prefs;
|
final Preferences _prefs;
|
||||||
|
|
||||||
@@ -11,32 +9,36 @@ class LocaleController extends ChangeNotifier {
|
|||||||
|
|
||||||
static const _key = 'language';
|
static const _key = 'language';
|
||||||
|
|
||||||
String _current = 'system';
|
LanguagePref _current = LanguagePref.en; // Default = Englisch
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
final saved = await _prefs.getString(_key);
|
final saved = await _prefs.getString(_key);
|
||||||
_current = saved ?? 'system';
|
_current = switch (saved) {
|
||||||
|
'de' => LanguagePref.de,
|
||||||
|
'system' => LanguagePref.system,
|
||||||
|
'en' || _ => LanguagePref.en, // default fallback = en
|
||||||
|
};
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLanguage(String lang) {
|
void setLanguage(LanguagePref pref) {
|
||||||
_current = lang;
|
if (_current == pref) return;
|
||||||
|
_current = pref;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
_prefs.setString(_key, lang);
|
_prefs.setString(_key, pref.name); // fire-and-forget
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the actual Locale or null = system.
|
LanguagePref get language => _current;
|
||||||
Locale? get locale {
|
|
||||||
switch (_current) {
|
|
||||||
case 'de':
|
|
||||||
return const Locale('de');
|
|
||||||
case 'en':
|
|
||||||
return const Locale('en');
|
|
||||||
case 'system':
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String get language => _current;
|
Locale? get locale => _current.locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LanguagePref {
|
||||||
|
system(null), // folgt System
|
||||||
|
de(Locale('de')), // Deutsch
|
||||||
|
en(Locale('en')); // Englisch (default)
|
||||||
|
|
||||||
|
final Locale? locale;
|
||||||
|
|
||||||
|
const LanguagePref(this.locale);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:fluttery/fluttery.dart';
|
import 'package:fluttery/fluttery.dart';
|
||||||
import 'package:fluttery/preferences.dart';
|
import 'package:fluttery/preferences.dart';
|
||||||
|
|
||||||
/// Controls the current text scale (system, small, medium, large).
|
|
||||||
/// Loads the value from Preferences or falls back to system default.
|
|
||||||
class ScaleController extends ChangeNotifier {
|
class ScaleController extends ChangeNotifier {
|
||||||
final Preferences _prefs;
|
final Preferences _prefs;
|
||||||
|
|
||||||
@@ -11,37 +9,40 @@ class ScaleController extends ChangeNotifier {
|
|||||||
|
|
||||||
static const _key = 'textScale';
|
static const _key = 'textScale';
|
||||||
|
|
||||||
/// supported sizes
|
TextScalePref _current = TextScalePref.system;
|
||||||
static const Map<String, double> _factors = {
|
|
||||||
'system': 1.0,
|
|
||||||
'small': 0.9,
|
|
||||||
'medium': 1.1,
|
|
||||||
'large': 1.25,
|
|
||||||
};
|
|
||||||
|
|
||||||
String _current = 'system';
|
/// Faktor direkt vom Enum
|
||||||
|
double get factor => _current.factor;
|
||||||
|
|
||||||
/// Loads text scale from Preferences.
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
final saved = await _prefs.getString(_key);
|
final saved = await _prefs.getString(_key);
|
||||||
_current = saved ?? 'system';
|
_current = switch (saved) {
|
||||||
if (!_factors.containsKey(_current)) {
|
'small' => TextScalePref.small,
|
||||||
_current = 'system';
|
'medium' => TextScalePref.medium,
|
||||||
}
|
'large' => TextScalePref.large,
|
||||||
|
_ => TextScalePref.system,
|
||||||
|
};
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set text scale and persist.
|
/// Set text scale and persist.
|
||||||
void setScale(String scale) {
|
void setScale(TextScalePref pref) {
|
||||||
if (!_factors.containsKey(scale)) return;
|
if (_current == pref) return;
|
||||||
_current = scale;
|
_current = pref;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
_prefs.setString(_key, scale);
|
_prefs.setString(_key, pref.name); // fire-and-forget
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get current factor (e.g. for MediaQuery.textScaler)
|
TextScalePref get scale => _current;
|
||||||
double get factor => _factors[_current]!;
|
}
|
||||||
|
|
||||||
/// get current string (system/small/medium/large)
|
enum TextScalePref {
|
||||||
String get scale => _current;
|
system(1.0),
|
||||||
|
small(0.9),
|
||||||
|
medium(1.1),
|
||||||
|
large(1.4);
|
||||||
|
|
||||||
|
final double factor;
|
||||||
|
|
||||||
|
const TextScalePref(this.factor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import 'package:app/core/app/router.dart';
|
import 'package:app/core/app/router.dart';
|
||||||
import 'package:app/core/app/startup/domain/initialize_app.dart';
|
import 'package:app/core/app/startup/domain/initialize_app.dart';
|
||||||
|
import 'package:app/core/ui/controller/locale_controller.dart';
|
||||||
|
import 'package:app/core/ui/controller/scale_controller.dart';
|
||||||
import 'package:app/core/ui/controller/theme.dart';
|
import 'package:app/core/ui/controller/theme.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fluttery/fluttery.dart';
|
import 'package:fluttery/fluttery.dart';
|
||||||
@@ -25,37 +27,48 @@ Future<void> main() async {
|
|||||||
final themeController = ThemeController();
|
final themeController = ThemeController();
|
||||||
await themeController.init();
|
await themeController.init();
|
||||||
|
|
||||||
|
final scaleController = ScaleController();
|
||||||
|
final localeController = LocaleController();
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
MultiProvider(
|
MultiProvider(
|
||||||
providers: [ChangeNotifierProvider(create: (context) => themeController)],
|
providers: [
|
||||||
child: FinlogApp(
|
ChangeNotifierProvider(create: (context) => themeController),
|
||||||
router: buildAppRouter(startRoute),
|
ChangeNotifierProvider(create: (context) => scaleController),
|
||||||
themeController: themeController,
|
ChangeNotifierProvider(create: (context) => localeController),
|
||||||
),
|
],
|
||||||
|
child: FinlogApp(router: buildAppRouter(startRoute)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FinlogApp extends StatelessWidget {
|
class FinlogApp extends StatelessWidget {
|
||||||
final GoRouter router;
|
final GoRouter router;
|
||||||
final ThemeController themeController;
|
|
||||||
|
|
||||||
const FinlogApp({
|
const FinlogApp({super.key, required this.router});
|
||||||
super.key,
|
|
||||||
required this.router,
|
|
||||||
required this.themeController,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<ThemeController>();
|
||||||
|
final textScale = context.watch<ScaleController>();
|
||||||
|
final localeCtrl = context.watch<LocaleController>();
|
||||||
|
|
||||||
return AnimatedBuilder(
|
return AnimatedBuilder(
|
||||||
animation: themeController,
|
animation: theme,
|
||||||
builder: (context, _) => MaterialApp.router(
|
builder: (context, _) => MaterialApp.router(
|
||||||
title: 'Finlog',
|
title: 'Finlog',
|
||||||
|
locale: localeCtrl.locale,
|
||||||
|
supportedLocales: const [Locale('de'), Locale('en')],
|
||||||
theme: ThemeData.light(),
|
theme: ThemeData.light(),
|
||||||
darkTheme: ThemeData.dark(),
|
darkTheme: ThemeData.dark(),
|
||||||
themeMode: themeController.themeMode,
|
themeMode: theme.themeMode,
|
||||||
routerConfig: router,
|
routerConfig: router,
|
||||||
|
builder: (context, child) => MediaQuery(
|
||||||
|
data: MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).copyWith(textScaler: TextScaler.linear(textScale.factor)),
|
||||||
|
child: child ?? Container(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'package:app/core/ui/controller/locale_controller.dart';
|
||||||
|
import 'package:app/core/ui/controller/scale_controller.dart';
|
||||||
import 'package:app/core/ui/controller/theme.dart';
|
import 'package:app/core/ui/controller/theme.dart';
|
||||||
import 'package:app/modules/settings/modules/app/model/app_settings_view_model.dart';
|
import 'package:app/modules/settings/modules/app/model/app_settings_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -8,9 +10,16 @@ class AppSettingsView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final themeModel = context.watch<ThemeController>();
|
final themeModel = context.read<ThemeController>();
|
||||||
|
final scaleModel = context.read<ScaleController>();
|
||||||
|
final localeModel = context.read<LocaleController>();
|
||||||
|
|
||||||
return ChangeNotifierProvider(
|
return ChangeNotifierProvider(
|
||||||
create: (_) => AppSettingsViewModel(themeModel: themeModel)..load(),
|
create: (_) => AppSettingsViewModel(
|
||||||
|
themeModel: themeModel,
|
||||||
|
scaleModel: scaleModel,
|
||||||
|
localeModel: localeModel,
|
||||||
|
)..load(),
|
||||||
child: const _AppSettingsContent(),
|
child: const _AppSettingsContent(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -36,7 +45,7 @@ class _AppSettingsContent extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
_SystemBackgroundSection(),
|
_SystemBackgroundSection(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_TextSizeSection(),
|
_TextScaleSection(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_LanguageSection(),
|
_LanguageSection(),
|
||||||
],
|
],
|
||||||
@@ -73,13 +82,13 @@ class _SystemBackgroundSection extends StatelessWidget {
|
|||||||
onPressed: (i) {
|
onPressed: (i) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
vm.setBackgroundPref(ThemeMode.system);
|
vm.setThemeMode(ThemeMode.system);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
vm.setBackgroundPref(ThemeMode.dark);
|
vm.setThemeMode(ThemeMode.dark);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
vm.setBackgroundPref(ThemeMode.light);
|
vm.setThemeMode(ThemeMode.light);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -120,36 +129,59 @@ class _SegItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TextSizeSection extends StatelessWidget {
|
class _TextScaleSection extends StatelessWidget {
|
||||||
|
const _TextScaleSection();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final vm = context.watch<AppSettingsViewModel>();
|
final vm = context.watch<AppSettingsViewModel>();
|
||||||
final selected = vm.textSize;
|
final selected = vm.textScale;
|
||||||
|
|
||||||
Widget radio(AppTextSize size, String label, String sub) {
|
|
||||||
return RadioListTile<AppTextSize>(
|
|
||||||
value: size,
|
|
||||||
groupValue: selected,
|
|
||||||
onChanged: (v) => vm.setTextSize(v ?? AppTextSize.normal),
|
|
||||||
title: Text(label),
|
|
||||||
subtitle: Text(sub),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('Textgröße', style: Theme.of(context).textTheme.titleMedium),
|
const Text('Textgröße', style: TextStyle(fontWeight: FontWeight.w600)),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
radio(AppTextSize.small, 'Klein', 'Kompakte Darstellung'),
|
ToggleButtons(
|
||||||
radio(AppTextSize.normal, 'Standard', 'Empfohlene Einstellung'),
|
isSelected: [
|
||||||
radio(AppTextSize.large, 'Groß', 'Größere, besser lesbare Texte'),
|
selected == TextScalePref.system,
|
||||||
|
selected == TextScalePref.small,
|
||||||
|
selected == TextScalePref.medium,
|
||||||
|
selected == TextScalePref.large,
|
||||||
|
],
|
||||||
|
onPressed: (i) {
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
vm.setTextScale(TextScalePref.system);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
vm.setTextScale(TextScalePref.small);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vm.setTextScale(TextScalePref.medium);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
vm.setTextScale(TextScalePref.large);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
constraints: const BoxConstraints(minHeight: 44, minWidth: 120),
|
||||||
|
children: const [
|
||||||
|
_SegItem(icon: Icons.phone_android, label: 'System'),
|
||||||
|
_SegItem(icon: Icons.text_fields, label: 'Klein'),
|
||||||
|
_SegItem(icon: Icons.text_fields, label: 'Mittel'),
|
||||||
|
_SegItem(icon: Icons.text_fields, label: 'Groß'),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LanguageSection extends StatelessWidget {
|
class _LanguageSection extends StatelessWidget {
|
||||||
|
const _LanguageSection();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final vm = context.watch<AppSettingsViewModel>();
|
final vm = context.watch<AppSettingsViewModel>();
|
||||||
@@ -160,18 +192,24 @@ class _LanguageSection extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text('Sprache', style: Theme.of(context).textTheme.titleMedium),
|
Text('Sprache', style: Theme.of(context).textTheme.titleMedium),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
DropdownButtonFormField<AppLanguage>(
|
|
||||||
value: vm.language,
|
DropdownButtonFormField<LanguagePref>(
|
||||||
onChanged: (v) => vm.setLanguage(v ?? AppLanguage.de),
|
initialValue: vm.language,
|
||||||
|
onChanged: (v) => vm.setLanguage(v ?? LanguagePref.en),
|
||||||
items: const [
|
items: const [
|
||||||
DropdownMenuItem(value: AppLanguage.de, child: Text('Deutsch')),
|
DropdownMenuItem(
|
||||||
DropdownMenuItem(value: AppLanguage.en, child: Text('Englisch')),
|
value: LanguagePref.system,
|
||||||
|
child: Text('Systemstandard'),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(value: LanguagePref.de, child: Text('Deutsch')),
|
||||||
|
DropdownMenuItem(value: LanguagePref.en, child: Text('Englisch')),
|
||||||
],
|
],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
isDense: true,
|
isDense: true,
|
||||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
'Änderungen wirken sich nach dem Speichern aus.',
|
'Änderungen wirken sich nach dem Speichern aus.',
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
|
import 'package:app/core/ui/controller/locale_controller.dart';
|
||||||
|
import 'package:app/core/ui/controller/scale_controller.dart';
|
||||||
import 'package:app/core/ui/controller/theme.dart';
|
import 'package:app/core/ui/controller/theme.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
/// Domain-ish enums for clarity and easy (de)serialization.
|
|
||||||
enum AppTextSize { small, normal, large }
|
|
||||||
|
|
||||||
enum AppLanguage { de, en }
|
|
||||||
|
|
||||||
class AppSettingsViewModel extends ChangeNotifier {
|
class AppSettingsViewModel extends ChangeNotifier {
|
||||||
/// Use `null` to represent "system default background".
|
|
||||||
Color? _backgroundColorSystem;
|
|
||||||
AppTextSize _textSize = AppTextSize.normal;
|
|
||||||
AppLanguage _language = AppLanguage.de;
|
|
||||||
|
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
bool _isSaving = false;
|
bool _isSaving = false;
|
||||||
|
|
||||||
final ThemeController _theme;
|
final ThemeController _theme;
|
||||||
|
final ScaleController _scale;
|
||||||
|
final LocaleController _locale;
|
||||||
|
|
||||||
AppSettingsViewModel({required ThemeController themeModel})
|
AppSettingsViewModel({
|
||||||
: _theme = themeModel;
|
required ThemeController themeModel,
|
||||||
|
required ScaleController scaleModel,
|
||||||
|
required LocaleController localeModel,
|
||||||
|
}) : _theme = themeModel,
|
||||||
|
_scale = scaleModel,
|
||||||
|
_locale = localeModel;
|
||||||
|
|
||||||
/// Pretend to load from backend. Plug your repository here later.
|
/// Pretend to load from backend. Plug your repository here later.
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
@@ -28,80 +27,30 @@ class AppSettingsViewModel extends ChangeNotifier {
|
|||||||
// TODO: Replace with real backend call.
|
// TODO: Replace with real backend call.
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 200));
|
await Future<void>.delayed(const Duration(milliseconds: 200));
|
||||||
|
|
||||||
// Example defaults (could come from server response).
|
|
||||||
_backgroundColorSystem = null; // null => Systemstandard
|
|
||||||
_textSize = AppTextSize.normal;
|
|
||||||
_language = AppLanguage.de;
|
|
||||||
|
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBackgroundPref(ThemeMode mode) {
|
void setThemeMode(ThemeMode mode) {
|
||||||
_theme.setTheme(mode);
|
_theme.setTheme(mode);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save to backend (stub).
|
void setTextScale(TextScalePref pref) {
|
||||||
Future<void> save() async {
|
_scale.setScale(pref);
|
||||||
if (_isSaving) return;
|
|
||||||
_isSaving = true;
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
// TODO: Replace with real backend update.
|
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 300));
|
|
||||||
|
|
||||||
_isSaving = false;
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSystemBackgroundColor(Color? colorOrNullForSystem) {
|
void setLanguage(LanguagePref lang) {
|
||||||
_backgroundColorSystem = colorOrNullForSystem;
|
_locale.setLanguage(lang);
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTextSize(AppTextSize size) {
|
|
||||||
_textSize = size;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLanguage(AppLanguage lang) {
|
|
||||||
_language = lang;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'backgroundColorSystem': _backgroundColorSystem?.value,
|
|
||||||
'textSize': _textSize.name,
|
|
||||||
'language': _language.name,
|
|
||||||
};
|
|
||||||
|
|
||||||
void fromJson(Map<String, dynamic> json) {
|
|
||||||
final int? colorValue = json['backgroundColorSystem'] as int?;
|
|
||||||
_backgroundColorSystem = colorValue != null ? Color(colorValue) : null;
|
|
||||||
|
|
||||||
final ts = json['textSize'] as String?;
|
|
||||||
_textSize = AppTextSize.values.firstWhere(
|
|
||||||
(e) => e.name == ts,
|
|
||||||
orElse: () => AppTextSize.normal,
|
|
||||||
);
|
|
||||||
|
|
||||||
final lng = json['language'] as String?;
|
|
||||||
_language = AppLanguage.values.firstWhere(
|
|
||||||
(e) => e.name == lng,
|
|
||||||
orElse: () => AppLanguage.de,
|
|
||||||
);
|
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeMode get themeMode => _theme.themeMode;
|
ThemeMode get themeMode => _theme.themeMode;
|
||||||
|
|
||||||
Color? get backgroundColorSystem => _backgroundColorSystem;
|
LanguagePref? get language => _locale.language;
|
||||||
|
|
||||||
AppTextSize get textSize => _textSize;
|
TextScalePref get textScale => _scale.scale;
|
||||||
|
|
||||||
AppLanguage get language => _language;
|
|
||||||
|
|
||||||
bool get isLoading => _isLoading;
|
bool get isLoading => _isLoading;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user