Skip to content

Store and show groups offline - #297

Merged
f-odc merged 3 commits into
devfrom
296-offline-groups
Oct 9, 2025
Merged

Store and show groups offline#297
f-odc merged 3 commits into
devfrom
296-offline-groups

Conversation

@f-odc

@f-odc f-odc commented Sep 29, 2025

Copy link
Copy Markdown
Contributor

Now users can see their groups and balance even if they are offline.
This PR was created in anticipation of longer server downtime or a permanent shutdown.

Screenshot From 2025-09-29 13-33-41

Closes #296

@f-odc
f-odc requested review from GR0ZA and Copilot September 29, 2025 11:38
@f-odc f-odc self-assigned this Sep 29, 2025
@f-odc f-odc linked an issue Sep 29, 2025 that may be closed by this pull request

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements offline storage functionality that allows users to view their groups and balance even when the server is unavailable, providing resilience against potential server downtime or shutdown.

  • Adds offline storage methods for groups, bills, and items using SharedPreferences
  • Implements fallback logic to load cached data when server requests fail
  • Enhances existing domain models with offline-specific serialization methods

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
lib/infrastructure/shared_preferences.dart Adds methods to store and retrieve groups from local storage
lib/domain/group/states/groups_state.dart Implements try-catch logic to fallback to cached data when server is unavailable
lib/domain/group/group.dart Adds toMapOffline() method for complete group serialization
lib/domain/bill/item.dart Adds toMapOffline() method for item serialization
lib/domain/bill/bill.dart Adds toMapOffline() method for bill serialization

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread lib/infrastructure/shared_preferences.dart Outdated
Comment thread lib/infrastructure/shared_preferences.dart Outdated
Comment thread lib/infrastructure/shared_preferences.dart Outdated

@GR0ZA GR0ZA left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice work 🚀
just one small thing

Future<List<Group>> _getGroupsByUser(String userId) async {
return await _groupRepository.getGroupsByUser(userId);
try {
// try to get groups from server

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comments are kinda superfluous here 😅 it's pretty clear what's happening already

Future<List<Group>> _getGroupsByUser(String userId) async {
return await _groupRepository.getGroupsByUser(userId);
try {
// try to get groups from server

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this caching logic should live inside the repository instead of here. The repository is responsible for data access, whether it comes from the network or local storage (yeah I know maybe we've done it differently somewhere else). This way we don't have to think about loading the local storage when we want to fetch groups, the repository does it automatically for us.

The repository could receive SharedUtility as a dependency:

@Riverpod(keepAlive: true)
GroupRepository groupRepository(Ref ref) {
  return RemoteGroupRepository(
    api: GroupAPI(),
    client: ref.read(httpClientProvider),
    sharedUtility: ref.read(sharedUtilityProvider),
  );
}

And the repository method could look like this:

...
final SharedUtility sharedUtility;
...

@override
Future<List<Group>> getGroupsByUser(String userId) async {
  try {
    final groups = await client.get(
      uri: api.getGroupsByUser(userId),
      builder: (data) {
        if (data == null || data.isEmpty) return [];
        return data.map((g) => Group.fromMap(g)).toList();
      },
    );

    sharedUtility.setGroups(groups);
    return groups;
  } catch (e) {
    return sharedUtility.getGroups();
  }
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed!

@f-odc
f-odc requested a review from GR0ZA October 9, 2025 16:20
@f-odc
f-odc merged commit 87f5e04 into dev Oct 9, 2025
1 check passed
@f-odc
f-odc deleted the 296-offline-groups branch October 9, 2025 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Offline Groups

3 participants