Skip to content

Commit

Permalink
refactor: apply singleton pattern for SharedPreferences
Browse files Browse the repository at this point in the history
  • Loading branch information
phoenixit99 committed Dec 27, 2024
1 parent 5493ee8 commit 691681e
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 335 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 1.9.0+10

- Migrate to `Fluent UI` Framework/DesignSystem
- feat: add some changes on theme configurations for using fluent_ui package [#45](https://github.com/pactus-project/pactus-gui/pull/45)

# 1.8.0+9

- Implement or replace the Easy Localization package for efficient localization management
Expand Down
20 changes: 10 additions & 10 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gui/src/core/constants/configurations.dart';
import 'package:gui/src/core/di/service_locator.dart';
import 'package:gui/src/core/router/app_router.dart';
import 'package:gui/src/core/utils/gen/localization/codegen_loader.g.dart';
import 'package:gui/src/features/main/theme/bloc/theme_bloc.dart';
Expand All @@ -12,26 +13,25 @@ import 'src/features/main/language/presentation/bloc/language_bloc.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();

final sharedPreferencesService = await SharedPreferencesService.initialize();
await setupSharedPreferences();

runApp(
MultiBlocProvider(
providers: [
BlocProvider<LanguageBloc>(
create: (_) => LanguageBloc(sharedPreferencesService),
create: (_) => LanguageBloc(locator<SharedPreferencesService>()),
),
BlocProvider<ThemeBloc>(
create: (_) => ThemeBloc(sharedPreferencesService),
create: (_) => ThemeBloc(locator<SharedPreferencesService>()),
),
],
child: const MyApp(),
child: PactusGuiApp(),
),
);
}

class MyApp extends StatelessWidget {
const MyApp({super.key});
class PactusGuiApp extends StatelessWidget {
const PactusGuiApp({super.key});

@override
Widget build(BuildContext context) {
Expand All @@ -51,10 +51,10 @@ class MyApp extends StatelessWidget {
}
return BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, themeState) {
return MaterialApp.router(
return FluentApp.router(
debugShowCheckedModeBanner: false,
routerConfig: routerConfig,
title: 'Flutter Demo',
title: 'Pactus Gui App',
theme: themeState.themeData,
localizationsDelegates: context.localizationDelegates,
supportedLocales: AppConfigs.supportedLocales,
Expand Down
12 changes: 12 additions & 0 deletions lib/src/core/di/service_locator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../services/shared_preferences_service.dart';

final locator = GetIt.instance;

Future<void> setupSharedPreferences() async {
final preferences = await SharedPreferences.getInstance();
locator.registerSingleton<SharedPreferencesService>(
SharedPreferencesService(preferences),
);
}
15 changes: 3 additions & 12 deletions lib/src/core/services/shared_preferences_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,10 @@ class SharedPreferencesService {
SharedPreferencesService(this._preferences);
final SharedPreferences _preferences;

static Future<SharedPreferencesService> initialize() async {
final preferences = await SharedPreferences.getInstance();
return SharedPreferencesService(preferences);
}

Future<String> getSelectedTheme() async {
final prefs = await SharedPreferences.getInstance();
final savedTheme = prefs.getString(AppConstants.themePrefsKey);
final savedTheme = _preferences.getString(AppConstants.themePrefsKey);

if (savedTheme == null) {
// Return system theme if no preference is saved
final brightness =
WidgetsBinding.instance.platformDispatcher.platformBrightness;

Expand All @@ -31,12 +24,10 @@ class SharedPreferencesService {
}

Future<void> saveSelectedTheme(String themeCode) async {
final prefs = await SharedPreferences.getInstance();
if (themeCode.isEmpty) {
// Remove saved preference to follow system theme
await prefs.remove(AppConstants.themePrefsKey);
await _preferences.remove(AppConstants.themePrefsKey);
} else {
await prefs.setString(AppConstants.themePrefsKey, themeCode);
await _preferences.setString(AppConstants.themePrefsKey, themeCode);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class LanguageBloc extends Bloc<LanguageEvent, LanguageState> {
await _sharedPreferencesService.saveSelectedLanguage(
event.selectedLanguage.code,
);

emit(state.copyWith(selectedLanguage: event.selectedLanguage));
}
}
42 changes: 30 additions & 12 deletions lib/src/features/main/theme/bloc/theme_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// lib/src/features/main/theme/bloc/theme_bloc.dart
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:gui/src/features/main/theme/bloc/theme_state.dart';
import '../../../../core/services/shared_preferences_service.dart';
import 'package:flutter/foundation.dart';

part 'theme_event.dart';

Expand All @@ -21,22 +22,39 @@ class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
InitializeThemeEvent event,
Emitter<ThemeState> emit,
) async {
final themeCode = await _sharedPreferencesService.getSelectedTheme();
final themeData = themeCode == ThemeMode.dark.name
? ThemeState.darkTheme
: ThemeState.lightTheme;
await _sharedPreferencesService.saveSelectedTheme(themeCode);
emit(state.copyWith(themeData: themeData));
try {
final themeCode = await _sharedPreferencesService.getSelectedTheme();
debugPrint('Initializing theme with code: $themeCode');

final FluentThemeData themeData = themeCode == ThemeMode.dark.name
? ThemeState.darkTheme
: ThemeState.lightTheme;

await _sharedPreferencesService.saveSelectedTheme(themeCode);
emit(state.copyWith(themeData: themeData));
debugPrint('Theme initialized successfully');
} catch (e) {
debugPrint('Error initializing theme: $e');
// Fallback to light theme in case of error
emit(state.copyWith(themeData: ThemeState.lightTheme));
}
}

Future<void> _onChangeTheme(
ChangeTheme event,
Emitter<ThemeState> emit,
) async {
final themeCode = event.themeData.brightness == Brightness.dark
? ThemeMode.dark.name
: ThemeMode.light.name;
await _sharedPreferencesService.saveSelectedTheme(themeCode);
emit(state.copyWith(themeData: event.themeData));
try {
final themeCode = event.themeData.brightness == Brightness.dark
? ThemeMode.dark.name
: ThemeMode.light.name;
debugPrint('Changing theme to: $themeCode');

await _sharedPreferencesService.saveSelectedTheme(themeCode);
emit(state.copyWith(themeData: event.themeData));
debugPrint('Theme changed successfully');
} catch (e) {
debugPrint('Error changing theme: $e');
}
}
}
2 changes: 1 addition & 1 deletion lib/src/features/main/theme/bloc/theme_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class InitializeThemeEvent extends ThemeEvent {}

class ChangeTheme extends ThemeEvent {
const ChangeTheme(this.themeData);
final ThemeData themeData;
final FluentThemeData themeData;

@override
List<Object> get props => [themeData];
Expand Down
10 changes: 5 additions & 5 deletions lib/src/features/main/theme/bloc/theme_state.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
// lib/src/features/main/theme/bloc/theme_state.dart
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:fluent_ui/fluent_ui.dart';

class ThemeState extends Equatable {
const ThemeState({
required this.themeData,
});
final ThemeData themeData;
final FluentThemeData themeData;

static ThemeData lightTheme = ThemeData(
static FluentThemeData lightTheme = FluentThemeData(
brightness: Brightness.light,
);
static ThemeData darkTheme = ThemeData.dark();
static FluentThemeData darkTheme = FluentThemeData.dark();

ThemeState copyWith({ThemeData? themeData}) {
ThemeState copyWith({FluentThemeData? themeData}) {
return ThemeState(
themeData: themeData ?? this.themeData,
);
Expand Down
Loading

0 comments on commit 691681e

Please sign in to comment.