diff --git a/lib/epics/groups.dart b/lib/epics/groups.dart index fc9473d..e72001b 100644 --- a/lib/epics/groups.dart +++ b/lib/epics/groups.dart @@ -8,7 +8,6 @@ import 'package:rxdart/rxdart.dart'; import 'package:supabase/supabase.dart'; createGroupsEpics(GroupsRepository groups) => combineEpics([ - _createRefreshRetrieveAllGroupsEpic(groups), _createRetrieveAllGroupsEpic(groups), _createRetrieveOneGroupEpic(groups), _createCreateOneGroupEpic(groups), @@ -48,30 +47,28 @@ Stream _loadGroupOnGroupDetailsOpenEpic( .whereType() .map((action) => RequestRetrieveOne(action.groupId)); -/// Let user refresh the groups, with an action including a Completer, to handle the refresh indicator. -Epic _createRefreshRetrieveAllGroupsEpic(GroupsRepository groups) { - return (Stream actions, EpicStore store) => actions - .whereType() - .asyncMap( - (action) => groups - .getUserGroups() - .then( - (groups) => SuccessRetrieveAll(groups.toList(growable: false))) - .catchError((error) => FailRetrieveAll(error)) - .whenComplete(() => action.completer.complete()), - ); -} - -/// Fetch all the groups from the database +/// Load all groups for the current user, together with their members and profiles. +/// If the action includes a Completer, complete, to handle the refresh indicator. Epic _createRetrieveAllGroupsEpic(GroupsRepository groups) { return (Stream actions, EpicStore store) => actions - .whereType>() - .asyncMap( + .where((action) => + action is GroupRefreshAllAction || + action is RequestRetrieveAll) + .switchMap( (action) => groups .getUserGroups() - .then( - (groups) => SuccessRetrieveAll(groups.toList(growable: false))) - .catchError((error) => FailRetrieveAll(error)), + .whenComplete(() => action is GroupRefreshAllAction + ? action.completer.complete() + : null) + .asStream() // TODO Would it be easier to dispatch 1 action here, and then rethink reducers? + .expand( + (userGroups) => [ + SuccessRetrieveAll(userGroups.groups.toList(growable: false)), + SuccessRetrieveMany(userGroups.members.toList(growable: false)), + SuccessRetrieveMany( + userGroups.profiles.toList(growable: false)), + ], + ), ); } diff --git a/lib/repositories/groups.dart b/lib/repositories/groups.dart index 87d365f..f727381 100644 --- a/lib/repositories/groups.dart +++ b/lib/repositories/groups.dart @@ -6,12 +6,29 @@ import 'supabase.dart'; class GroupsRepository extends SupabaseRepository with Postgrest { GroupsRepository({required super.supabase}) : super(tableName: Tables.groups); - Future> getUserGroups() async { + Future< + ({ + Iterable groups, + Iterable members, + Iterable profiles, + })> getUserGroups() async { return table() .select('*, members!inner(*,profiles!inner(*))') // TODO(borgoat): should filter by profile_id but return all members // .eq('members.profile_id', supabase.auth.currentUser!.id) - .withConverter((data) => data.map(Group.fromJson)); + .withConverter((data) { + final groups = {}; + final members = {}; + final profiles = {}; + for (var value in data) { + groups.add(Group.fromJson(value)); + for (var member in value['members']) { + members.add(Member.fromJson(member)); + profiles.add(Profile.fromJson(member['profiles'])); + } + } + return (groups: groups, members: members, profiles: profiles); + }); } Future getGroupById(int id) async {