import "package:collection/collection.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/new_events_controller.dart"; import "package:nexus/models/read_receipt.dart"; import "package:nexus/models/room.dart"; class RoomsController extends Notifier> { @override IMap build() => const IMap.empty(); void update(IMap rooms, ISet leftRooms) { final merged = rooms.entries.fold(state, (acc, entry) { final roomId = entry.key; final incoming = entry.value; final existing = acc[roomId]; final events = existing?.events.updateById( incoming.events, (item) => item.eventId, ); ref .watch(NewEventsController.provider(roomId).notifier) .add( incoming.timeline .map( (timelineTuple) => events?.firstWhereOrNull( (event) => timelineTuple.eventRowId == event.rowId, ), ) .nonNulls .toIList(), ); return acc.add( roomId, existing?.copyWith( metadata: incoming.metadata ?? existing.metadata, events: events!, state: incoming.state.entries.fold( existing.state, (previousValue, event) => previousValue.add( event.key, (previousValue[event.key] ?? const IMap.empty()).addAll( event.value, ), ), ), timeline: (incoming.reset ? incoming.timeline : existing.timeline.updateById( incoming.timeline, (item) => item.timelineRowId, )) .sortedBy((element) => element.timelineRowId) .toIList(), receipts: incoming.receipts.entries.fold( existing.receipts, (receiptAcc, event) => receiptAcc.add( event.key, (receiptAcc[event.key] ?? IList()).addAll( event.value, ), ), ), ) ?? incoming, ); }); final prunedList = leftRooms.fold( merged, (acc, roomId) => acc.remove(roomId), ); state = prunedList; } static final provider = NotifierProvider>( RoomsController.new, ); }