Skip to content

Commit

Permalink
Merge pull request #2023 from famedly/krille/make-sure-we-do-not-over…
Browse files Browse the repository at this point in the history
…ride-state-on-fetch-history

fix: Older state events overwrite newer ones on fetching history
  • Loading branch information
krille-chan authored Feb 12, 2025
2 parents beef67b + fdbe95b commit 352b3fa
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
21 changes: 20 additions & 1 deletion lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2665,8 +2665,27 @@ class Client extends MatrixApi {
if (syncRoomUpdate is JoinedRoomUpdate) {
final state = syncRoomUpdate.state;

// If we are receiving states when fetching history we need to check if
// we are not overwriting a newer state.
if (direction == Direction.b) {
await room.postLoad();
state?.removeWhere((state) {
final existingState =
room.getState(state.type, state.stateKey ?? '');
if (existingState == null) return false;
if (existingState is User) {
return existingState.originServerTs
?.isAfter(state.originServerTs) ??
true;
}
if (existingState is MatrixEvent) {
return existingState.originServerTs.isAfter(state.originServerTs);
}
return true;
});
}

if (state != null && state.isNotEmpty) {
// TODO: This method seems to be comperatively slow for some updates
await _handleRoomEvents(
room,
state,
Expand Down
1 change: 1 addition & 0 deletions lib/src/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ class Event extends MatrixEvent {
typeKey: type,
senderId: senderId,
room: room,
originServerTs: originServerTs,
);

String get messageType => type == EventTypes.Sticker
Expand Down
5 changes: 5 additions & 0 deletions lib/src/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import 'package:matrix/matrix.dart';
class User extends StrippedStateEvent {
final Room room;
final Map<String, Object?>? prevContent;
final DateTime? originServerTs;

factory User(
String id, {
String? membership,
String? displayName,
String? avatarUrl,
DateTime? originServerTs,
required Room room,
}) {
return User.fromState(
Expand All @@ -40,6 +42,7 @@ class User extends StrippedStateEvent {
},
typeKey: EventTypes.RoomMember,
room: room,
originServerTs: originServerTs,
);
}

Expand All @@ -49,6 +52,7 @@ class User extends StrippedStateEvent {
required String typeKey,
required super.senderId,
required this.room,
this.originServerTs,
this.prevContent,
}) : super(
type: typeKey,
Expand Down Expand Up @@ -254,5 +258,6 @@ extension FromStrippedStateEventExtension on StrippedStateEvent {
typeKey: type,
senderId: senderId,
room: room,
originServerTs: null,
);
}
29 changes: 29 additions & 0 deletions test/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,35 @@ void main() {
);
expect(room.lastEvent!.content['body'], '* floooof');

// Older state event should not overwrite current state events
room.partial = false;
await matrix.handleSync(
SyncUpdate(
nextBatch: '',
rooms: RoomsUpdate(
join: {
room.id: JoinedRoomUpdate(
state: [
MatrixEvent(
type: EventTypes.RoomMember,
content: {'displayname': 'Alice Catgirl'},
senderId: '@alice:example.com',
eventId: 'oldEventId',
stateKey: '@alice:example.com',
originServerTs:
DateTime.now().subtract(const Duration(days: 365 * 30)),
),
],
),
},
),
),
direction: Direction.b,
);
room.partial = true;
expect(room.getParticipants().first.id, '@alice:example.com');
expect(room.getParticipants().first.displayName, 'Alice Margatroid');

// accepts a consecutive edit
await matrix.handleSync(
SyncUpdate.fromJson({
Expand Down

0 comments on commit 352b3fa

Please sign in to comment.