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 06bf054
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 333 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
2 changes: 1 addition & 1 deletion lib/src/core/common/widgets/theme_switcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ThemeSwitcher extends StatelessWidget {
GestureDetector(
onTap: () {
context.read<ThemeBloc>().add(
ChangeTheme(
ThemeChanged(
isLightTheme ? ThemeState.darkTheme : ThemeState.lightTheme,
),
);
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));
}
}
12 changes: 7 additions & 5 deletions lib/src/features/main/theme/bloc/theme_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// 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/core/enums/theme_modes.dart';
import 'package:gui/src/features/main/theme/bloc/theme_state.dart';
import '../../../../core/services/shared_preferences_service.dart';

Expand All @@ -11,7 +12,7 @@ class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
ThemeBloc(this._sharedPreferencesService)
: super(ThemeState(themeData: ThemeState.lightTheme)) {
on<InitializeThemeEvent>(_onInitializeTheme);
on<ChangeTheme>(_onChangeTheme);
on<ThemeChanged>(_onChangeTheme);
add(InitializeThemeEvent());
}

Expand All @@ -25,18 +26,19 @@ class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
final themeData = themeCode == ThemeMode.dark.name
? ThemeState.darkTheme
: ThemeState.lightTheme;

await _sharedPreferencesService.saveSelectedTheme(themeCode);
emit(state.copyWith(themeData: themeData));
}

Future<void> _onChangeTheme(
ChangeTheme event,
ThemeChanged event,
Emitter<ThemeState> emit,
) async {
final themeCode = event.themeData.brightness == Brightness.dark
final themeCode = event.theme.brightness == Brightness.dark
? ThemeMode.dark.name
: ThemeMode.light.name;
await _sharedPreferencesService.saveSelectedTheme(themeCode);
emit(state.copyWith(themeData: event.themeData));
emit(state.copyWith(themeData: event.theme));
}
}
8 changes: 4 additions & 4 deletions lib/src/features/main/theme/bloc/theme_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ abstract class ThemeEvent extends Equatable {

class InitializeThemeEvent extends ThemeEvent {}

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

@override
List<Object> get props => [themeData];
List<Object> get props => [theme];
}

class SystemThemeChanged extends ThemeEvent {}
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ThemeSelector extends StatelessWidget {
ElevatedButton(
onPressed: () {
context.read<ThemeBloc>().add(
ChangeTheme(
ThemeChanged(
isLightTheme ? ThemeState.darkTheme : ThemeState.lightTheme,
),
);
Expand Down
Loading

0 comments on commit 06bf054

Please sign in to comment.