Fix race conditions around threads (#8448)
This commit is contained in:
parent
1aaaad2f32
commit
f29ef04751
8 changed files with 37 additions and 67 deletions
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React, { createRef, KeyboardEvent } from 'react';
|
||||
import { Thread, ThreadEvent, THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread';
|
||||
import { Thread, THREAD_RELATION_TYPE, ThreadEvent } from 'matrix-js-sdk/src/models/thread';
|
||||
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||
import { IEventRelation, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||
import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
|
||||
|
@ -66,7 +66,6 @@ interface IProps {
|
|||
|
||||
interface IState {
|
||||
thread?: Thread;
|
||||
lastThreadReply?: MatrixEvent;
|
||||
layout: Layout;
|
||||
editState?: EditorStateTransfer;
|
||||
replyToEvent?: MatrixEvent;
|
||||
|
@ -104,7 +103,6 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
this.teardownThread();
|
||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||
const roomId = this.props.mxEvent.getRoomId();
|
||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
||||
|
@ -123,7 +121,6 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
|
||||
public componentDidUpdate(prevProps) {
|
||||
if (prevProps.mxEvent !== this.props.mxEvent) {
|
||||
this.teardownThread();
|
||||
this.setupThread(this.props.mxEvent);
|
||||
}
|
||||
|
||||
|
@ -134,7 +131,6 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
|
||||
private onAction = (payload: ActionPayload): void => {
|
||||
if (payload.phase == RightPanelPhases.ThreadView && payload.event) {
|
||||
this.teardownThread();
|
||||
this.setupThread(payload.event);
|
||||
}
|
||||
switch (payload.action) {
|
||||
|
@ -164,23 +160,15 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private setupThread = (mxEv: MatrixEvent) => {
|
||||
let thread = this.props.room.threads?.get(mxEv.getId());
|
||||
let thread = this.props.room.getThread(mxEv.getId());
|
||||
if (!thread) {
|
||||
thread = this.props.room.createThread(mxEv, [mxEv], true);
|
||||
thread = this.props.room.createThread(mxEv.getId(), mxEv, [mxEv], true);
|
||||
}
|
||||
thread.on(ThreadEvent.Update, this.updateLastThreadReply);
|
||||
this.updateThread(thread);
|
||||
};
|
||||
|
||||
private teardownThread = () => {
|
||||
if (this.state.thread) {
|
||||
this.state.thread.removeListener(ThreadEvent.Update, this.updateLastThreadReply);
|
||||
}
|
||||
};
|
||||
|
||||
private onNewThread = (thread: Thread) => {
|
||||
if (thread.id === this.props.mxEvent.getId()) {
|
||||
this.teardownThread();
|
||||
this.setupThread(this.props.mxEvent);
|
||||
}
|
||||
};
|
||||
|
@ -189,33 +177,15 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
if (thread && this.state.thread !== thread) {
|
||||
this.setState({
|
||||
thread,
|
||||
lastThreadReply: thread.lastReply((ev: MatrixEvent) => {
|
||||
return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status;
|
||||
}),
|
||||
}, async () => {
|
||||
thread.emit(ThreadEvent.ViewThread);
|
||||
if (!thread.initialEventsFetched) {
|
||||
const response = await thread.fetchInitialEvents();
|
||||
if (response?.nextBatch) {
|
||||
this.nextBatch = response.nextBatch;
|
||||
}
|
||||
}
|
||||
|
||||
await thread.fetchInitialEvents();
|
||||
this.nextBatch = thread.liveTimeline.getPaginationToken(Direction.Backward);
|
||||
this.timelinePanel.current?.refreshTimeline();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private updateLastThreadReply = () => {
|
||||
if (this.state.thread) {
|
||||
this.setState({
|
||||
lastThreadReply: this.state.thread.lastReply((ev: MatrixEvent) => {
|
||||
return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status;
|
||||
}),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private resetJumpToEvent = (event?: string): void => {
|
||||
if (this.props.initialEvent && this.props.initialEventScrollIntoView &&
|
||||
event === this.props.initialEvent?.getId()) {
|
||||
|
@ -298,12 +268,16 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private get threadRelation(): IEventRelation {
|
||||
const lastThreadReply = this.state.thread?.lastReply((ev: MatrixEvent) => {
|
||||
return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status;
|
||||
});
|
||||
|
||||
return {
|
||||
"rel_type": THREAD_RELATION_TYPE.name,
|
||||
"event_id": this.state.thread?.id,
|
||||
"is_falling_back": true,
|
||||
"m.in_reply_to": {
|
||||
"event_id": this.state.lastThreadReply?.getId() ?? this.state.thread?.id,
|
||||
"event_id": lastThreadReply?.getId() ?? this.state.thread?.id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -356,6 +330,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
|||
{ this.state.thread && <div className="mx_ThreadView_timelinePanelWrapper">
|
||||
<FileDropTarget parent={this.card.current} onFileDrop={this.onFileDrop} />
|
||||
<TimelinePanel
|
||||
key={this.state?.thread?.id}
|
||||
ref={this.timelinePanel}
|
||||
showReadReceipts={false} // Hide the read receipts
|
||||
// until homeservers speak threads language
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue