// Version: 1.2.0 | Created: 2026-04-01 | Updated: 2026-04-02 // Rooms repository. Reads room list from the Matrix SDK client. import 'package:matrix/matrix.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../../../core/network/matrix_client.dart'; import '../../../shared/utils/mxc_url.dart'; import '../../../shared/utils/room_preview.dart'; import '../domain/room_model.dart'; part 'rooms_repository.g.dart'; @riverpod RoomsRepository roomsRepository(Ref ref) { return RoomsRepository(client: ref.watch(matrixClientProvider)); } class RoomsRepository { RoomsRepository({required Client client}) : _client = client; final Client _client; /// Returns the current room list, sorted unread-first then by last activity. List getRooms() { final rooms = _client.rooms; final models = rooms.map(_toModel).toList(); models.sort((a, b) { // Unread rooms first. if (a.unreadCount != b.unreadCount) { return b.unreadCount.compareTo(a.unreadCount); } // Then by most recent activity. final aTime = a.lastActivityAt ?? DateTime(0); final bTime = b.lastActivityAt ?? DateTime(0); return bTime.compareTo(aTime); }); return models; } /// Emits current rooms immediately, then re-emits on every sync. /// Immediate yield prevents indefinite spinner while waiting for first sync. Stream> watchRooms() async* { yield getRooms(); yield* _client.onSync.stream.map((_) => getRooms()); } RoomModel _toModel(Room room) { return RoomModel( id: room.id, displayName: room.getLocalizedDisplayname(), avatarUrl: resolveMxcUrl(_client, room.avatar), lastMessagePreview: lastMessagePreview(room), lastActivityAt: room.lastEvent?.originServerTs ?? room.timeCreated, unreadCount: room.notificationCount, isDirect: room.isDirectChat, ); } }