Use updates stable relations from js-sdk (#8715)
* Use updates stable relations from js-sdk * Relations is now accessible on the Room instead * Reuse more existing code and ditch confusing `isThreadRelation` * Fix last usage of removed `isThreadRelation` * Update tests to match removal of isThreadRelation * Tweak method naming to closer match spec * Fix missing method name change
This commit is contained in:
parent
56b0b79fb7
commit
21d0aaf524
8 changed files with 26 additions and 54 deletions
|
@ -285,7 +285,6 @@ class MatrixClientPegClass implements IMatrixClientPeg {
|
||||||
SHOW_QR_CODE_METHOD,
|
SHOW_QR_CODE_METHOD,
|
||||||
verificationMethods.RECIPROCATE_QR_CODE,
|
verificationMethods.RECIPROCATE_QR_CODE,
|
||||||
],
|
],
|
||||||
unstableClientRelationAggregation: true,
|
|
||||||
identityServer: new IdentityAuthClient(),
|
identityServer: new IdentityAuthClient(),
|
||||||
cryptoCallbacks: {},
|
cryptoCallbacks: {},
|
||||||
};
|
};
|
||||||
|
|
|
@ -469,12 +469,9 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
// TODO: Implement granular (per-room) hide options
|
// TODO: Implement granular (per-room) hide options
|
||||||
public shouldShowEvent(mxEv: MatrixEvent, forceHideEvents = false): boolean {
|
public shouldShowEvent(mxEv: MatrixEvent, forceHideEvents = false): boolean {
|
||||||
if (this.props.hideThreadedMessages && this.threadsEnabled) {
|
if (this.props.hideThreadedMessages && this.threadsEnabled && this.props.room) {
|
||||||
if (mxEv.isThreadRelation) {
|
const { shouldLiveInRoom } = this.props.room.eventShouldLiveIn(mxEv, this.props.events);
|
||||||
return false;
|
if (!shouldLiveInRoom) {
|
||||||
}
|
|
||||||
|
|
||||||
if (this.shouldLiveInThreadOnly(mxEv)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,24 +494,6 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
||||||
return !shouldHideEvent(mxEv, this.context);
|
return !shouldHideEvent(mxEv, this.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private shouldLiveInThreadOnly(event: MatrixEvent): boolean {
|
|
||||||
const associatedId = event.getAssociatedId();
|
|
||||||
|
|
||||||
const targetsThreadRoot = event.threadRootId === associatedId;
|
|
||||||
if (event.isThreadRoot || targetsThreadRoot || !event.isThreadRelation) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a reply, then we use the associated event to decide whether
|
|
||||||
// this should be thread only or not
|
|
||||||
const parentEvent = this.props.room.findEventById(associatedId);
|
|
||||||
if (parentEvent) {
|
|
||||||
return this.shouldLiveInThreadOnly(parentEvent);
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public readMarkerForEvent(eventId: string, isLastEvent: boolean): ReactNode {
|
public readMarkerForEvent(eventId: string, isLastEvent: boolean): ReactNode {
|
||||||
const visible = !isLastEvent && this.props.readMarkerVisible;
|
const visible = !isLastEvent && this.props.readMarkerVisible;
|
||||||
|
|
||||||
|
|
|
@ -974,9 +974,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
|
|
||||||
CHAT_EFFECTS.forEach(effect => {
|
CHAT_EFFECTS.forEach(effect => {
|
||||||
if (containsEmoji(ev.getContent(), effect.emojis) || ev.getContent().msgtype === effect.msgType) {
|
if (containsEmoji(ev.getContent(), effect.emojis) || ev.getContent().msgtype === effect.msgType) {
|
||||||
// For initial threads launch, chat effects are disabled
|
// For initial threads launch, chat effects are disabled see #19731
|
||||||
// see #19731
|
if (!SettingsStore.getValue("feature_thread") || !ev.isRelation(THREAD_RELATION_TYPE.name)) {
|
||||||
if (!SettingsStore.getValue("feature_thread") || !ev.isThreadRelation) {
|
|
||||||
dis.dispatch({ action: `effects.${effect.command}` });
|
dis.dispatch({ action: `effects.${effect.command}` });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1425,28 +1425,19 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
// if we're at the end of the live timeline, append the pending events
|
// if we're at the end of the live timeline, append the pending events
|
||||||
if (!this.timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
if (!this.timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
||||||
const pendingEvents = this.props.timelineSet.getPendingEvents();
|
const pendingEvents = this.props.timelineSet.getPendingEvents();
|
||||||
|
events.push(...pendingEvents.filter(event => {
|
||||||
|
const {
|
||||||
|
shouldLiveInRoom,
|
||||||
|
threadId,
|
||||||
|
} = this.props.timelineSet.room.eventShouldLiveIn(event, pendingEvents);
|
||||||
|
|
||||||
if (this.context.timelineRenderingType === TimelineRenderingType.Thread) {
|
if (this.context.timelineRenderingType === TimelineRenderingType.Thread) {
|
||||||
events.push(...pendingEvents.filter(e => e.threadRootId === this.context.threadId));
|
return threadId === this.context.threadId;
|
||||||
} else {
|
} {
|
||||||
events.push(...pendingEvents.filter(e => {
|
return shouldLiveInRoom;
|
||||||
const hasNoRelation = !e.getRelation();
|
|
||||||
if (hasNoRelation) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.isThreadRelation) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parentEvent = this.props.timelineSet.findEventById(e.getAssociatedId());
|
|
||||||
if (!parentEvent) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return !parentEvent.isThreadRelation;
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
events,
|
events,
|
||||||
|
@ -1678,7 +1669,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
eventId: string,
|
eventId: string,
|
||||||
relationType: RelationType,
|
relationType: RelationType,
|
||||||
eventType: EventType | string,
|
eventType: EventType | string,
|
||||||
) => this.props.timelineSet.getRelationsForEvent(eventId, relationType, eventType);
|
) => this.props.timelineSet.relations?.getChildEventsForEvent(eventId, relationType, eventType);
|
||||||
|
|
||||||
private buildCallEventGroupers(events?: MatrixEvent[]): void {
|
private buildCallEventGroupers(events?: MatrixEvent[]): void {
|
||||||
this.callEventGroupers = buildCallEventGroupers(this.callEventGroupers, events);
|
this.callEventGroupers = buildCallEventGroupers(this.callEventGroupers, events);
|
||||||
|
|
|
@ -189,7 +189,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => {
|
||||||
action: Action.ViewUserSettings,
|
action: Action.ViewUserSettings,
|
||||||
initialTabId: UserTab.Labs,
|
initialTabId: UserTab.Labs,
|
||||||
});
|
});
|
||||||
} else if (mxEvent.isThreadRelation) {
|
} else if (mxEvent.getThread() && !mxEvent.isThreadRoot) {
|
||||||
showThread({
|
showThread({
|
||||||
rootEvent: mxEvent.getThread().rootEvent,
|
rootEvent: mxEvent.getThread().rootEvent,
|
||||||
initialEvent: mxEvent,
|
initialEvent: mxEvent,
|
||||||
|
|
|
@ -285,8 +285,8 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
||||||
let shouldReact = true;
|
let shouldReact = true;
|
||||||
const lastMessage = events[i];
|
const lastMessage = events[i];
|
||||||
const userId = MatrixClientPeg.get().getUserId();
|
const userId = MatrixClientPeg.get().getUserId();
|
||||||
const messageReactions = this.props.room.getUnfilteredTimelineSet()
|
const messageReactions = this.props.room.relations
|
||||||
.getRelationsForEvent(lastMessage.getId(), RelationType.Annotation, EventType.Reaction);
|
.getChildEventsForEvent(lastMessage.getId(), RelationType.Annotation, EventType.Reaction);
|
||||||
|
|
||||||
// if we have already sent this reaction, don't redact but don't re-send
|
// if we have already sent this reaction, don't redact but don't re-send
|
||||||
if (messageReactions) {
|
if (messageReactions) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { logger } from 'matrix-js-sdk/src/logger';
|
||||||
import { M_POLL_START } from "matrix-events-sdk";
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
|
import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
|
||||||
import { M_BEACON_INFO } from 'matrix-js-sdk/src/@types/beacon';
|
import { M_BEACON_INFO } from 'matrix-js-sdk/src/@types/beacon';
|
||||||
|
import { THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread';
|
||||||
|
|
||||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||||
import shouldHideEvent from "../shouldHideEvent";
|
import shouldHideEvent from "../shouldHideEvent";
|
||||||
|
@ -231,7 +232,10 @@ export async function fetchInitialEvent(
|
||||||
initialEvent = null;
|
initialEvent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialEvent?.isThreadRelation && client.supportsExperimentalThreads() && !initialEvent.getThread()) {
|
if (client.supportsExperimentalThreads() &&
|
||||||
|
initialEvent?.isRelation(THREAD_RELATION_TYPE.name) &&
|
||||||
|
!initialEvent.getThread()
|
||||||
|
) {
|
||||||
const threadId = initialEvent.threadRootId;
|
const threadId = initialEvent.threadRootId;
|
||||||
const room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -443,7 +443,7 @@ describe('<MessageActionBar />', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// mock the thread stuff
|
// mock the thread stuff
|
||||||
jest.spyOn(threadReplyEvent, 'isThreadRelation', 'get').mockReturnValue(true);
|
jest.spyOn(threadReplyEvent, 'isThreadRoot', 'get').mockReturnValue(false);
|
||||||
// set alicesMessageEvent as the root event
|
// set alicesMessageEvent as the root event
|
||||||
jest.spyOn(threadReplyEvent, 'getThread').mockReturnValue(
|
jest.spyOn(threadReplyEvent, 'getThread').mockReturnValue(
|
||||||
{ rootEvent: alicesMessageEvent } as unknown as Thread,
|
{ rootEvent: alicesMessageEvent } as unknown as Thread,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue