Skip to content

Commit

Permalink
thememode and calendar language
Browse files Browse the repository at this point in the history
  • Loading branch information
mixin27 committed Aug 12, 2024
1 parent 98b7795 commit a3b4304
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 31 deletions.
22 changes: 14 additions & 8 deletions lib/app_start_up.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_mmcalendar/flutter_mmcalendar.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mmcalendar/firebase_options.dart';
import 'package:mmcalendar/src/utils/shared_prefs/preference_manager.dart';
import 'package:mmcalendar/src/widgets/widgets.dart';
// import 'package:mmcalendar/src/utils/onesignal/onesignal.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

Expand All @@ -11,16 +13,12 @@ part 'app_start_up.g.dart';
@Riverpod(keepAlive: true)
FutureOr<void> appStartup(AppStartupRef ref) async {
ref.onDispose(() {
// ensure dependent providers are disposed as well
// ensure we invalidate all the providers we depend on
// ref.invalidate(onboardingRepositoryProvider);
ref.invalidate(sharedPreferencesProvider);
ref.invalidate(calendarLanguageControllerProvider);
});

MmCalendarConfig.initDefault(
const MmCalendarOptions(
language: Language.myanmar,
),
);

// await for all initialization code to be complete before returning
// we can use `Future.wait` for independent long run tasks.
await Future.wait([
Expand All @@ -32,8 +30,14 @@ FutureOr<void> appStartup(AppStartupRef ref) async {

// list of providers to be warmed up
// ref.watch(onboardingRepositoryProvider.future),
// Future.delayed(const Duration(seconds: 5)),
ref.watch(sharedPreferencesProvider.future),
]);

MmCalendarConfig.initDefault(
MmCalendarOptions(
language: ref.watch(calendarLanguageControllerProvider),
),
);
}

/// Widget class to manage asynchronous app initialization
Expand Down Expand Up @@ -66,6 +70,7 @@ class AppStartupLoadingWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Column(
Expand Down Expand Up @@ -99,6 +104,7 @@ class AppStartupErrorWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Column(
Expand Down
20 changes: 4 additions & 16 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mmcalendar/flutter_mmcalendar.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mmcalendar/firebase_options.dart';
import 'package:mmcalendar/app_start_up.dart';
import 'package:mmcalendar/src/features/app/app.dart';
import 'package:mmcalendar/src/shared/errors/async_error_logger.dart';
import 'package:mmcalendar/src/shared/errors/error_logger.dart';
Expand All @@ -15,18 +13,6 @@ Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();

MmCalendarConfig.initDefault(
const MmCalendarOptions(
language: Language.myanmar,
),
);

await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

// await initOnesignal();

final container = ProviderContainer(
observers: [AsyncErrorLogger()],
);
Expand All @@ -47,7 +33,9 @@ Future<void> main() async {
],
path: 'assets/translations',
fallbackLocale: const Locale('en', 'US'),
child: AppWidget(),
child: AppStartUpWidget(
onLoaded: (context) => AppWidget(),
),
),
),
);
Expand Down
16 changes: 14 additions & 2 deletions lib/src/features/app/presentation/app.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mmcalendar/src/routes/routes.dart';
import 'package:mmcalendar/src/widgets/settings/theme_mode_switch_tile.dart';

class AppWidget extends StatelessWidget {
class AppWidget extends HookConsumerWidget {
AppWidget({super.key});

final _appRouter = AppRouter();

@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
final themeMode = ref.watch(themeModeControllerProvider);

return MaterialApp.router(
debugShowCheckedModeBanner: false,
title: 'Myanmar Calendar',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF18363E)),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF18363E),
brightness: Brightness.dark,
),
useMaterial3: true,
),
themeMode: themeMode,
routerConfig: _appRouter.config(
navigatorObservers: () => [
AppRouteObserver(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class AppSettingsPage extends StatelessWidget {
body: ListView(
children: [
// const NotificationSwitchListTile(),
const CalendarLanguageListTile(),
const ThemeModeSwitchTile(),
// const CalendarLanguageListTile(),
const AppLanguageListTile(),
const RateMeListTile(),
const PrivacyPolicyListTile(),
Expand Down
64 changes: 64 additions & 0 deletions lib/src/utils/shared_prefs/preference_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'dart:developer';

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shared_preferences/shared_preferences.dart';

part 'preference_manager.g.dart';

typedef PreferenceKey = String;

class PreferenceManager {
final SharedPreferences _prefs;

PreferenceManager(this._prefs);

Future<bool> setData<T>(T data, PreferenceKey key) async {
const invalidTypeError = 'Invalid Type';
assert(
T == String || T == bool || T == int || T == double || T == List<String>,
invalidTypeError,
);
log('data: $data');

final setFuncs = <Type, Future<bool> Function()>{
String: () => _prefs.setString(key, data as String),
bool: () => _prefs.setBool(key, data as bool),
int: () => _prefs.setInt(key, data as int),
double: () => _prefs.setDouble(key, data as double),
List<String>: () => _prefs.setStringList(key, data as List<String>),
};

final result = await (setFuncs[T] ?? () async => false)();
return result;
}

T? getData<T>(PreferenceKey key) {
const invalidTypeError = 'Invalid Type';
assert(
T == String || T == bool || T == int || T == double || T == List<String>,
invalidTypeError,
);

final getFuncs = <Type, T? Function()>{
String: () => _prefs.getString(key) as T?,
bool: () => _prefs.getBool(key) as T?,
int: () => _prefs.getInt(key) as T?,
double: () => _prefs.getDouble(key) as T?,
List<String>: () => _prefs.getStringList(key) as T?,
};

final data = getFuncs[T]?.call();
return data;
}
}

@riverpod
PreferenceManager preferenceManager(PreferenceManagerRef ref) {
final prefs = ref.read(sharedPreferencesProvider).requireValue;
return PreferenceManager(prefs);
}

@Riverpod(keepAlive: true)
Future<SharedPreferences> sharedPreferences(SharedPreferencesRef ref) {
return SharedPreferences.getInstance();
}
112 changes: 109 additions & 3 deletions lib/src/widgets/settings/calendar_language_list_tile.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,124 @@
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_mmcalendar/flutter_mmcalendar.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:iconly/iconly.dart';
import 'package:mmcalendar/src/utils/shared_prefs/preference_manager.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'calendar_language_list_tile.g.dart';

const PreferenceKey keyCalendarLang = 'key_cal_lang';

class CalendarLanguageListTile extends StatelessWidget {
class CalendarLanguageListTile extends HookConsumerWidget {
const CalendarLanguageListTile({
super.key,
});

@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
final language = ref.watch(calendarLanguageControllerProvider);

void changeCalendarLanguage(Language lang) {
ref
.read(calendarLanguageControllerProvider.notifier)
.setCalendarLanguage(lang);
Navigator.of(context).pop();
}

void handleTap() {
showAdaptiveDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Theme'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
onTap: () => changeCalendarLanguage(Language.myanmar),
title: const Text('Myanmar (Unicode)'),
trailing: language == Language.myanmar
? const Icon(Icons.check_outlined, color: Colors.green)
: null,
),
ListTile(
onTap: () => changeCalendarLanguage(Language.zawgyi),
title: const Text('Myanmar (Zawgyi)'),
trailing: language == Language.zawgyi
? const Icon(Icons.check_outlined, color: Colors.green)
: null,
),
ListTile(
onTap: () => changeCalendarLanguage(Language.english),
title: const Text('English'),
trailing: language == Language.english
? const Icon(Icons.check_outlined, color: Colors.green)
: null,
),
ListTile(
onTap: () => changeCalendarLanguage(Language.karen),
title: const Text('Karen'),
trailing: language == Language.karen
? const Icon(Icons.check_outlined, color: Colors.green)
: null,
),
ListTile(
onTap: () => changeCalendarLanguage(Language.mon),
title: const Text('Mon'),
trailing: language == Language.mon
? const Icon(Icons.check_outlined, color: Colors.green)
: null,
),
ListTile(
onTap: () => changeCalendarLanguage(Language.tai),
title: const Text('Tai'),
trailing: language == Language.tai
? const Icon(Icons.check_outlined, color: Colors.green)
: null,
),
],
),
),
);
}

return ListTile(
onTap: () {},
onTap: handleTap,
leading: const Icon(IconlyLight.calendar),
title: const Text('Calendar Language'),
subtitle: const Text('English, myanmar, karen ...'),
);
}
}

@Riverpod(keepAlive: true)
class CalendarLanguageController extends _$CalendarLanguageController {
Language _getLanguageFromCached() {
final prefs = ref.read(preferenceManagerProvider);

final language = prefs.getData<String>(keyCalendarLang);
log('lang: $language');

return switch (language) {
'Language.english' => Language.english,
'Language.karen' => Language.karen,
'Language.mon' => Language.mon,
'Language.tai' => Language.tai,
'Language.zawgyi' => Language.zawgyi,
_ => Language.myanmar,
};
}

@override
Language build() {
return _getLanguageFromCached();
}

void setCalendarLanguage(Language language) {
final prefs = ref.read(preferenceManagerProvider);
prefs.setData<String>(language.toString(), keyCalendarLang);

state = _getLanguageFromCached();
}
}
Loading

0 comments on commit a3b4304

Please sign in to comment.