Add offline-first mode support to settings
- Add AppMode enum (local, online) - Extend settings datasource with mode, setup, and onboarding flags - Update settings viewmodel with mode helpers and persistence
This commit is contained in:
parent
3c3da50a54
commit
ceef4f4c72
@ -1,11 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import '../domain/enums/app_mode.dart';
|
||||||
|
|
||||||
abstract class SettingsLocalDataSource {
|
abstract class SettingsLocalDataSource {
|
||||||
Locale? getLocale();
|
Locale? getLocale();
|
||||||
Future<void> setLocale(Locale locale);
|
Future<void> setLocale(Locale locale);
|
||||||
ThemeMode getThemeMode();
|
ThemeMode getThemeMode();
|
||||||
Future<void> setThemeMode(ThemeMode mode);
|
Future<void> setThemeMode(ThemeMode mode);
|
||||||
|
AppMode? getAppMode();
|
||||||
|
Future<void> setAppMode(AppMode mode);
|
||||||
|
bool isSetupCompleted();
|
||||||
|
Future<void> setSetupCompleted(bool completed);
|
||||||
|
bool isOnboardingShown();
|
||||||
|
Future<void> setOnboardingShown(bool shown);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SettingsLocalDataSourceImpl implements SettingsLocalDataSource {
|
class SettingsLocalDataSourceImpl implements SettingsLocalDataSource {
|
||||||
@ -13,6 +21,9 @@ class SettingsLocalDataSourceImpl implements SettingsLocalDataSource {
|
|||||||
|
|
||||||
static const String _localeKey = 'locale';
|
static const String _localeKey = 'locale';
|
||||||
static const String _themeModeKey = 'theme_mode';
|
static const String _themeModeKey = 'theme_mode';
|
||||||
|
static const String _appModeKey = 'app_mode';
|
||||||
|
static const String _setupCompletedKey = 'setup_completed';
|
||||||
|
static const String _onboardingShownKey = 'onboarding_shown';
|
||||||
|
|
||||||
SettingsLocalDataSourceImpl({required this.sharedPreferences});
|
SettingsLocalDataSourceImpl({required this.sharedPreferences});
|
||||||
|
|
||||||
@ -39,4 +50,36 @@ class SettingsLocalDataSourceImpl implements SettingsLocalDataSource {
|
|||||||
Future<void> setThemeMode(ThemeMode mode) async {
|
Future<void> setThemeMode(ThemeMode mode) async {
|
||||||
await sharedPreferences.setInt(_themeModeKey, mode.index);
|
await sharedPreferences.setInt(_themeModeKey, mode.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AppMode? getAppMode() {
|
||||||
|
final index = sharedPreferences.getInt(_appModeKey);
|
||||||
|
if (index == null) return null;
|
||||||
|
return AppMode.values[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setAppMode(AppMode mode) async {
|
||||||
|
await sharedPreferences.setInt(_appModeKey, mode.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isSetupCompleted() {
|
||||||
|
return sharedPreferences.getBool(_setupCompletedKey) ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setSetupCompleted(bool completed) async {
|
||||||
|
await sharedPreferences.setBool(_setupCompletedKey, completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isOnboardingShown() {
|
||||||
|
return sharedPreferences.getBool(_onboardingShownKey) ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setOnboardingShown(bool shown) async {
|
||||||
|
await sharedPreferences.setBool(_onboardingShownKey, shown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
lib/features/settings/domain/enums/app_mode.dart
Normal file
4
lib/features/settings/domain/enums/app_mode.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
enum AppMode {
|
||||||
|
local,
|
||||||
|
online,
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import '../../../../core/logging/app_logger.dart';
|
import '../../../../core/logging/app_logger.dart';
|
||||||
import '../../data/settings_local_datasource.dart';
|
import '../../data/settings_local_datasource.dart';
|
||||||
|
import '../../domain/enums/app_mode.dart';
|
||||||
|
|
||||||
class SettingsViewModel extends ChangeNotifier {
|
class SettingsViewModel extends ChangeNotifier {
|
||||||
final SettingsLocalDataSource dataSource;
|
final SettingsLocalDataSource dataSource;
|
||||||
@ -16,9 +17,17 @@ class SettingsViewModel extends ChangeNotifier {
|
|||||||
|
|
||||||
Locale? _locale;
|
Locale? _locale;
|
||||||
ThemeMode _themeMode = ThemeMode.system;
|
ThemeMode _themeMode = ThemeMode.system;
|
||||||
|
AppMode? _appMode;
|
||||||
|
bool _setupCompleted = false;
|
||||||
|
bool _onboardingShown = false;
|
||||||
|
|
||||||
Locale? get locale => _locale;
|
Locale? get locale => _locale;
|
||||||
ThemeMode get themeMode => _themeMode;
|
ThemeMode get themeMode => _themeMode;
|
||||||
|
AppMode? get appMode => _appMode;
|
||||||
|
bool get setupCompleted => _setupCompleted;
|
||||||
|
bool get onboardingShown => _onboardingShown;
|
||||||
|
bool get isLocalMode => _appMode == AppMode.local;
|
||||||
|
bool get isOnlineMode => _appMode == AppMode.online;
|
||||||
|
|
||||||
static const supportedLocales = [
|
static const supportedLocales = [
|
||||||
Locale('en'),
|
Locale('en'),
|
||||||
@ -28,7 +37,10 @@ class SettingsViewModel extends ChangeNotifier {
|
|||||||
void _loadSettings() {
|
void _loadSettings() {
|
||||||
_locale = dataSource.getLocale() ?? const Locale('en');
|
_locale = dataSource.getLocale() ?? const Locale('en');
|
||||||
_themeMode = dataSource.getThemeMode();
|
_themeMode = dataSource.getThemeMode();
|
||||||
logger.info('Settings loaded: locale=$_locale, themeMode=$_themeMode');
|
_appMode = dataSource.getAppMode();
|
||||||
|
_setupCompleted = dataSource.isSetupCompleted();
|
||||||
|
_onboardingShown = dataSource.isOnboardingShown();
|
||||||
|
logger.info('Settings loaded: locale=$_locale, themeMode=$_themeMode, appMode=$_appMode, setupCompleted=$_setupCompleted, onboardingShown=$_onboardingShown');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setLocale(Locale locale) async {
|
Future<void> setLocale(Locale locale) async {
|
||||||
@ -45,6 +57,27 @@ class SettingsViewModel extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> setAppMode(AppMode mode) async {
|
||||||
|
_appMode = mode;
|
||||||
|
await dataSource.setAppMode(mode);
|
||||||
|
logger.info('App mode changed to: $mode');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setSetupCompleted(bool completed) async {
|
||||||
|
_setupCompleted = completed;
|
||||||
|
await dataSource.setSetupCompleted(completed);
|
||||||
|
logger.info('Setup completed: $completed');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setOnboardingShown(bool shown) async {
|
||||||
|
_onboardingShown = shown;
|
||||||
|
await dataSource.setOnboardingShown(shown);
|
||||||
|
logger.info('Onboarding shown: $shown');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
String getLanguageName(Locale locale) {
|
String getLanguageName(Locale locale) {
|
||||||
switch (locale.languageCode) {
|
switch (locale.languageCode) {
|
||||||
case 'en':
|
case 'en':
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user