mirror of
https://github.com/we-promise/sure.git
synced 2026-04-18 19:44:09 +00:00
Mobile: Add theme selection (light/dark/system) to settings (#1213)
* Feature: Add Theme selection in Settings page * Fix: Theme provider exception handling. * feat(mobile): Show theme selection option in settings screen. * BuildID version 9 --------- Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import 'providers/auth_provider.dart';
|
||||
import 'providers/accounts_provider.dart';
|
||||
import 'providers/transactions_provider.dart';
|
||||
import 'providers/chat_provider.dart';
|
||||
import 'providers/theme_provider.dart';
|
||||
import 'screens/backend_config_screen.dart';
|
||||
import 'screens/login_screen.dart';
|
||||
import 'screens/main_navigation_screen.dart';
|
||||
@@ -35,6 +36,7 @@ class SureApp extends StatelessWidget {
|
||||
ChangeNotifierProvider(create: (_) => ConnectivityService()),
|
||||
ChangeNotifierProvider(create: (_) => AuthProvider()),
|
||||
ChangeNotifierProvider(create: (_) => ChatProvider()),
|
||||
ChangeNotifierProvider(create: (_) => ThemeProvider()),
|
||||
ChangeNotifierProxyProvider<ConnectivityService, AccountsProvider>(
|
||||
create: (_) => AccountsProvider(),
|
||||
update: (_, connectivityService, accountsProvider) {
|
||||
@@ -62,7 +64,8 @@ class SureApp extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
child: Consumer<ThemeProvider>(
|
||||
builder: (context, themeProvider, _) => MaterialApp(
|
||||
title: 'Sure Finances',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
@@ -139,14 +142,14 @@ class SureApp extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
themeMode: ThemeMode.system,
|
||||
themeMode: themeProvider.themeMode,
|
||||
routes: {
|
||||
'/config': (context) => const BackendConfigScreen(),
|
||||
'/login': (context) => const LoginScreen(),
|
||||
'/home': (context) => const MainNavigationScreen(),
|
||||
},
|
||||
home: const AppWrapper(),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
50
mobile/lib/providers/theme_provider.dart
Normal file
50
mobile/lib/providers/theme_provider.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/preferences_service.dart';
|
||||
|
||||
class ThemeProvider extends ChangeNotifier {
|
||||
ThemeMode _themeMode = ThemeMode.system;
|
||||
|
||||
ThemeMode get themeMode => _themeMode;
|
||||
|
||||
ThemeProvider() {
|
||||
_loadThemeMode();
|
||||
}
|
||||
|
||||
Future<void> _loadThemeMode() async {
|
||||
try {
|
||||
final mode = await PreferencesService.instance.getThemeMode();
|
||||
_themeMode = _fromString(mode);
|
||||
} catch (_) {
|
||||
_themeMode = ThemeMode.system;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> setThemeMode(ThemeMode mode) async {
|
||||
_themeMode = mode;
|
||||
notifyListeners();
|
||||
await PreferencesService.instance.setThemeMode(_toString(mode));
|
||||
}
|
||||
|
||||
static ThemeMode _fromString(String mode) {
|
||||
switch (mode) {
|
||||
case 'light':
|
||||
return ThemeMode.light;
|
||||
case 'dark':
|
||||
return ThemeMode.dark;
|
||||
default:
|
||||
return ThemeMode.system;
|
||||
}
|
||||
}
|
||||
|
||||
static String _toString(ThemeMode mode) {
|
||||
switch (mode) {
|
||||
case ThemeMode.light:
|
||||
return 'light';
|
||||
case ThemeMode.dark:
|
||||
return 'dark';
|
||||
case ThemeMode.system:
|
||||
return 'system';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
import '../providers/theme_provider.dart';
|
||||
import '../services/offline_storage_service.dart';
|
||||
import '../services/log_service.dart';
|
||||
import '../services/preferences_service.dart';
|
||||
@@ -399,6 +400,37 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
},
|
||||
),
|
||||
|
||||
Consumer<ThemeProvider>(
|
||||
builder: (context, themeProvider, _) {
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.brightness_6_outlined),
|
||||
title: const Text('Theme'),
|
||||
trailing: SegmentedButton<ThemeMode>(
|
||||
segments: const [
|
||||
ButtonSegment(
|
||||
value: ThemeMode.light,
|
||||
icon: Icon(Icons.light_mode, size: 18),
|
||||
tooltip: 'Light',
|
||||
),
|
||||
ButtonSegment(
|
||||
value: ThemeMode.system,
|
||||
icon: Icon(Icons.brightness_auto, size: 18),
|
||||
tooltip: 'System',
|
||||
),
|
||||
ButtonSegment(
|
||||
value: ThemeMode.dark,
|
||||
icon: Icon(Icons.dark_mode, size: 18),
|
||||
tooltip: 'Dark',
|
||||
),
|
||||
],
|
||||
selected: {themeProvider.themeMode},
|
||||
onSelectionChanged: (modes) => themeProvider.setThemeMode(modes.first),
|
||||
showSelectedIcon: false,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
// Data Management Section
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class PreferencesService {
|
||||
static const _groupByTypeKey = 'dashboard_group_by_type';
|
||||
static const _themeModeKey = 'theme_mode';
|
||||
|
||||
static PreferencesService? _instance;
|
||||
SharedPreferences? _prefs;
|
||||
@@ -27,4 +28,15 @@ class PreferencesService {
|
||||
final prefs = await _preferences;
|
||||
await prefs.setBool(_groupByTypeKey, value);
|
||||
}
|
||||
|
||||
/// Returns 'light', 'dark', or 'system' (default).
|
||||
Future<String> getThemeMode() async {
|
||||
final prefs = await _preferences;
|
||||
return prefs.getString(_themeModeKey) ?? 'system';
|
||||
}
|
||||
|
||||
Future<void> setThemeMode(String mode) async {
|
||||
final prefs = await _preferences;
|
||||
await prefs.setString(_themeModeKey, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: sure_mobile
|
||||
description: A mobile app for Sure personal finance management
|
||||
publish_to: 'none'
|
||||
version: 0.6.9+1
|
||||
version: 0.6.9+9
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.0 <4.0.0'
|
||||
|
||||
Reference in New Issue
Block a user