Skip to content
Snippets Groups Projects
Commit cb7131a6 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '38-add-light-dark-theme-selector' into 'master'

Resolve "Add light/dark theme selector"

Closes #38

See merge request !39
parents b84e5daa 4b1f831d
No related branches found
No related tags found
1 merge request!39Resolve "Add light/dark theme selector"
Pipeline #5629 passed
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=1.2.29
app.versionCode=35
app.versionName=1.2.30
app.versionCode=36
......@@ -6,6 +6,7 @@
"bottom_nav_about": "About",
"settings_title": "Settings",
"settings_label_theme":"Theme mode",
"settings_label_timer_value":"Game turn allowed time",
"about_title": "Informations",
......
......@@ -6,6 +6,7 @@
"bottom_nav_about": "Infos",
"settings_title": "Réglages",
"settings_label_theme":"Thème de couleurs",
"settings_label_timer_value":"Durée du tour de jeu",
"about_title": "Informations",
......
Add light/dark theme setting.
Ajout d'un réglage de thème clair/sombre.
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
part 'theme_state.dart';
class ThemeCubit extends HydratedCubit<ThemeModeState> {
ThemeCubit() : super(const ThemeModeState());
void getTheme(ThemeModeState state) {
emit(state);
}
@override
ThemeModeState? fromJson(Map<String, dynamic> json) {
switch (json['themeMode']) {
case 'ThemeMode.dark':
return const ThemeModeState(themeMode: ThemeMode.dark);
case 'ThemeMode.light':
return const ThemeModeState(themeMode: ThemeMode.light);
case 'ThemeMode.system':
default:
return const ThemeModeState(themeMode: ThemeMode.system);
}
}
@override
Map<String, String>? toJson(ThemeModeState state) {
return <String, String>{'themeMode': state.themeMode.toString()};
}
}
part of 'theme_cubit.dart';
@immutable
class ThemeModeState extends Equatable {
const ThemeModeState({
this.themeMode,
});
final ThemeMode? themeMode;
@override
List<Object?> get props => <Object?>[
themeMode,
];
}
......@@ -6,6 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'package:petitbac/cubit/theme_cubit.dart';
import 'package:provider/provider.dart';
import 'package:petitbac/config/theme.dart';
......@@ -49,14 +50,19 @@ class MyApp extends StatelessWidget {
BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
BlocProvider<GameCubit>(create: (context) => GameCubit()),
BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
BlocProvider<ThemeCubit>(create: (context) => ThemeCubit()),
],
child: ChangeNotifierProvider(
child: BlocBuilder<ThemeCubit, ThemeModeState>(
builder: (BuildContext context, ThemeModeState state) {
return ChangeNotifierProvider(
create: (BuildContext context) => Data(),
child: Consumer<Data>(
builder: (context, data, child) {
return MaterialApp(
title: 'Petit Bac',
theme: appTheme,
theme: lightTheme,
darkTheme: darkTheme,
themeMode: state.themeMode,
home: const SkeletonScreen(),
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
......@@ -65,7 +71,8 @@ class MyApp extends StatelessWidget {
);
},
),
),
);
}),
);
}
}
......@@ -4,6 +4,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:petitbac/config/default_settings.dart';
import 'package:petitbac/cubit/settings_cubit.dart';
import 'package:petitbac/ui/widgets/theme_card.dart';
import 'package:unicons/unicons.dart';
class SettingsForm extends StatefulWidget {
const SettingsForm({super.key});
......@@ -47,6 +49,35 @@ class _SettingsFormState extends State<SettingsForm> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
// Light/dark theme
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Text('settings_label_theme').tr(),
const Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ThemeCard(
mode: ThemeMode.system,
icon: UniconsLine.cog,
),
ThemeCard(
mode: ThemeMode.light,
icon: UniconsLine.sun,
),
ThemeCard(
mode: ThemeMode.dark,
icon: UniconsLine.moon,
)
],
),
],
),
const SizedBox(height: 16),
// Timer value
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
......
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:petitbac/cubit/theme_cubit.dart';
class ThemeCard extends StatelessWidget {
const ThemeCard({
super.key,
required this.mode,
required this.icon,
});
final IconData icon;
final ThemeMode mode;
@override
Widget build(BuildContext context) {
return BlocBuilder<ThemeCubit, ThemeModeState>(
builder: (BuildContext context, ThemeModeState state) {
return Card(
elevation: 2,
shadowColor: Theme.of(context).colorScheme.shadow,
color: state.themeMode == mode
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.surface,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
margin: const EdgeInsets.all(5),
child: InkWell(
onTap: () => BlocProvider.of<ThemeCubit>(context).getTheme(
ThemeModeState(themeMode: mode),
),
borderRadius: const BorderRadius.all(Radius.circular(12)),
child: Icon(
icon,
size: 32,
color:
state.themeMode != mode ? Theme.of(context).colorScheme.primary : Colors.white,
),
),
);
});
}
}
......@@ -2,7 +2,7 @@ name: petitbac
description: A PetitBac game application.
publish_to: 'none'
version: 1.2.29+35
version: 1.2.30+36
environment:
sdk: '^3.0.0'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment