@unwanted/matrix-sdk-mini 34.12.0-8 → 34.12.0-9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +11 -11
- package/lib/client.js.map +1 -1
- package/lib/embedded.d.ts.map +1 -1
- package/lib/embedded.js +35 -2
- package/lib/embedded.js.map +1 -1
- package/lib/models/event-timeline-set.d.ts +6 -10
- package/lib/models/event-timeline-set.d.ts.map +1 -1
- package/lib/models/event-timeline-set.js +28 -36
- package/lib/models/event-timeline-set.js.map +1 -1
- package/lib/models/event-timeline.d.ts +7 -2
- package/lib/models/event-timeline.d.ts.map +1 -1
- package/lib/models/event-timeline.js +8 -9
- package/lib/models/event-timeline.js.map +1 -1
- package/lib/models/event.d.ts.map +1 -1
- package/lib/models/event.js +1 -1
- package/lib/models/event.js.map +1 -1
- package/lib/models/room-state.d.ts +2 -13
- package/lib/models/room-state.d.ts.map +1 -1
- package/lib/models/room-state.js +2 -30
- package/lib/models/room-state.js.map +1 -1
- package/lib/models/room.d.ts +2 -2
- package/lib/models/room.d.ts.map +1 -1
- package/lib/models/room.js +27 -14
- package/lib/models/room.js.map +1 -1
- package/lib/models/thread.d.ts.map +1 -1
- package/lib/models/thread.js +5 -3
- package/lib/models/thread.js.map +1 -1
- package/lib/sliding-sync-sdk.d.ts +1 -1
- package/lib/sliding-sync-sdk.d.ts.map +1 -1
- package/lib/sliding-sync-sdk.js +15 -13
- package/lib/sliding-sync-sdk.js.map +1 -1
- package/lib/sync-accumulator.d.ts +6 -4
- package/lib/sync-accumulator.d.ts.map +1 -1
- package/lib/sync-accumulator.js +23 -12
- package/lib/sync-accumulator.js.map +1 -1
- package/lib/sync.d.ts +10 -1
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +93 -42
- package/lib/sync.js.map +1 -1
- package/package.json +6 -6
- package/src/client.ts +11 -11
- package/src/embedded.ts +35 -2
- package/src/models/event-timeline-set.ts +17 -38
- package/src/models/event-timeline.ts +10 -5
- package/src/models/event.ts +3 -1
- package/src/models/room-state.ts +2 -29
- package/src/models/room.ts +18 -6
- package/src/models/thread.ts +4 -2
- package/src/sliding-sync-sdk.ts +8 -11
- package/src/sync-accumulator.ts +33 -16
- package/src/sync.ts +111 -45
package/src/sync-accumulator.ts
CHANGED
@@ -77,7 +77,9 @@ export interface ITimeline {
|
|
77
77
|
|
78
78
|
export interface IJoinedRoom {
|
79
79
|
"summary": IRoomSummary;
|
80
|
-
|
80
|
+
// One of `state` or `state_after` is required.
|
81
|
+
"state"?: IState;
|
82
|
+
"org.matrix.msc4222.state_after"?: IState; // https://github.com/matrix-org/matrix-spec-proposals/pull/4222
|
81
83
|
"timeline": ITimeline;
|
82
84
|
"ephemeral": IEphemeral;
|
83
85
|
"account_data": IAccountData;
|
@@ -106,9 +108,11 @@ export interface IInvitedRoom {
|
|
106
108
|
}
|
107
109
|
|
108
110
|
export interface ILeftRoom {
|
109
|
-
state
|
110
|
-
|
111
|
-
|
111
|
+
// One of `state` or `state_after` is required.
|
112
|
+
"state"?: IState;
|
113
|
+
"org.matrix.msc4222.state_after"?: IState;
|
114
|
+
"timeline": ITimeline;
|
115
|
+
"account_data": IAccountData;
|
112
116
|
}
|
113
117
|
|
114
118
|
export interface IKnockedRoom {
|
@@ -481,13 +485,18 @@ export class SyncAccumulator {
|
|
481
485
|
// Work out the current state. The deltas need to be applied in the order:
|
482
486
|
// - existing state which didn't come down /sync.
|
483
487
|
// - State events under the 'state' key.
|
484
|
-
// - State events in the 'timeline'.
|
488
|
+
// - State events under the 'state_after' key OR state events in the 'timeline' if 'state_after' is not present.
|
485
489
|
data.state?.events?.forEach((e) => {
|
486
490
|
setState(currentData._currentState, e);
|
487
491
|
});
|
488
|
-
data.
|
489
|
-
// this nops if 'e' isn't a state event
|
492
|
+
data["org.matrix.msc4222.state_after"]?.events?.forEach((e) => {
|
490
493
|
setState(currentData._currentState, e);
|
494
|
+
});
|
495
|
+
data.timeline?.events?.forEach((e, index) => {
|
496
|
+
if (!data["org.matrix.msc4222.state_after"]) {
|
497
|
+
// this nops if 'e' isn't a state event
|
498
|
+
setState(currentData._currentState, e);
|
499
|
+
}
|
491
500
|
// append the event to the timeline. The back-pagination token
|
492
501
|
// corresponds to the first event in the timeline
|
493
502
|
let transformedEvent: TaggedEvent;
|
@@ -563,17 +572,22 @@ export class SyncAccumulator {
|
|
563
572
|
});
|
564
573
|
Object.keys(this.joinRooms).forEach((roomId) => {
|
565
574
|
const roomData = this.joinRooms[roomId];
|
566
|
-
const roomJson: IJoinedRoom
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
575
|
+
const roomJson: IJoinedRoom & {
|
576
|
+
// We track both `state` and `state_after` for downgrade compatibility
|
577
|
+
"state": IState;
|
578
|
+
"org.matrix.msc4222.state_after": IState;
|
579
|
+
} = {
|
580
|
+
"ephemeral": { events: [] },
|
581
|
+
"account_data": { events: [] },
|
582
|
+
"state": { events: [] },
|
583
|
+
"org.matrix.msc4222.state_after": { events: [] },
|
584
|
+
"timeline": {
|
571
585
|
events: [],
|
572
586
|
prev_batch: null,
|
573
587
|
},
|
574
|
-
unread_notifications: roomData._unreadNotifications,
|
575
|
-
unread_thread_notifications: roomData._unreadThreadNotifications,
|
576
|
-
summary: roomData._summary as IRoomSummary,
|
588
|
+
"unread_notifications": roomData._unreadNotifications,
|
589
|
+
"unread_thread_notifications": roomData._unreadThreadNotifications,
|
590
|
+
"summary": roomData._summary as IRoomSummary,
|
577
591
|
};
|
578
592
|
// Add account data
|
579
593
|
Object.keys(roomData._accountData).forEach((evType) => {
|
@@ -650,8 +664,11 @@ export class SyncAccumulator {
|
|
650
664
|
Object.keys(roomData._currentState).forEach((evType) => {
|
651
665
|
Object.keys(roomData._currentState[evType]).forEach((stateKey) => {
|
652
666
|
let ev = roomData._currentState[evType][stateKey];
|
667
|
+
// Push to both fields to provide downgrade compatibility in the sync accumulator db
|
668
|
+
// the code will prefer `state_after` if it is present
|
669
|
+
roomJson["org.matrix.msc4222.state_after"].events.push(ev);
|
670
|
+
// Roll the state back to the value at the start of the timeline if it was changed
|
653
671
|
if (rollBackState[evType] && rollBackState[evType][stateKey]) {
|
654
|
-
// use the reverse clobbered event instead.
|
655
672
|
ev = rollBackState[evType][stateKey];
|
656
673
|
}
|
657
674
|
roomJson.state.events.push(ev);
|
package/src/sync.ts
CHANGED
@@ -161,14 +161,15 @@ export enum SetPresence {
|
|
161
161
|
}
|
162
162
|
|
163
163
|
interface ISyncParams {
|
164
|
-
filter?: string;
|
165
|
-
timeout: number;
|
166
|
-
since?: string;
|
164
|
+
"filter"?: string;
|
165
|
+
"timeout": number;
|
166
|
+
"since"?: string;
|
167
167
|
// eslint-disable-next-line camelcase
|
168
|
-
full_state?: boolean;
|
168
|
+
"full_state"?: boolean;
|
169
169
|
// eslint-disable-next-line camelcase
|
170
|
-
set_presence?: SetPresence;
|
171
|
-
_cacheBuster?: string | number; // not part of the API itself
|
170
|
+
"set_presence"?: SetPresence;
|
171
|
+
"_cacheBuster"?: string | number; // not part of the API itself
|
172
|
+
"org.matrix.msc4222.use_state_after"?: boolean; // https://github.com/matrix-org/matrix-spec-proposals/pull/4222
|
172
173
|
}
|
173
174
|
|
174
175
|
type WrappedRoom<T> = T & {
|
@@ -330,8 +331,9 @@ export class SyncApi {
|
|
330
331
|
);
|
331
332
|
|
332
333
|
const qps: ISyncParams = {
|
333
|
-
timeout: 0, // don't want to block since this is a single isolated req
|
334
|
-
filter: filterId,
|
334
|
+
"timeout": 0, // don't want to block since this is a single isolated req
|
335
|
+
"filter": filterId,
|
336
|
+
"org.matrix.msc4222.use_state_after": true,
|
335
337
|
};
|
336
338
|
|
337
339
|
const data = await client.http.authedRequest<ISyncResponse>(Method.Get, "/sync", qps as any, undefined, {
|
@@ -361,21 +363,17 @@ export class SyncApi {
|
|
361
363
|
prev_batch: null,
|
362
364
|
events: [],
|
363
365
|
};
|
364
|
-
const events = this.mapSyncEventsFormat(leaveObj.timeline, room);
|
365
|
-
|
366
|
-
const stateEvents = this.mapSyncEventsFormat(leaveObj.state, room);
|
367
|
-
|
368
366
|
// set the back-pagination token. Do this *before* adding any
|
369
367
|
// events so that clients can start back-paginating.
|
370
368
|
room.getLiveTimeline().setPaginationToken(leaveObj.timeline.prev_batch, EventTimeline.BACKWARDS);
|
371
369
|
|
372
|
-
await this.
|
370
|
+
const { timelineEvents } = await this.mapAndInjectRoomEvents(leaveObj);
|
373
371
|
|
374
372
|
room.recalculate();
|
375
373
|
client.store.storeRoom(room);
|
376
374
|
client.emit(ClientEvent.Room, room);
|
377
375
|
|
378
|
-
this.processEventsForNotifs(room,
|
376
|
+
this.processEventsForNotifs(room, timelineEvents);
|
379
377
|
return room;
|
380
378
|
}),
|
381
379
|
);
|
@@ -450,6 +448,7 @@ export class SyncApi {
|
|
450
448
|
this._peekRoom.addEventsToTimeline(
|
451
449
|
messages.reverse(),
|
452
450
|
true,
|
451
|
+
true,
|
453
452
|
this._peekRoom.getLiveTimeline(),
|
454
453
|
response.messages.start,
|
455
454
|
);
|
@@ -537,7 +536,7 @@ export class SyncApi {
|
|
537
536
|
})
|
538
537
|
.map(this.client.getEventMapper());
|
539
538
|
|
540
|
-
await peekRoom.addLiveEvents(events);
|
539
|
+
await peekRoom.addLiveEvents(events, { addToState: true });
|
541
540
|
this.peekPoll(peekRoom, res.end);
|
542
541
|
},
|
543
542
|
(err) => {
|
@@ -938,7 +937,11 @@ export class SyncApi {
|
|
938
937
|
filter = this.getGuestFilter();
|
939
938
|
}
|
940
939
|
|
941
|
-
const qps: ISyncParams = {
|
940
|
+
const qps: ISyncParams = {
|
941
|
+
filter,
|
942
|
+
timeout,
|
943
|
+
"org.matrix.msc4222.use_state_after": true,
|
944
|
+
};
|
942
945
|
|
943
946
|
if (this.opts.disablePresence) {
|
944
947
|
qps.set_presence = SetPresence.Offline;
|
@@ -1200,7 +1203,7 @@ export class SyncApi {
|
|
1200
1203
|
const room = inviteObj.room;
|
1201
1204
|
const stateEvents = this.mapSyncEventsFormat(inviteObj.invite_state, room);
|
1202
1205
|
|
1203
|
-
await this.injectRoomEvents(room, stateEvents);
|
1206
|
+
await this.injectRoomEvents(room, stateEvents, undefined);
|
1204
1207
|
|
1205
1208
|
if (inviteObj.isBrandNewRoom) {
|
1206
1209
|
room.recalculate();
|
@@ -1219,15 +1222,24 @@ export class SyncApi {
|
|
1219
1222
|
await promiseMapSeries(joinRooms, async (joinObj) => {
|
1220
1223
|
const room = joinObj.room;
|
1221
1224
|
const stateEvents = this.mapSyncEventsFormat(joinObj.state, room);
|
1225
|
+
const stateAfterEvents = this.mapSyncEventsFormat(joinObj["org.matrix.msc4222.state_after"], room);
|
1222
1226
|
// Prevent events from being decrypted ahead of time
|
1223
1227
|
// this helps large account to speed up faster
|
1224
1228
|
// room::decryptCriticalEvent is in charge of decrypting all the events
|
1225
1229
|
// required for a client to function properly
|
1226
|
-
const
|
1230
|
+
const timelineEvents = this.mapSyncEventsFormat(joinObj.timeline, room, false);
|
1227
1231
|
const ephemeralEvents = this.mapSyncEventsFormat(joinObj.ephemeral);
|
1228
1232
|
const accountDataEvents = this.mapSyncEventsFormat(joinObj.account_data);
|
1229
1233
|
|
1230
|
-
|
1234
|
+
// If state_after is present, this is the events that form the state at the end of the timeline block and
|
1235
|
+
// regular timeline events do *not* count towards state. If it's not present, then the state is formed by
|
1236
|
+
// the state events plus the timeline events. Note mapSyncEventsFormat returns an empty array if the field
|
1237
|
+
// is absent so we explicitly check the field on the original object.
|
1238
|
+
const eventsFormingFinalState = joinObj["org.matrix.msc4222.state_after"]
|
1239
|
+
? stateAfterEvents
|
1240
|
+
: stateEvents.concat(timelineEvents);
|
1241
|
+
|
1242
|
+
const encrypted = this.isRoomEncrypted(room, eventsFormingFinalState);
|
1231
1243
|
// We store the server-provided value first so it's correct when any of the events fire.
|
1232
1244
|
if (joinObj.unread_notifications) {
|
1233
1245
|
/**
|
@@ -1315,8 +1327,8 @@ export class SyncApi {
|
|
1315
1327
|
// which we'll try to paginate but not get any new events (which
|
1316
1328
|
// will stop us linking the empty timeline into the chain).
|
1317
1329
|
//
|
1318
|
-
for (let i =
|
1319
|
-
const eventId =
|
1330
|
+
for (let i = timelineEvents.length - 1; i >= 0; i--) {
|
1331
|
+
const eventId = timelineEvents[i].getId()!;
|
1320
1332
|
if (room.getTimelineForEvent(eventId)) {
|
1321
1333
|
debuglog(`Already have event ${eventId} in limited sync - not resetting`);
|
1322
1334
|
limited = false;
|
@@ -1324,7 +1336,7 @@ export class SyncApi {
|
|
1324
1336
|
// we might still be missing some of the events before i;
|
1325
1337
|
// we don't want to be adding them to the end of the
|
1326
1338
|
// timeline because that would put them out of order.
|
1327
|
-
|
1339
|
+
timelineEvents.splice(0, i);
|
1328
1340
|
|
1329
1341
|
// XXX: there's a problem here if the skipped part of the
|
1330
1342
|
// timeline modifies the state set in stateEvents, because
|
@@ -1353,7 +1365,17 @@ export class SyncApi {
|
|
1353
1365
|
}
|
1354
1366
|
|
1355
1367
|
try {
|
1356
|
-
|
1368
|
+
if ("org.matrix.msc4222.state_after" in joinObj) {
|
1369
|
+
await this.injectRoomEvents(
|
1370
|
+
room,
|
1371
|
+
undefined,
|
1372
|
+
stateAfterEvents,
|
1373
|
+
timelineEvents,
|
1374
|
+
syncEventData.fromCache,
|
1375
|
+
);
|
1376
|
+
} else {
|
1377
|
+
await this.injectRoomEvents(room, stateEvents, undefined, timelineEvents, syncEventData.fromCache);
|
1378
|
+
}
|
1357
1379
|
} catch (e) {
|
1358
1380
|
logger.error(`Failed to process events on room ${room.roomId}:`, e);
|
1359
1381
|
}
|
@@ -1377,11 +1399,11 @@ export class SyncApi {
|
|
1377
1399
|
client.emit(ClientEvent.Room, room);
|
1378
1400
|
}
|
1379
1401
|
|
1380
|
-
this.processEventsForNotifs(room,
|
1402
|
+
this.processEventsForNotifs(room, timelineEvents);
|
1381
1403
|
|
1382
1404
|
const emitEvent = (e: MatrixEvent): boolean => client.emit(ClientEvent.Event, e);
|
1383
1405
|
stateEvents.forEach(emitEvent);
|
1384
|
-
|
1406
|
+
timelineEvents.forEach(emitEvent);
|
1385
1407
|
ephemeralEvents.forEach(emitEvent);
|
1386
1408
|
accountDataEvents.forEach(emitEvent);
|
1387
1409
|
});
|
@@ -1389,11 +1411,9 @@ export class SyncApi {
|
|
1389
1411
|
// Handle leaves (e.g. kicked rooms)
|
1390
1412
|
await promiseMapSeries(leaveRooms, async (leaveObj) => {
|
1391
1413
|
const room = leaveObj.room;
|
1392
|
-
const stateEvents = this.
|
1393
|
-
const events = this.mapSyncEventsFormat(leaveObj.timeline, room);
|
1414
|
+
const { timelineEvents, stateEvents, stateAfterEvents } = await this.mapAndInjectRoomEvents(leaveObj);
|
1394
1415
|
const accountDataEvents = this.mapSyncEventsFormat(leaveObj.account_data);
|
1395
1416
|
|
1396
|
-
await this.injectRoomEvents(room, stateEvents, events);
|
1397
1417
|
room.addAccountData(accountDataEvents);
|
1398
1418
|
|
1399
1419
|
room.recalculate();
|
@@ -1402,12 +1422,15 @@ export class SyncApi {
|
|
1402
1422
|
client.emit(ClientEvent.Room, room);
|
1403
1423
|
}
|
1404
1424
|
|
1405
|
-
this.processEventsForNotifs(room,
|
1425
|
+
this.processEventsForNotifs(room, timelineEvents);
|
1406
1426
|
|
1407
|
-
stateEvents
|
1427
|
+
stateEvents?.forEach(function (e) {
|
1408
1428
|
client.emit(ClientEvent.Event, e);
|
1409
1429
|
});
|
1410
|
-
|
1430
|
+
stateAfterEvents?.forEach(function (e) {
|
1431
|
+
client.emit(ClientEvent.Event, e);
|
1432
|
+
});
|
1433
|
+
timelineEvents.forEach(function (e) {
|
1411
1434
|
client.emit(ClientEvent.Event, e);
|
1412
1435
|
});
|
1413
1436
|
accountDataEvents.forEach(function (e) {
|
@@ -1420,7 +1443,7 @@ export class SyncApi {
|
|
1420
1443
|
const room = knockObj.room;
|
1421
1444
|
const stateEvents = this.mapSyncEventsFormat(knockObj.knock_state, room);
|
1422
1445
|
|
1423
|
-
await this.injectRoomEvents(room, stateEvents);
|
1446
|
+
await this.injectRoomEvents(room, stateEvents, undefined);
|
1424
1447
|
|
1425
1448
|
if (knockObj.isBrandNewRoom) {
|
1426
1449
|
room.recalculate();
|
@@ -1445,7 +1468,7 @@ export class SyncApi {
|
|
1445
1468
|
return a.getTs() - b.getTs();
|
1446
1469
|
});
|
1447
1470
|
this.notifEvents.forEach(function (event) {
|
1448
|
-
client.getNotifTimelineSet()?.addLiveEvent(event);
|
1471
|
+
client.getNotifTimelineSet()?.addLiveEvent(event, { addToState: true });
|
1449
1472
|
});
|
1450
1473
|
}
|
1451
1474
|
}
|
@@ -1572,7 +1595,7 @@ export class SyncApi {
|
|
1572
1595
|
}
|
1573
1596
|
|
1574
1597
|
private mapSyncEventsFormat(
|
1575
|
-
obj: IInviteState | ITimeline | IEphemeral,
|
1598
|
+
obj: IInviteState | ITimeline | IEphemeral | undefined,
|
1576
1599
|
room?: Room,
|
1577
1600
|
decrypt = true,
|
1578
1601
|
): MatrixEvent[] {
|
@@ -1640,28 +1663,69 @@ export class SyncApi {
|
|
1640
1663
|
|
1641
1664
|
// When processing the sync response we cannot rely on Room.hasEncryptionStateEvent we actually
|
1642
1665
|
// inject the events into the room object, so we have to inspect the events themselves.
|
1643
|
-
private isRoomEncrypted(room: Room,
|
1644
|
-
return (
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1666
|
+
private isRoomEncrypted(room: Room, eventsFormingFinalState: MatrixEvent[]): boolean {
|
1667
|
+
return room.hasEncryptionStateEvent() || !!this.findEncryptionEvent(eventsFormingFinalState);
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
private async mapAndInjectRoomEvents(wrappedRoom: WrappedRoom<ILeftRoom>): Promise<{
|
1671
|
+
timelineEvents: MatrixEvent[];
|
1672
|
+
stateEvents?: MatrixEvent[];
|
1673
|
+
stateAfterEvents?: MatrixEvent[];
|
1674
|
+
}> {
|
1675
|
+
const stateEvents = this.mapSyncEventsFormat(wrappedRoom.state, wrappedRoom.room);
|
1676
|
+
const stateAfterEvents = this.mapSyncEventsFormat(
|
1677
|
+
wrappedRoom["org.matrix.msc4222.state_after"],
|
1678
|
+
wrappedRoom.room,
|
1648
1679
|
);
|
1680
|
+
const timelineEvents = this.mapSyncEventsFormat(wrappedRoom.timeline, wrappedRoom.room);
|
1681
|
+
|
1682
|
+
if ("org.matrix.msc4222.state_after" in wrappedRoom) {
|
1683
|
+
await this.injectRoomEvents(wrappedRoom.room, undefined, stateAfterEvents, timelineEvents);
|
1684
|
+
} else {
|
1685
|
+
await this.injectRoomEvents(wrappedRoom.room, stateEvents, undefined, timelineEvents);
|
1686
|
+
}
|
1687
|
+
|
1688
|
+
return { timelineEvents, stateEvents, stateAfterEvents };
|
1649
1689
|
}
|
1650
1690
|
|
1651
1691
|
/**
|
1652
1692
|
* Injects events into a room's model.
|
1653
1693
|
* @param stateEventList - A list of state events. This is the state
|
1654
1694
|
* at the *START* of the timeline list if it is supplied.
|
1695
|
+
* @param stateAfterEventList - A list of state events. This is the state
|
1696
|
+
* at the *END* of the timeline list if it is supplied.
|
1655
1697
|
* @param timelineEventList - A list of timeline events, including threaded. Lower index
|
1656
1698
|
* is earlier in time. Higher index is later.
|
1657
1699
|
* @param fromCache - whether the sync response came from cache
|
1700
|
+
*
|
1701
|
+
* No more than one of stateEventList and stateAfterEventList must be supplied. If
|
1702
|
+
* stateEventList is supplied, the events in timelineEventList are added to the state
|
1703
|
+
* after stateEventList. If stateAfterEventList is supplied, the events in timelineEventList
|
1704
|
+
* are not added to the state.
|
1658
1705
|
*/
|
1659
1706
|
public async injectRoomEvents(
|
1660
1707
|
room: Room,
|
1661
1708
|
stateEventList: MatrixEvent[],
|
1709
|
+
stateAfterEventList: undefined,
|
1710
|
+
timelineEventList?: MatrixEvent[],
|
1711
|
+
fromCache?: boolean,
|
1712
|
+
): Promise<void>;
|
1713
|
+
public async injectRoomEvents(
|
1714
|
+
room: Room,
|
1715
|
+
stateEventList: undefined,
|
1716
|
+
stateAfterEventList: MatrixEvent[],
|
1717
|
+
timelineEventList?: MatrixEvent[],
|
1718
|
+
fromCache?: boolean,
|
1719
|
+
): Promise<void>;
|
1720
|
+
public async injectRoomEvents(
|
1721
|
+
room: Room,
|
1722
|
+
stateEventList: MatrixEvent[] | undefined,
|
1723
|
+
stateAfterEventList: MatrixEvent[] | undefined,
|
1662
1724
|
timelineEventList?: MatrixEvent[],
|
1663
1725
|
fromCache = false,
|
1664
1726
|
): Promise<void> {
|
1727
|
+
const eitherStateEventList = stateAfterEventList ?? stateEventList!;
|
1728
|
+
|
1665
1729
|
// If there are no events in the timeline yet, initialise it with
|
1666
1730
|
// the given state events
|
1667
1731
|
const liveTimeline = room.getLiveTimeline();
|
@@ -1675,10 +1739,11 @@ export class SyncApi {
|
|
1675
1739
|
// push actions cache elsewhere so we can freeze MatrixEvents, or otherwise
|
1676
1740
|
// find some solution where MatrixEvents are immutable but allow for a cache
|
1677
1741
|
// field.
|
1678
|
-
|
1742
|
+
|
1743
|
+
for (const ev of eitherStateEventList) {
|
1679
1744
|
this.client.getPushActionsForEvent(ev);
|
1680
1745
|
}
|
1681
|
-
liveTimeline.initialiseState(
|
1746
|
+
liveTimeline.initialiseState(eitherStateEventList, {
|
1682
1747
|
timelineWasEmpty,
|
1683
1748
|
});
|
1684
1749
|
}
|
@@ -1710,17 +1775,18 @@ export class SyncApi {
|
|
1710
1775
|
// XXX: As above, don't do this...
|
1711
1776
|
//room.addLiveEvents(stateEventList || []);
|
1712
1777
|
// Do this instead...
|
1713
|
-
room.oldState.setStateEvents(
|
1714
|
-
room.currentState.setStateEvents(
|
1778
|
+
room.oldState.setStateEvents(eitherStateEventList);
|
1779
|
+
room.currentState.setStateEvents(eitherStateEventList);
|
1715
1780
|
}
|
1716
1781
|
|
1717
|
-
// Execute the timeline events.
|
1718
|
-
//
|
1782
|
+
// Execute the timeline events. If addToState is true the timeline has any state
|
1783
|
+
// events in it, this will continue to diverge the current state.
|
1719
1784
|
// This also needs to be done before running push rules on the events as they need
|
1720
1785
|
// to be decorated with sender etc.
|
1721
1786
|
await room.addLiveEvents(timelineEventList || [], {
|
1722
1787
|
fromCache,
|
1723
1788
|
timelineWasEmpty,
|
1789
|
+
addToState: stateAfterEventList === undefined,
|
1724
1790
|
});
|
1725
1791
|
this.client.processBeaconEvents(room, timelineEventList);
|
1726
1792
|
}
|