Merge pull request #2056 from famedly/karthi/fix-prev-batch-invite-state

fix: set prev_batch first time from sync response correctly
This commit is contained in:
Karthikeyan S 2025-03-19 17:12:35 +05:30 committed by GitHub
commit 58637f89c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 134 additions and 14 deletions

View File

@ -331,6 +331,31 @@ class FakeMatrixApi extends BaseClient {
}; };
} }
// since direction is b, the start and end are reversed
static const Map<String, dynamic> emptyHistoryResponse = {
'start': 'simpleHistoryResponse', // next_batch
'end': null, // prev_batch
'chunk': [],
'state': [],
};
static const Map<String, dynamic> simpleHistoryResponse = {
'start': '1', // next_batch
'end': 'emptyHistoryResponse', // prev_batch
'chunk': [
{
'content': {'body': '0'},
'type': 'm.room.message',
'event_id': '0',
'room_id': 'new_room_id',
'sender': '@example:example.org',
'origin_server_ts': 1432735824653,
'unsigned': {'age': 1234},
'state_key': '',
},
],
'state': [],
};
static const Map<String, dynamic> messagesResponsePast = { static const Map<String, dynamic> messagesResponsePast = {
'start': 't47429-4392820_219380_26003_2265', 'start': 't47429-4392820_219380_26003_2265',
'end': 't47409-4357353_219380_26003_2265', 'end': 't47409-4357353_219380_26003_2265',
@ -1724,6 +1749,10 @@ class FakeMatrixApi extends BaseClient {
'origin_server_ts': 1432735824653, 'origin_server_ts': 1432735824653,
'unsigned': {'age': 1234}, 'unsigned': {'age': 1234},
}, },
'/client/v3/rooms/new_room_id/messages?from=emptyHistoryResponse&dir=b&limit=30&filter=%7B%22lazy_load_members%22%3Atrue%7D':
(var req) => emptyHistoryResponse,
'/client/v3/rooms/new_room_id/messages?from=1&dir=b&limit=30&filter=%7B%22lazy_load_members%22%3Atrue%7D':
(var req) => simpleHistoryResponse,
'/client/v3/rooms/!localpart%3Aserver.abc/messages?from=1234&dir=b&to=1234&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D': '/client/v3/rooms/!localpart%3Aserver.abc/messages?from=1234&dir=b&to=1234&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D':
(var req) => messagesResponsePast, (var req) => messagesResponsePast,
'/client/v3/rooms/!localpart%3Aserver.abc/messages?from=&dir=b&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D': '/client/v3/rooms/!localpart%3Aserver.abc/messages?from=&dir=b&limit=10&filter=%7B%22lazy_load_members%22%3Atrue%7D':

View File

@ -2984,14 +2984,18 @@ class Client extends MatrixApi {
(chatUpdate.unreadNotifications?.highlightCount ?? 0) || (chatUpdate.unreadNotifications?.highlightCount ?? 0) ||
chatUpdate.summary != null || chatUpdate.summary != null ||
chatUpdate.timeline?.prevBatch != null)) { chatUpdate.timeline?.prevBatch != null)) {
/// [InvitedRoomUpdate] doesn't have prev_batch, so we want to set it in case
/// the room first appeared in sync update when membership was invite.
if (rooms[roomIndex].membership == Membership.invite &&
chatUpdate.timeline?.prevBatch != null) {
rooms[roomIndex].prev_batch = chatUpdate.timeline?.prevBatch;
}
rooms[roomIndex].membership = membership; rooms[roomIndex].membership = membership;
rooms[roomIndex].notificationCount = rooms[roomIndex].notificationCount =
chatUpdate.unreadNotifications?.notificationCount ?? 0; chatUpdate.unreadNotifications?.notificationCount ?? 0;
rooms[roomIndex].highlightCount = rooms[roomIndex].highlightCount =
chatUpdate.unreadNotifications?.highlightCount ?? 0; chatUpdate.unreadNotifications?.highlightCount ?? 0;
if (chatUpdate.timeline?.prevBatch != null) {
rooms[roomIndex].prev_batch = chatUpdate.timeline?.prevBatch;
}
final summary = chatUpdate.summary; final summary = chatUpdate.summary;
if (summary != null) { if (summary != null) {
final roomSummaryJson = rooms[roomIndex].summary.toJson() final roomSummaryJson = rooms[roomIndex].summary.toJson()

View File

@ -761,21 +761,59 @@ void main() {
expect(room.lastEvent!.content['body'], '* foxies'); expect(room.lastEvent!.content['body'], '* foxies');
}); });
test('set prev_batch if in sync', () async { test('set prev_batch when invite then join', () async {
final roomId = '!726s6s6q:example.com';
final room = matrix.getRoomById(roomId)!;
expect(room.prev_batch, 't44-23535_0_0');
// put an important state event in-memory
await matrix.handleSync( await matrix.handleSync(
SyncUpdate.fromJson({ SyncUpdate.fromJson({
'next_batch': 'fakesync', 'next_batch': '1',
'rooms': {
'invite': {
'new_room_id': {
'invite_state': {
'events': [
MatrixEvent(
eventId: '0',
type: EventTypes.RoomCreate,
content: {'body': '0'},
senderId: '@alice:example.com',
stateKey: '@alice:example.com',
originServerTs: DateTime.now(),
).toJson(),
],
},
},
},
},
}),
);
expect(
matrix.rooms.singleWhereOrNull(
(element) => element.id == 'new_room_id',
),
isNotNull,
);
final newRoom = matrix.getRoomById('new_room_id')!;
expect(newRoom.prev_batch, null);
await matrix.handleSync(
SyncUpdate.fromJson({
'next_batch': '3',
'rooms': { 'rooms': {
'join': { 'join': {
roomId: { 'new_room_id': {
'timeline': { 'timeline': {
'events': [], 'events': [
'prev_batch': 'prev_batch_1', MatrixEvent(
eventId: '2',
type: EventTypes.RoomCreate,
content: {'body': '2'},
senderId: '@alice:example.com',
stateKey: '@alice:example.com',
originServerTs: DateTime.now(),
).toJson(),
],
'prev_batch': '1',
}, },
}, },
}, },
@ -783,7 +821,56 @@ void main() {
}), }),
); );
expect(room.prev_batch, 'prev_batch_1'); final timeline = await newRoom.getTimeline();
expect(newRoom.prev_batch, '1');
expect(timeline.events.length, 1);
expect(timeline.events.first.eventId, '2');
await matrix.handleSync(
SyncUpdate.fromJson({
'next_batch': '4',
'rooms': {
'join': {
'new_room_id': {
'timeline': {
'events': [
MatrixEvent(
eventId: '3',
type: EventTypes.Message,
content: {'body': '3'},
senderId: '@alice2:example.com',
stateKey: '@alice2:example.com',
originServerTs: DateTime.now(),
).toJson(),
],
'prev_batch': '2',
},
},
},
},
}),
);
expect(newRoom.prev_batch, '1');
expect(timeline.events.length, 2);
expect(timeline.events.last.eventId, '2');
expect(timeline.events.first.eventId, '3');
if (timeline.canRequestHistory) {
await timeline.requestHistory();
}
expect(newRoom.prev_batch, 'emptyHistoryResponse');
expect(timeline.events.length, 3);
expect(timeline.events.last.eventId, '0');
expect(timeline.events.first.eventId, '3');
while (timeline.canRequestHistory) {
await timeline.requestHistory();
}
expect(newRoom.prev_batch, null);
expect(timeline.events.length, 3);
expect(timeline.events.last.eventId, '0');
expect(timeline.events.first.eventId, '3');
}); });
test('getProfileFromUserId', () async { test('getProfileFromUserId', () async {