-
-
Notifications
You must be signed in to change notification settings - Fork 619
Draft: Refresh room timeline when we see a MSC2716 marker event #2282
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
Changes from 6 commits
2b029c9
ffbcbff
39cd6e9
e5f34db
e070b3c
21f6aa2
9bfcf4b
1c2b955
05b9800
8b82bb5
35f3f04
b2636c3
da57a74
c539b64
11040e5
07fcf27
701bf34
c080c6c
0694b84
26fb2b6
8ca2645
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,38 @@ export interface IRoomTimelineData { | |
liveEvent?: boolean; | ||
} | ||
|
||
export interface IAddLiveEventOptions { | ||
/** Applies to events in the timeline only. If this is 'replace' then if a | ||
* duplicate is encountered, the event passed to this function will replace | ||
* the existing event in the timeline. If this is not specified, or is | ||
* 'ignore', then the event passed to this function will be ignored | ||
* entirely, preserving the existing event in the timeline. Events are | ||
* identical based on their event ID <b>only</b>. */ | ||
duplicateStrategy?: DuplicateStrategy; | ||
/** Whether the sync response came from cache */ | ||
fromCache?: boolean; | ||
/** The state events to reconcile metadata from */ | ||
roomState?: RoomState; | ||
/** Whether the state is part of the first state snapshot we're seeing in | ||
* the room. This could be happen in a variety of cases: | ||
* 1. From the initial sync | ||
* 2. It's the first state we're seeing after joining the room | ||
* 3. Or whether it's coming from `syncFromCache` */ | ||
fromInitialState?: boolean; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of dealing with unwieldy long function signatures with unlabeled and optional arguments in the usage, I've refactored some of these into option objects now that I am adding yet another Before: room.addLiveEvents(mainTimelineEvents, null, fromCache, timelineWasEmpty); After: room.addLiveEvents(mainTimelineEvents, {
fromCache,
fromInitialState: timelineWasEmpty
}); If necessary, this refactor can be split out to another PR with some effort. |
||
|
||
export interface IAddEventToTimelineOptions { | ||
toStartOfTimeline: boolean; | ||
fromCache?: boolean; | ||
roomState?: RoomState; | ||
/** Whether the state is part of the first state snapshot we're seeing in | ||
* the room. This could be happen in a variety of cases: | ||
* 1. From the initial sync | ||
* 2. It's the first state we're seeing after joining the room | ||
* 3. Or whether it's coming from `syncFromCache` */ | ||
fromInitialState?: boolean; | ||
} | ||
|
||
type EmittedEvents = RoomEvent.Timeline | RoomEvent.TimelineReset; | ||
|
||
export type EventTimelineSetHandlerMap = { | ||
|
@@ -431,7 +463,9 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime | |
|
||
if (!existingTimeline) { | ||
// we don't know about this event yet. Just add it to the timeline. | ||
this.addEventToTimeline(event, timeline, toStartOfTimeline); | ||
this.addEventToTimeline(event, timeline, { | ||
toStartOfTimeline | ||
}); | ||
lastEventWasNew = true; | ||
didUpdate = true; | ||
continue; | ||
|
@@ -523,15 +557,16 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime | |
* Add an event to the end of this live timeline. | ||
* | ||
* @param {MatrixEvent} event Event to be added | ||
* @param {string?} duplicateStrategy 'ignore' or 'replace' | ||
* @param {boolean} fromCache whether the sync response came from cache | ||
* @param roomState the state events to reconcile metadata from | ||
* @param {IAddLiveEventOptions} options addLiveEvent options | ||
*/ | ||
public addLiveEvent( | ||
event: MatrixEvent, | ||
duplicateStrategy: DuplicateStrategy = DuplicateStrategy.Ignore, | ||
fromCache = false, | ||
roomState?: RoomState, | ||
{ | ||
duplicateStrategy = DuplicateStrategy.Ignore, | ||
fromCache = false, | ||
roomState, | ||
fromInitialState | ||
}: IAddLiveEventOptions = {} | ||
): void { | ||
if (this.filter) { | ||
const events = this.filter.filterRoomTimeline([event]); | ||
|
@@ -570,7 +605,12 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime | |
return; | ||
} | ||
|
||
this.addEventToTimeline(event, this.liveTimeline, false, fromCache, roomState); | ||
this.addEventToTimeline(event, this.liveTimeline, { | ||
toStartOfTimeline: false, | ||
fromCache, | ||
roomState, | ||
fromInitialState, | ||
}); | ||
} | ||
|
||
/** | ||
|
@@ -581,20 +621,26 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime | |
* | ||
* @param {MatrixEvent} event | ||
* @param {EventTimeline} timeline | ||
* @param {boolean} toStartOfTimeline | ||
* @param {boolean} fromCache whether the sync response came from cache | ||
* @param {IAddEventToTimelineOptions} options addEventToTimeline options | ||
* | ||
* @fires module:client~MatrixClient#event:"Room.timeline" | ||
*/ | ||
public addEventToTimeline( | ||
event: MatrixEvent, | ||
timeline: EventTimeline, | ||
toStartOfTimeline: boolean, | ||
fromCache = false, | ||
roomState?: RoomState, | ||
{ | ||
toStartOfTimeline, | ||
fromCache = false, | ||
roomState, | ||
fromInitialState = false | ||
}: IAddEventToTimelineOptions, | ||
) { | ||
const eventId = event.getId(); | ||
timeline.addEvent(event, toStartOfTimeline, roomState); | ||
timeline.addEvent(event, { | ||
atStart: toStartOfTimeline, | ||
stateContext: roomState, | ||
fromInitialState, | ||
}); | ||
this._eventIdToTimeline[eventId] = timeline; | ||
|
||
this.setRelationsTarget(event); | ||
|
@@ -630,10 +676,14 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime | |
} else { | ||
if (this.filter) { | ||
if (this.filter.filterRoomTimeline([localEvent]).length) { | ||
this.addEventToTimeline(localEvent, this.liveTimeline, false); | ||
this.addEventToTimeline(localEvent, this.liveTimeline, { | ||
toStartOfTimeline: false | ||
}); | ||
} | ||
} else { | ||
this.addEventToTimeline(localEvent, this.liveTimeline, false); | ||
this.addEventToTimeline(localEvent, this.liveTimeline, { | ||
toStartOfTimeline: false | ||
}); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,12 +36,22 @@ enum OobStatus { | |
Finished, | ||
} | ||
|
||
export interface ISetStateOptions { | ||
/** Whether the state is part of the first state snapshot we're seeing in | ||
* the room. This could be happen in a variety of cases: | ||
* 1. From the initial sync | ||
* 2. It's the first state we're seeing after joining the room | ||
* 3. Or whether it's coming from `syncFromCache` */ | ||
fromInitialState?: boolean; | ||
} | ||
|
||
export enum RoomStateEvent { | ||
Events = "RoomState.events", | ||
Members = "RoomState.members", | ||
NewMember = "RoomState.newMember", | ||
Update = "RoomState.update", // signals batches of updates without specificity | ||
BeaconLiveness = "RoomState.BeaconLiveness", | ||
Marker = "RoomState.org.matrix.msc2716.marker", | ||
} | ||
|
||
export type RoomStateEventHandlerMap = { | ||
|
@@ -51,6 +61,7 @@ export type RoomStateEventHandlerMap = { | |
[RoomStateEvent.Update]: (state: RoomState) => void; | ||
[RoomStateEvent.BeaconLiveness]: (state: RoomState, hasLiveBeacons: boolean) => void; | ||
[BeaconEvent.New]: (event: MatrixEvent, beacon: Beacon) => void; | ||
[RoomStateEvent.Marker]: (event: MatrixEvent, setStateOptions: ISetStateOptions) => void; | ||
}; | ||
|
||
type EmittedEvents = RoomStateEvent | BeaconEvent; | ||
|
@@ -309,16 +320,18 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap> | |
} | ||
|
||
/** | ||
* Add an array of one or more state MatrixEvents, overwriting | ||
* any existing state with the same {type, stateKey} tuple. Will fire | ||
* "RoomState.events" for every event added. May fire "RoomState.members" | ||
* if there are <code>m.room.member</code> events. | ||
* Add an array of one or more state MatrixEvents, overwriting any existing | ||
* state with the same {type, stateKey} tuple. Will fire "RoomState.events" | ||
* for every event added. May fire "RoomState.members" if there are | ||
* <code>m.room.member</code> events. | ||
* @param {MatrixEvent[]} stateEvents a list of state events for this room. | ||
* @param {boolean} fromInitialState whether the stateEvents are from the first | ||
* sync in the room or a sync we already know about (syncFromCache) | ||
* @fires module:client~MatrixClient#event:"RoomState.members" | ||
* @fires module:client~MatrixClient#event:"RoomState.newMember" | ||
* @fires module:client~MatrixClient#event:"RoomState.events" | ||
*/ | ||
public setStateEvents(stateEvents: MatrixEvent[]) { | ||
public setStateEvents(stateEvents: MatrixEvent[], setStateOptions?: ISetStateOptions) { | ||
this.updateModifiedTime(); | ||
|
||
// update the core event dict | ||
|
@@ -398,6 +411,8 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap> | |
|
||
// assume all our sentinels are now out-of-date | ||
this.sentinels = {}; | ||
} else if (event.getType() === EventType.Marker) { | ||
this.emit(RoomStateEvent.Marker, event, setStateOptions); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we see a new marker state event, emit an event so we can listen for it in |
||
} | ||
}); | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.