Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Older state events overwrite newer ones on fetching history #2023

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading