show messages whilst sending

This commit is contained in:
Henry Hiles 2026-05-26 12:07:43 -04:00
commit b836c3b06e
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
5 changed files with 51 additions and 35 deletions

View file

@ -15,7 +15,6 @@ import "package:nexus/controllers/top_level_spaces_controller.dart";
import "package:nexus/helpers/extensions/gomuks_buffer.dart"; import "package:nexus/helpers/extensions/gomuks_buffer.dart";
import "package:nexus/main.dart"; import "package:nexus/main.dart";
import "package:nexus/models/client_state.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/event.dart";
import "package:nexus/models/paginate.dart"; import "package:nexus/models/paginate.dart";
import "package:nexus/models/requests/get_event_request.dart"; import "package:nexus/models/requests/get_event_request.dart";
@ -79,10 +78,17 @@ class ClientController extends AsyncNotifier<int> {
break; break;
case "send_complete": case "send_complete":
final event = Event.fromJson(decodedMuksEvent["event"]); 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; break;
case "sync_complete": case "sync_complete":
final syncData = SyncData.fromJson(decodedMuksEvent); final syncData = SyncData.fromJson(decodedMuksEvent);

View file

@ -44,12 +44,16 @@ class RoomChatController extends AsyncNotifier<IList<Event>> {
loadOlder(); loadOlder();
} }
return room.timeline return IMap<int, int?>.fromValues(
keyMapper: (id) => 9999999 + (id ?? 0),
values: room.sticky,
)
.addAll(room.timeline)
.toEntryIList(compare: (a, b) => (b?.key ?? 0).compareTo(a?.key ?? 0)) .toEntryIList(compare: (a, b) => (b?.key ?? 0).compareTo(a?.key ?? 0))
.map((entry) { .map((entry) {
if (entry.value == null) return null; final foundEvent = entry.value == null
? null
final foundEvent = room.events[entry.value!]; : room.events[entry.value!];
final editedEvent = final editedEvent =
foundEvent == null || foundEvent.lastEditRowId == 0 foundEvent == null || foundEvent.lastEditRowId == 0
@ -153,23 +157,17 @@ class RoomChatController extends AsyncNotifier<IList<Event>> {
), ),
); );
// TODO: Add new event to timeline whilst its sending ref
// ref .watch(RoomsController.provider.notifier)
// .watch(RoomsController.provider.notifier) .update(
// .update( {
// { roomId: Room(
// roomId: Room( events: {event.rowId: event}.toIMap(),
// events: [event].toIList(), sticky: {event.rowId}.toISet(),
// timeline: [ ),
// TimelineRowTuple( }.toIMap(),
// timelineRowId: event.timelineRowId, const ISet.empty(),
// eventRowId: event.rowId, );
// ),
// ].toIList(),
// ),
// }.toIMap(),
// const ISet.empty(),
// );
} }
Future<void> removeReaction( Future<void> removeReaction(

View file

@ -50,6 +50,13 @@ class RoomsController extends Notifier<IMap<String, Room>> {
roomId, roomId,
existing?.copyWith( existing?.copyWith(
hasMore: incoming.hasMore, 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, metadata: incoming.metadata ?? existing.metadata,
events: incoming.events.isEmpty events: incoming.events.isEmpty
? existing.events ? existing.events

View file

@ -28,11 +28,13 @@ abstract class Room with _$Room {
/// [timeline] is an IMap of timelineRowId to eventRowId /// [timeline] is an IMap of timelineRowId to eventRowId
/// [events] is an IMap of eventRowId to event /// [events] is an IMap of eventRowId to event
/// [sticky] is an ISet of eventRowId
const factory Room({ const factory Room({
@JsonKey(name: "meta") RoomMetadata? metadata, @JsonKey(name: "meta") RoomMetadata? metadata,
@Default(IMap.empty()) @Default(IMap.empty())
@JsonKey(fromJson: Room.timelineTupleJsonToIMap) @JsonKey(fromJson: Room.timelineTupleJsonToIMap)
IMap<int, int?> timeline, IMap<int, int?> timeline,
@Default(ISet.empty()) ISet<int> sticky,
@Default(IMap.empty()) @Default(IMap.empty())
@JsonKey(fromJson: Room.eventsJsonToIMap) @JsonKey(fromJson: Room.eventsJsonToIMap)

View file

@ -446,19 +446,22 @@ class EventRenderer extends ConsumerWidget {
), ),
), ),
if (event.content is! MessageContent) ...[
Padding( if (event.content is! MessageContent) ReactionRow(event),
padding: EdgeInsetsGeometry.only(left: 12),
child: ReactionRow(event),
),
if (event.sendError != null && event.sendError != "not sent") if (event.sendError != null && event.sendError != "not sent")
Text( Text(
event.sendError!, event.sendError!,
style: theme.textTheme.labelSmall?.copyWith( style: theme.textTheme.labelSmall?.copyWith(
color: theme.colorScheme.error, color: theme.colorScheme.error,
),
), ),
].map(
(child) => Padding(
padding: EdgeInsetsGeometry.only(left: 4),
child: child,
), ),
),
] else if (textOnly) ] else if (textOnly)
Text("Unknown event type", style: errorStyle), Text("Unknown event type", style: errorStyle),
], ],