diff --git a/lib/app.dart b/lib/app.dart index badf211..b9316a4 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:kmobile/features/auth/controllers/theme_mode_cubit.dart'; +import 'package:kmobile/features/auth/controllers/theme_mode_state.dart'; import 'package:kmobile/security/secure_storage.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import './l10n/app_localizations.dart'; @@ -78,9 +80,37 @@ class _KMobileState extends State { providers: [ BlocProvider(create: (_) => getIt()), BlocProvider(create: (_) => ThemeCubit()), + BlocProvider(create: (_) => ThemeModeCubit()), ], - child: BlocBuilder( - builder: (context, themeState) { + // child: BlocBuilder( + // builder: (context, themeState) { + // return MaterialApp( + // debugShowCheckedModeBanner: false, + // locale: _locale ?? const Locale('en'), + // supportedLocales: const [ + // Locale('en'), + // Locale('hi'), + // ], + // localizationsDelegates: const [ + // AppLocalizations.delegate, + // GlobalMaterialLocalizations.delegate, + // GlobalWidgetsLocalizations.delegate, + // GlobalCupertinoLocalizations.delegate, + // ], + // title: 'kMobile', + // theme: themeState.getThemeData(), + // //darkTheme: themeState.getThemeData(), + // themeMode: ThemeMode.light, + // onGenerateRoute: AppRoutes.generateRoute, + // initialRoute: AppRoutes.splash, + // home: showSplash ? const SplashScreen() : const AuthGate(), + // ); + // }, + // ), + child: BlocBuilder( + builder: (context, themeState) { + return BlocBuilder( + builder: (context, modeState) { return MaterialApp( debugShowCheckedModeBanner: false, locale: _locale ?? const Locale('en'), @@ -96,14 +126,16 @@ class _KMobileState extends State { ], title: 'kMobile', theme: themeState.getThemeData(), - //darkTheme: themeState.getThemeData(), - themeMode: ThemeMode.light, + darkTheme: themeState.getThemeData(), // reuse same color in dark + themeMode: context.watch().state.mode, // <<-- coming from ThemeModeCubit onGenerateRoute: AppRoutes.generateRoute, initialRoute: AppRoutes.splash, home: showSplash ? const SplashScreen() : const AuthGate(), ); }, - ), + ); + }, + ), ); } } @@ -336,7 +368,7 @@ class _NavigationScaffoldState extends State { currentIndex: _selectedIndex, type: BottomNavigationBarType.fixed, backgroundColor: Theme.of(context) - .scaffoldBackgroundColor, // Light blue background + .scaffoldBackgroundColor, selectedItemColor: Theme.of(context).primaryColor, unselectedItemColor: Colors.black54, onTap: (index) { diff --git a/lib/di/injection.dart b/lib/di/injection.dart index 84810f0..4b04807 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -8,6 +8,7 @@ import 'package:kmobile/api/services/payment_service.dart'; import 'package:kmobile/api/services/user_service.dart'; import 'package:kmobile/data/repositories/transaction_repository.dart'; import 'package:kmobile/features/auth/controllers/theme_cubit.dart'; +import 'package:kmobile/features/auth/controllers/theme_mode_cubit.dart'; import '../api/services/auth_service.dart'; import '../api/interceptors/auth_interceptor.dart'; import '../data/repositories/auth_repository.dart'; @@ -20,6 +21,7 @@ Future setupDependencies() async { //getIt.registerLazySingleton(() => ThemeController()); //getIt.registerLazySingleton(() => ThemeModeController()); getIt.registerSingleton(ThemeCubit()); + getIt.registerSingleton(ThemeModeCubit()); // Register Dio client getIt.registerSingleton(_createDioClient()); diff --git a/lib/features/auth/controllers/theme_mode_cubit.dart b/lib/features/auth/controllers/theme_mode_cubit.dart new file mode 100644 index 0000000..97ce4ba --- /dev/null +++ b/lib/features/auth/controllers/theme_mode_cubit.dart @@ -0,0 +1,24 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'theme_mode_state.dart'; + + +class ThemeModeCubit extends Cubit { + ThemeModeCubit() : super(const ThemeModeState(mode: ThemeMode.system)) { + loadThemeMode(); + } + + Future loadThemeMode() async { + final prefs = await SharedPreferences.getInstance(); + final modeIndex = prefs.getInt('theme_mode') ?? 2; // default system + final mode = ThemeMode.values[modeIndex]; + emit(ThemeModeState(mode: mode)); + } + + Future changeThemeMode(ThemeMode mode) async { + final prefs = await SharedPreferences.getInstance(); + await prefs.setInt('theme_mode', mode.index); + emit(ThemeModeState(mode: mode)); + } +} \ No newline at end of file diff --git a/lib/features/auth/controllers/theme_mode_state.dart b/lib/features/auth/controllers/theme_mode_state.dart new file mode 100644 index 0000000..cad006a --- /dev/null +++ b/lib/features/auth/controllers/theme_mode_state.dart @@ -0,0 +1,11 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; + +class ThemeModeState extends Equatable { + final ThemeMode mode; + + const ThemeModeState({required this.mode}); + + @override + List get props => [mode]; +} \ No newline at end of file diff --git a/lib/features/profile/preferences/preference_screen.dart b/lib/features/profile/preferences/preference_screen.dart index 28b93fb..65a0c8e 100644 --- a/lib/features/profile/preferences/preference_screen.dart +++ b/lib/features/profile/preferences/preference_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:kmobile/features/profile/preferences/theme_mode_dialog.dart'; import 'language_dialog.dart'; import 'color_theme_dialog.dart'; import '../../../l10n/app_localizations.dart'; @@ -29,7 +30,7 @@ class PreferenceScreen extends StatelessWidget { showDialog( context: context, builder: (_) => - const LanguageDialog(), // your custom language dialog + const LanguageDialog(), ); }, ), @@ -37,12 +38,9 @@ class PreferenceScreen extends StatelessWidget { ListTile( leading: const Icon(Icons.brightness_6), title: Text(AppLocalizations.of(context).themeMode), - //trailing: Switch( - // value: state.isDarkMode, - // onChanged: (val) { - // context.read().toggleDarkMode(val); - // }, - //), + onTap: () { + showThemeModeDialog(context); + }, ), //Color_Theme_Selection ListTile( @@ -53,7 +51,8 @@ class PreferenceScreen extends StatelessWidget { context: context, builder: (_) => const ColorThemeDialog(), ); - }), + } + ), ], ); }, diff --git a/lib/features/profile/preferences/theme_mode_dialog.dart b/lib/features/profile/preferences/theme_mode_dialog.dart new file mode 100644 index 0000000..f03c29b --- /dev/null +++ b/lib/features/profile/preferences/theme_mode_dialog.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:kmobile/features/auth/controllers/theme_mode_cubit.dart'; + +Future showThemeModeDialog(BuildContext context) async { + final cubit = context.read(); + final currentMode = context.read().state.mode; + + await showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text("Select Theme Mode"), + content: Column( + mainAxisSize: MainAxisSize.min, + children: ThemeMode.values.map((mode) { + return RadioListTile( + title: Text(mode.toString().split('.').last.toUpperCase()), + value: mode, + groupValue: currentMode, + onChanged: (value) { + if (value != null) { + cubit.changeThemeMode(value); + Navigator.pop(context); + } + }, + ); + }).toList(), + ), + ); + }, + ); +} \ No newline at end of file