fix bug in timeline

This commit is contained in:
Henry Hiles 2026-01-30 14:26:59 +01:00
commit 0e6b9a8133
No known key found for this signature in database
4 changed files with 36 additions and 19 deletions

View file

@ -27,6 +27,16 @@ class RoomChatController extends AsyncNotifier<ChatController> {
final room = ref.read(SelectedRoomController.provider);
if (room == null) return InMemoryChatController();
final messages = await room.timeline
.map(
(timelineRowTuple) => room.events.firstWhereOrNull(
(event) => event.rowId == timelineRowTuple.eventRowId,
),
)
.nonNulls
.toMessages(ref);
final controller = InMemoryChatController(messages: messages);
ref.onDispose(
ref.listen(NewEventsController.provider(roomId), (_, next) async {
for (final event in next) {
@ -62,23 +72,17 @@ class RoomChatController extends AsyncNotifier<ChatController> {
),
);
}
if (message != null) {
return await insertMessage(message);
if (message != null &&
!controller.messages.any(
(oldMessage) => oldMessage.id == message.id,
)) {
await insertMessage(message);
}
}
}
}).close,
}, weak: true).close,
);
final messages = await room.timeline
.map(
(timelineRowTuple) => room.events.firstWhereOrNull(
(event) => event.rowId == timelineRowTuple.eventRowId,
),
)
.nonNulls
.toMessages(ref);
final controller = InMemoryChatController(messages: messages);
ref.onDispose(controller.dispose);
if (messages.length < 20) await loadOlder(controller);

View file

@ -15,18 +15,29 @@ class RoomsController extends Notifier<IMap<String, Room>> {
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.events);
.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: existing.events.updateById(
incoming.events,
(item) => item.eventId,
),
events: events!,
state: incoming.state.entries.fold(
existing.state,
(previousValue, event) => previousValue.add(

View file

@ -28,7 +28,7 @@ abstract class Room with _$Room {
abstract class TimelineRowTuple with _$TimelineRowTuple {
const factory TimelineRowTuple({
@JsonKey(name: "timeline_rowid") required int timelineRowId,
@JsonKey(name: "timeline_eventid") int? eventRowId,
@JsonKey(name: "event_rowid") int? eventRowId,
}) = _TimelineRowTuple;
factory TimelineRowTuple.fromJson(Map<String, Object?> json) =>

View file

@ -267,7 +267,9 @@ class RoomChat extends HookConsumerWidget {
chatAnimatedListBuilder: (_, itemBuilder) =>
ChatAnimatedList(
itemBuilder: itemBuilder,
onEndReached: notifier.loadOlder,
onEndReached: room.hasMore
? notifier.loadOlder
: null,
onStartReached: () => client.markRead(room),
bottomPadding: 72,
),