Wrap all EventTiles with a TileErrorBoundary and guard parsePermalink (#7916)
Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
parent
08c47ac473
commit
16e67e7716
3 changed files with 49 additions and 40 deletions
|
@ -48,7 +48,6 @@ import DateSeparator from '../views/messages/DateSeparator';
|
||||||
import ErrorBoundary from '../views/elements/ErrorBoundary';
|
import ErrorBoundary from '../views/elements/ErrorBoundary';
|
||||||
import ResizeNotifier from "../../utils/ResizeNotifier";
|
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||||
import Spinner from "../views/elements/Spinner";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import TileErrorBoundary from '../views/messages/TileErrorBoundary';
|
|
||||||
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
||||||
import EditorStateTransfer from "../../utils/EditorStateTransfer";
|
import EditorStateTransfer from "../../utils/EditorStateTransfer";
|
||||||
import { Action } from '../../dispatcher/actions';
|
import { Action } from '../../dispatcher/actions';
|
||||||
|
@ -787,37 +786,36 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
||||||
const callEventGrouper = this.props.callEventGroupers.get(mxEv.getContent().call_id);
|
const callEventGrouper = this.props.callEventGroupers.get(mxEv.getContent().call_id);
|
||||||
// use txnId as key if available so that we don't remount during sending
|
// use txnId as key if available so that we don't remount during sending
|
||||||
ret.push(
|
ret.push(
|
||||||
<TileErrorBoundary key={mxEv.getTxnId() || eventId} mxEvent={mxEv} layout={this.props.layout}>
|
<EventTile
|
||||||
<EventTile
|
key={mxEv.getTxnId() || eventId}
|
||||||
as="li"
|
as="li"
|
||||||
ref={this.collectEventTile.bind(this, eventId)}
|
ref={this.collectEventTile.bind(this, eventId)}
|
||||||
alwaysShowTimestamps={this.props.alwaysShowTimestamps}
|
alwaysShowTimestamps={this.props.alwaysShowTimestamps}
|
||||||
mxEvent={mxEv}
|
mxEvent={mxEv}
|
||||||
continuation={continuation}
|
continuation={continuation}
|
||||||
isRedacted={mxEv.isRedacted()}
|
isRedacted={mxEv.isRedacted()}
|
||||||
replacingEventId={mxEv.replacingEventId()}
|
replacingEventId={mxEv.replacingEventId()}
|
||||||
editState={isEditing && this.props.editState}
|
editState={isEditing && this.props.editState}
|
||||||
onHeightChanged={this.onHeightChanged}
|
onHeightChanged={this.onHeightChanged}
|
||||||
readReceipts={readReceipts}
|
readReceipts={readReceipts}
|
||||||
readReceiptMap={this.readReceiptMap}
|
readReceiptMap={this.readReceiptMap}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
checkUnmounting={this.isUnmounting}
|
checkUnmounting={this.isUnmounting}
|
||||||
eventSendStatus={mxEv.getAssociatedStatus()}
|
eventSendStatus={mxEv.getAssociatedStatus()}
|
||||||
isTwelveHour={this.props.isTwelveHour}
|
isTwelveHour={this.props.isTwelveHour}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
permalinkCreator={this.props.permalinkCreator}
|
||||||
last={last}
|
last={last}
|
||||||
lastInSection={lastInSection}
|
lastInSection={lastInSection}
|
||||||
lastSuccessful={isLastSuccessful}
|
lastSuccessful={isLastSuccessful}
|
||||||
isSelectedEvent={highlight}
|
isSelectedEvent={highlight}
|
||||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||||
showReactions={this.props.showReactions}
|
showReactions={this.props.showReactions}
|
||||||
layout={this.props.layout}
|
layout={this.props.layout}
|
||||||
enableFlair={this.props.enableFlair}
|
enableFlair={this.props.enableFlair}
|
||||||
showReadReceipts={this.props.showReadReceipts}
|
showReadReceipts={this.props.showReadReceipts}
|
||||||
callEventGrouper={callEventGrouper}
|
callEventGrouper={callEventGrouper}
|
||||||
hideSender={this.state.hideSender}
|
hideSender={this.state.hideSender}
|
||||||
/>
|
/>,
|
||||||
</TileErrorBoundary>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -82,6 +82,7 @@ import RedactedBody from '../messages/RedactedBody';
|
||||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||||
import { shouldDisplayReply } from '../../../utils/Reply';
|
import { shouldDisplayReply } from '../../../utils/Reply';
|
||||||
import PosthogTrackers from "../../../PosthogTrackers";
|
import PosthogTrackers from "../../../PosthogTrackers";
|
||||||
|
import TileErrorBoundary from '../messages/TileErrorBoundary';
|
||||||
|
|
||||||
export type GetRelationsForEvent = (eventId: string, relationType: string, eventType: string) => Relations;
|
export type GetRelationsForEvent = (eventId: string, relationType: string, eventType: string) => Relations;
|
||||||
|
|
||||||
|
@ -1114,7 +1115,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
private renderEvent() {
|
||||||
const msgtype = this.props.mxEvent.getContent().msgtype;
|
const msgtype = this.props.mxEvent.getContent().msgtype;
|
||||||
const eventType = this.props.mxEvent.getType() as EventType;
|
const eventType = this.props.mxEvent.getType() as EventType;
|
||||||
const {
|
const {
|
||||||
|
@ -1641,6 +1642,12 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return <TileErrorBoundary mxEvent={this.props.mxEvent} layout={this.props.layout}>
|
||||||
|
{ this.renderEvent() }
|
||||||
|
</TileErrorBoundary>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX this'll eventually be dynamic based on the fields once we have extensible event types
|
// XXX this'll eventually be dynamic based on the fields once we have extensible event types
|
||||||
|
|
|
@ -422,13 +422,17 @@ function getPermalinkConstructor(): PermalinkConstructor {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parsePermalink(fullUrl: string): PermalinkParts {
|
export function parsePermalink(fullUrl: string): PermalinkParts {
|
||||||
const elementPrefix = SdkConfig.get()['permalinkPrefix'];
|
try {
|
||||||
if (decodeURIComponent(fullUrl).startsWith(matrixtoBaseUrl)) {
|
const elementPrefix = SdkConfig.get()['permalinkPrefix'];
|
||||||
return new MatrixToPermalinkConstructor().parsePermalink(decodeURIComponent(fullUrl));
|
if (decodeURIComponent(fullUrl).startsWith(matrixtoBaseUrl)) {
|
||||||
} else if (fullUrl.startsWith("matrix:")) {
|
return new MatrixToPermalinkConstructor().parsePermalink(decodeURIComponent(fullUrl));
|
||||||
return new MatrixSchemePermalinkConstructor().parsePermalink(fullUrl);
|
} else if (fullUrl.startsWith("matrix:")) {
|
||||||
} else if (elementPrefix && fullUrl.startsWith(elementPrefix)) {
|
return new MatrixSchemePermalinkConstructor().parsePermalink(fullUrl);
|
||||||
return new ElementPermalinkConstructor(elementPrefix).parsePermalink(fullUrl);
|
} else if (elementPrefix && fullUrl.startsWith(elementPrefix)) {
|
||||||
|
return new ElementPermalinkConstructor(elementPrefix).parsePermalink(fullUrl);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("Failed to parse permalink", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // not a permalink we can handle
|
return null; // not a permalink we can handle
|
||||||
|
|
Loading…
Reference in a new issue