update dark mode handling
This commit is contained in:
+14
-5
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
Reference in New Issue
Block a user