diff --git a/lib/controllers/client_controller.dart b/lib/controllers/client_controller.dart index 5ccdc27..fd84f5d 100644 --- a/lib/controllers/client_controller.dart +++ b/lib/controllers/client_controller.dart @@ -15,7 +15,6 @@ import "package:nexus/controllers/top_level_spaces_controller.dart"; import "package:nexus/helpers/extensions/gomuks_buffer.dart"; import "package:nexus/main.dart"; import "package:nexus/models/client_state.dart"; -import "package:nexus/models/content/content.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/paginate.dart"; import "package:nexus/models/requests/get_event_request.dart"; @@ -79,10 +78,17 @@ class ClientController extends AsyncNotifier { break; case "send_complete": final event = Event.fromJson(decodedMuksEvent["event"]); + ref + .watch(RoomsController.provider.notifier) + .update( + { + event.roomId: Room( + events: {event.rowId: event}.toIMap(), + ), + }.toIMap(), + const ISet.empty(), + ); - if (event.type == EventType.message.type) { - // ref.watch(provider.notifier).addEvent(event); TODO - } break; case "sync_complete": final syncData = SyncData.fromJson(decodedMuksEvent); diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index 028f2a1..d8fea0c 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -44,12 +44,16 @@ class RoomChatController extends AsyncNotifier> { loadOlder(); } - return room.timeline + return IMap.fromValues( + keyMapper: (id) => 9999999 + (id ?? 0), + values: room.sticky, + ) + .addAll(room.timeline) .toEntryIList(compare: (a, b) => (b?.key ?? 0).compareTo(a?.key ?? 0)) .map((entry) { - if (entry.value == null) return null; - - final foundEvent = room.events[entry.value!]; + final foundEvent = entry.value == null + ? null + : room.events[entry.value!]; final editedEvent = foundEvent == null || foundEvent.lastEditRowId == 0 @@ -153,23 +157,17 @@ class RoomChatController extends AsyncNotifier> { ), ); - // TODO: Add new event to timeline whilst its sending - // ref - // .watch(RoomsController.provider.notifier) - // .update( - // { - // roomId: Room( - // events: [event].toIList(), - // timeline: [ - // TimelineRowTuple( - // timelineRowId: event.timelineRowId, - // eventRowId: event.rowId, - // ), - // ].toIList(), - // ), - // }.toIMap(), - // const ISet.empty(), - // ); + ref + .watch(RoomsController.provider.notifier) + .update( + { + roomId: Room( + events: {event.rowId: event}.toIMap(), + sticky: {event.rowId}.toISet(), + ), + }.toIMap(), + const ISet.empty(), + ); } Future removeReaction( diff --git a/lib/controllers/rooms_controller.dart b/lib/controllers/rooms_controller.dart index 382fac4..c4b36c1 100644 --- a/lib/controllers/rooms_controller.dart +++ b/lib/controllers/rooms_controller.dart @@ -50,6 +50,13 @@ class RoomsController extends Notifier> { roomId, existing?.copyWith( hasMore: incoming.hasMore, + sticky: + (incoming.sticky.isEmpty == true + ? existing.sticky + : existing.sticky.addAll(incoming.sticky)) + .removeWhere( + (rowId) => incoming.timeline.values.contains(rowId), + ), metadata: incoming.metadata ?? existing.metadata, events: incoming.events.isEmpty ? existing.events diff --git a/lib/models/room.dart b/lib/models/room.dart index 8aaadbe..fb21a55 100644 --- a/lib/models/room.dart +++ b/lib/models/room.dart @@ -28,11 +28,13 @@ abstract class Room with _$Room { /// [timeline] is an IMap of timelineRowId to eventRowId /// [events] is an IMap of eventRowId to event + /// [sticky] is an ISet of eventRowId const factory Room({ @JsonKey(name: "meta") RoomMetadata? metadata, @Default(IMap.empty()) @JsonKey(fromJson: Room.timelineTupleJsonToIMap) IMap timeline, + @Default(ISet.empty()) ISet sticky, @Default(IMap.empty()) @JsonKey(fromJson: Room.eventsJsonToIMap) diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index 217c4d3..2302156 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -446,19 +446,22 @@ class EventRenderer extends ConsumerWidget { ), ), - if (event.content is! MessageContent) - Padding( - padding: EdgeInsetsGeometry.only(left: 12), - child: ReactionRow(event), - ), + ...[ + if (event.content is! MessageContent) ReactionRow(event), - if (event.sendError != null && event.sendError != "not sent") - Text( - event.sendError!, - style: theme.textTheme.labelSmall?.copyWith( - color: theme.colorScheme.error, + if (event.sendError != null && event.sendError != "not sent") + Text( + event.sendError!, + style: theme.textTheme.labelSmall?.copyWith( + color: theme.colorScheme.error, + ), ), + ].map( + (child) => Padding( + padding: EdgeInsetsGeometry.only(left: 4), + child: child, ), + ), ] else if (textOnly) Text("Unknown event type", style: errorStyle), ],