Update m.render_in to is_falling_back (+ unstable field) (#7979)
parent
2ab8b46ba3
commit
288e47fd81
|
@ -34,3 +34,10 @@ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];
|
||||||
|
|
||||||
export type Leaves<T, D extends number = 5> = [D] extends [never] ? never : T extends object ?
|
export type Leaves<T, D extends number = 5> = [D] extends [never] ? never : T extends object ?
|
||||||
{ [K in keyof T]-?: Join<K, Leaves<T[K], Prev[D]>> }[keyof T] : "";
|
{ [K in keyof T]-?: Join<K, Leaves<T[K], Prev[D]>> }[keyof T] : "";
|
||||||
|
|
||||||
|
export type RecursivePartial<T> = {
|
||||||
|
[P in keyof T]?:
|
||||||
|
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
|
||||||
|
T[P] extends object ? RecursivePartial<T[P]> :
|
||||||
|
T[P];
|
||||||
|
};
|
||||||
|
|
|
@ -1403,11 +1403,8 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
|
||||||
msgOption = readAvatars;
|
msgOption = readAvatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderTarget = this.context.timelineRenderingType === TimelineRenderingType.Thread
|
const inThread = this.context.timelineRenderingType === TimelineRenderingType.Thread;
|
||||||
? RelationType.Thread
|
const replyChain = haveTileForEvent(this.props.mxEvent) && shouldDisplayReply(this.props.mxEvent, inThread)
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const replyChain = haveTileForEvent(this.props.mxEvent) && shouldDisplayReply(this.props.mxEvent, renderTarget)
|
|
||||||
? <ReplyChain
|
? <ReplyChain
|
||||||
parentEv={this.props.mxEvent}
|
parentEv={this.props.mxEvent}
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
|
|
|
@ -57,12 +57,12 @@ import { ComposerType } from "../../../dispatcher/payloads/ComposerInsertPayload
|
||||||
import { getSlashCommand, isSlashCommand, runSlashCommand, shouldSendAnyway } from "../../../editor/commands";
|
import { getSlashCommand, isSlashCommand, runSlashCommand, shouldSendAnyway } from "../../../editor/commands";
|
||||||
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
||||||
import { PosthogAnalytics } from "../../../PosthogAnalytics";
|
import { PosthogAnalytics } from "../../../PosthogAnalytics";
|
||||||
import { getNestedReplyText, getRenderInMixin, makeReplyMixIn } from '../../../utils/Reply';
|
import { getNestedReplyText, makeReplyMixIn } from '../../../utils/Reply';
|
||||||
|
|
||||||
interface IAddReplyOpts {
|
interface IAddReplyOpts {
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
permalinkCreator?: RoomPermalinkCreator;
|
||||||
includeLegacyFallback?: boolean;
|
includeLegacyFallback?: boolean;
|
||||||
renderIn?: string[];
|
inThread?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addReplyToMessageContent(
|
function addReplyToMessageContent(
|
||||||
|
@ -72,7 +72,7 @@ function addReplyToMessageContent(
|
||||||
includeLegacyFallback: true,
|
includeLegacyFallback: true,
|
||||||
},
|
},
|
||||||
): void {
|
): void {
|
||||||
const replyContent = makeReplyMixIn(replyToEvent, opts.renderIn);
|
const replyContent = makeReplyMixIn(replyToEvent, opts.inThread);
|
||||||
Object.assign(content, replyContent);
|
Object.assign(content, replyContent);
|
||||||
|
|
||||||
if (opts.includeLegacyFallback) {
|
if (opts.includeLegacyFallback) {
|
||||||
|
@ -131,8 +131,8 @@ export function createMessageContent(
|
||||||
if (replyToEvent) {
|
if (replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent, {
|
||||||
permalinkCreator,
|
permalinkCreator,
|
||||||
includeLegacyFallback: true,
|
includeLegacyFallback: includeReplyLegacyFallback,
|
||||||
renderIn: getRenderInMixin(relation),
|
inThread: relation?.rel_type === RelationType.Thread,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent, {
|
||||||
permalinkCreator: this.props.permalinkCreator,
|
permalinkCreator: this.props.permalinkCreator,
|
||||||
includeLegacyFallback: true,
|
includeLegacyFallback: true,
|
||||||
renderIn: getRenderInMixin(this.props.relation),
|
inThread: this.props.relation?.rel_type === RelationType.Thread,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { IEventRelation, MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { IContent, MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { RelationType } from "matrix-js-sdk/src/@types/event";
|
import { RelationType } from "matrix-js-sdk/src/@types/event";
|
||||||
import sanitizeHtml from "sanitize-html";
|
import sanitizeHtml from "sanitize-html";
|
||||||
import escapeHtml from "escape-html";
|
import escapeHtml from "escape-html";
|
||||||
|
|
||||||
import { PERMITTED_URL_SCHEMES } from "../HtmlUtils";
|
import { PERMITTED_URL_SCHEMES } from "../HtmlUtils";
|
||||||
import { makeUserPermalink, RoomPermalinkCreator } from "./permalinks/Permalinks";
|
import { makeUserPermalink, RoomPermalinkCreator } from "./permalinks/Permalinks";
|
||||||
|
import { RecursivePartial } from "../@types/common";
|
||||||
|
|
||||||
export function getParentEventId(ev: MatrixEvent): string | undefined {
|
export function getParentEventId(ev: MatrixEvent): string | undefined {
|
||||||
if (!ev || ev.isRedacted()) return;
|
if (!ev || ev.isRedacted()) return;
|
||||||
|
@ -141,21 +142,18 @@ export function getNestedReplyText(
|
||||||
return { body, html };
|
return { body, html };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeReplyMixIn(ev: MatrixEvent, renderIn?: string[]) {
|
export function makeReplyMixIn(ev?: MatrixEvent, inThread = false): RecursivePartial<IContent> {
|
||||||
if (!ev) return {};
|
if (!ev) return {};
|
||||||
|
|
||||||
const mixin: any = {
|
const mixin: RecursivePartial<IContent> = {
|
||||||
'm.relates_to': {
|
'm.relates_to': {
|
||||||
'm.in_reply_to': {
|
'm.in_reply_to': {
|
||||||
'event_id': ev.getId(),
|
'event_id': ev.getId(),
|
||||||
|
'io.element.is_falling_back': !inThread, // MSC3440 unstable `is_falling_back` field
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (renderIn) {
|
|
||||||
mixin['m.relates_to']['m.in_reply_to']['m.render_in'] = renderIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the event replied is part of a thread
|
* If the event replied is part of a thread
|
||||||
* Add the `m.thread` relation so that clients
|
* Add the `m.thread` relation so that clients
|
||||||
|
@ -173,19 +171,12 @@ export function makeReplyMixIn(ev: MatrixEvent, renderIn?: string[]) {
|
||||||
return mixin;
|
return mixin;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldDisplayReply(event: MatrixEvent, renderTarget?: string): boolean {
|
export function shouldDisplayReply(event: MatrixEvent, inThread = false): boolean {
|
||||||
const parentExist = Boolean(getParentEventId(event));
|
const parentExist = Boolean(getParentEventId(event));
|
||||||
|
if (!parentExist) return false;
|
||||||
|
if (!inThread) return true;
|
||||||
|
|
||||||
const relations = event.getRelation();
|
const inReplyTo = event.getRelation()?.["m.in_reply_to"];
|
||||||
const renderIn = relations?.["m.in_reply_to"]?.["m.render_in"] ?? [];
|
const isFallingBack = inReplyTo?.is_falling_back ?? inReplyTo?.["io.element.is_falling_back"];
|
||||||
|
return !isFallingBack;
|
||||||
const shouldRenderInTarget = !renderTarget || (renderIn.includes(renderTarget));
|
|
||||||
|
|
||||||
return parentExist && shouldRenderInTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getRenderInMixin(relation?: IEventRelation): string[] | undefined {
|
|
||||||
if (relation?.rel_type === RelationType.Thread) {
|
|
||||||
return [RelationType.Thread];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue