update dark mode handling

This commit is contained in:
odweta
2026-04-03 14:26:57 +02:00
parent 1f8526a7dd
commit 1ec4a65032
7 changed files with 136 additions and 11 deletions
+14 -5
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:frontend/provider/theme_provider.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
@@ -17,10 +18,17 @@ import 'pages/leaderboard.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => QuoteProvider(),
child: HlaskovnikFrontendApp(),
),
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => QuoteProvider()
),
ChangeNotifierProvider(
create: (_) => ThemeProvider()
)
],
child: HlaskovnikFrontendApp()
)
);
}
@@ -46,6 +54,7 @@ class HlaskovnikFrontendApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeProvider = context.watch<ThemeProvider>();
return MaterialApp.router(
title: Strings.appName,
theme: ThemeData(
@@ -62,7 +71,7 @@ class HlaskovnikFrontendApp extends StatelessWidget {
),
useMaterial3: true,
),
themeMode: ThemeMode.system,
themeMode: themeProvider.isDark ? ThemeMode.dark : ThemeMode.system,
routerConfig: _router,
);
}
+27 -6
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:frontend/provider/quote_provider.dart';
import 'package:frontend/model/quote.dart';
import 'package:frontend/provider/theme_provider.dart';
import 'package:frontend/values/strings.dart';
import 'package:provider/provider.dart';
@@ -13,15 +14,16 @@ class ListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final provider = context.watch<QuoteProvider>();
final themeProvider = context.watch<ThemeProvider>();
return RefreshIndicator(
onRefresh: () async {
await provider.readQuotes();
},
child: _bodyBuilder(context, provider),
child: _bodyBuilder(context, provider, themeProvider),
);
}
Widget _bodyBuilder(BuildContext context, QuoteProvider provider) {
Widget _bodyBuilder(BuildContext context, QuoteProvider provider, ThemeProvider themeProvider) {
if (provider.loading) {
return Center(child: CircularProgressIndicator());
}
@@ -51,7 +53,7 @@ class ListPage extends StatelessWidget {
),
),
),
filterBar(context, provider),
filterBar(context, provider, themeProvider),
Expanded(
child: ListView.builder(
padding: EdgeInsets.all(Constants.edgeInset),
@@ -220,7 +222,7 @@ class ListPage extends StatelessWidget {
);
}
Widget filterBar(BuildContext context, QuoteProvider provider) {
Widget filterBar(BuildContext context, QuoteProvider provider, ThemeProvider themeProvider) {
return Padding(
padding: const EdgeInsets.all(Constants.edgeInset),
child: Row(
@@ -246,7 +248,7 @@ class ListPage extends StatelessWidget {
IconButton(
icon: Icon(Icons.more_horiz),
onPressed: () {
_showOptionsBottomSheet(context, provider);
_showOptionsBottomSheet(context, provider, themeProvider);
},
),
],
@@ -254,7 +256,7 @@ class ListPage extends StatelessWidget {
);
}
void _showOptionsBottomSheet(BuildContext context, QuoteProvider provider) {
void _showOptionsBottomSheet(BuildContext context, QuoteProvider provider, ThemeProvider themeProvider) {
showModalBottomSheet(
context: context,
builder: (context) {
@@ -284,6 +286,25 @@ class ListPage extends StatelessWidget {
);
}
),
ListTile(
title: Text(Strings.userPrefersDarkMode),
onTap: () { themeProvider.setDarkMode(!themeProvider.isDark); },
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(right: Constants.edgeInset),
child: Switch(
onChanged: (value) {
themeProvider.setDarkMode(value);
},
value: themeProvider.isDark
),
),
Icon(Icons.dark_mode),
],
),
),
],
),
);
+34
View File
@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<void> saveDarkMode(bool isDark) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('darkMode', isDark);
}
Future<bool> loadDarkMode() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getBool('darkMode') ?? false; // default light
}
class ThemeProvider extends ChangeNotifier {
bool _isDark = false;
bool get isDark => _isDark;
ThemeProvider() {
_load(); // load saved value on startup
}
void _load() async {
_isDark = await loadDarkMode();
notifyListeners();
}
void setDarkMode(bool value) async {
_isDark = value;
notifyListeners();
await saveDarkMode(value);
}
}
+2
View File
@@ -30,4 +30,6 @@ class Strings {
static const String filterBy = "Filtrovat podle";
static const String exportSelectedQuotes = "Exportovat vybrané hlášky";
static const String byAttribute = "podle příznaku";
static const String userPrefersDarkMode = "Preferuji tmavý režim";
}