Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistent (Theme & Localization) Storage #31

Open
esmaeil-ahmadipour opened this issue Nov 28, 2024 · 3 comments · May be fixed by #46
Open

Persistent (Theme & Localization) Storage #31

esmaeil-ahmadipour opened this issue Nov 28, 2024 · 3 comments · May be fixed by #46
Assignees
Labels
feature Add/Create new feature

Comments

@esmaeil-ahmadipour
Copy link
Collaborator

esmaeil-ahmadipour commented Nov 28, 2024

Overview

Feature Description

Implement persistent localization storage and app state initialization to ensure the selected language, theme, and other relevant settings persist across app restarts.

Click to expand the scenario

Scenario: Language and Theme Persistence on Restart

A user selects French as their preferred language and dark mode as their theme. When reopening the app, it should automatically display in French with the dark theme applied, without requiring the user to reselect them.

References

FOLDER STRUCTURE

src
│
└──lib/
    ├── features ....
    └── core/
        ├── constants/
        │   └── app_constants.dart # App-wide constants (e.g., all keys used in  shared_preferences_service , etc )
        └── services/
            └── shared_preferences_service.dart # SharedPreferences wrapper for app-wide usage

Proposed Changes

  • Save and load user language, theme, and other app state using SharedPreferences.
  • Initialize app with saved preferences (language and theme) on startup.
@esmaeil-ahmadipour esmaeil-ahmadipour added the feature Add/Create new feature label Nov 28, 2024
@esmaeil-ahmadipour esmaeil-ahmadipour changed the title Persistent Localization Storage Persistent (Theme & Localization) Storage Nov 29, 2024
@esmaeil-ahmadipour esmaeil-ahmadipour pinned this issue Dec 13, 2024
@phoenixit99
Copy link

phoenixit99 commented Dec 26, 2024

📊 Current Status:

Progress: 100%
✔️ Completed Tasks:

Implemented localization.
Implemented theme.

🔄 Additional Information:

The default language has been set to English.
The default theme is configured to the system preference.

@esmaeil-ahmadipour esmaeil-ahmadipour unpinned this issue Dec 26, 2024
@esmaeil-ahmadipour esmaeil-ahmadipour linked a pull request Dec 26, 2024 that will close this issue
@esmaeil-ahmadipour
Copy link
Collaborator Author

esmaeil-ahmadipour commented Dec 26, 2024

@phoenixit99, I reviewed the code and found the following areas for improvement:

  1. We need a singleton object of SharedPreferences. I suggest using this code to reduce the cost of creating and using an asynchronous object:
locator code
/// The dependency injection container used throughout the application.
final locator = GetIt.instance;

/// Sets up and registers the shared preferences instance.
///
/// Ensures a `SharedPreferences` instance is available.
/// Creates a new instance if `param` is null.
/// Registers the instance as a singleton in `locator`.
///
/// **Parameters:**
///
/// * `param`: An optional `SharedPreferences` instance.
///   If provided, this instance will be used.
///   Otherwise, a new instance will be created.
///
/// **See also:**
///
/// * [SharedPreferences]
Future<SharedPreferences> setupSharedPreferences(
    {SharedPreferences? param}) async {
  final prefs = param ?? await SharedPreferences.getInstance();
  return locator.registerSingleton<SharedPreferences>(prefs);
}

2- The tests related to language and theme have failed and need to be fixed. To write tests for SharedPreferences , we need to add the mocktail: ^1.0.4 library. The code is expected to be written as follows:

locator code
/// The dependency injection container used throughout the application.
final locator = GetIt.instance;

/// Initializes all necessary dependencies for the application.
///
/// This function registers all required services, repositories, and other dependencies 
/// within the [locator] (GetIt instance).
void initDependencies() {
  // ... some codes need using as singleton
}

/// A mock implementation of `SharedPreferences` for testing purposes.
class MockSharedPreferences extends Mock implements SharedPreferences {}

/// Sets up the testing environment.
///
/// Initializes the `TestWidgetsFlutterBinding`, creates a mock `SharedPreferences` 
/// instance, initializes dependencies, and sets up the list of providers.
void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  late SharedPreferences sharedPreferencesObject;
  late List<BloProvider> providers; 

  setUpAll(() {
    sharedPreferencesObject = MockSharedPreferences();
    setupSharedPreferences(param: sharedPreferencesObject).then((_) {
      initDependencies();
      providers = [
        // ... scope of bloc providers
      ];
    });
  });


/// write main test code :

  group(
    'testing sample screen',
    () {
    /// bla bla bla
    }
}

@phoenixit99
Copy link

@phoenixit99, I reviewed the code and found the following areas for improvement:

  1. We need a singleton object of SharedPreferences. I suggest using this code to reduce the cost of creating and using an asynchronous object:

locator code
2- The tests related to language and theme have failed and need to be fixed. To write tests for SharedPreferences , we need to add the mocktail: ^1.0.4 library. The code is expected to be written as follows:

locator code

Thanks @esmaeil-ahmadipour . This has been really helpful and has saved me a lot of time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Add/Create new feature
Projects
None yet
3 participants