Use Room.findPredecessor when rendering RoomCreate tiles (#10012)

* Use Room.findPredecessor to render RoomCreate tiles

* Handle state updates

* Handle missing predecessor

* Check for missing a room
This commit is contained in:
Andy Balaam 2023-02-01 15:44:46 +00:00 committed by GitHub
parent 371a3c0d36
commit 33b89a5709
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 18 deletions

View file

@ -1,6 +1,6 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019, 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -15,7 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useCallback } from "react";
import React, { useCallback, useContext } from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import dis from "../../../dispatcher/dispatcher";
@ -25,6 +26,8 @@ import { _t } from "../../../languageHandler";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import EventTileBubble from "./EventTileBubble";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import RoomContext from "../../../contexts/RoomContext";
import { useRoomState } from "../../../hooks/useRoomState";
interface IProps {
/** The m.room.create MatrixEvent that this tile represents */
@ -37,31 +40,57 @@ interface IProps {
* room.
*/
export const RoomCreate: React.FC<IProps> = ({ mxEvent, timestamp }) => {
// Note: we ask the room for its predecessor here, instead of directly using
// the information inside mxEvent. This allows us the flexibility later to
// use a different predecessor (e.g. through MSC3946) and still display it
// in the timeline location of the create event.
const roomContext = useContext(RoomContext);
const predecessor = useRoomState(
roomContext.room,
useCallback((state) => state.findPredecessor(), []),
);
const onLinkClicked = useCallback(
(e: React.MouseEvent): void => {
e.preventDefault();
const predecessor = mxEvent.getContent()["predecessor"];
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
event_id: predecessor["event_id"],
event_id: predecessor.eventId,
highlighted: true,
room_id: predecessor["room_id"],
room_id: predecessor.roomId,
metricsTrigger: "Predecessor",
metricsViaKeyboard: e.type !== "click",
});
},
[mxEvent],
[predecessor?.eventId, predecessor?.roomId],
);
const predecessor = mxEvent.getContent()["predecessor"];
if (predecessor === undefined) {
return <div />; // We should never have been instantiated in this case
if (!roomContext.room || roomContext.room.roomId !== mxEvent.getRoomId()) {
logger.warn(
"RoomCreate unexpectedly used outside of the context of the room containing this m.room.create event.",
);
return <></>;
}
const prevRoom = MatrixClientPeg.get().getRoom(predecessor["room_id"]);
const permalinkCreator = new RoomPermalinkCreator(prevRoom, predecessor["room_id"]);
if (!predecessor) {
logger.warn("RoomCreate unexpectedly used in a room with no predecessor.");
return <div />;
}
const prevRoom = MatrixClientPeg.get().getRoom(predecessor.roomId);
if (!prevRoom) {
logger.warn(`Failed to find predecessor room with id ${predecessor.roomId}`);
return <></>;
}
const permalinkCreator = new RoomPermalinkCreator(prevRoom, predecessor.roomId);
permalinkCreator.load();
const predecessorPermalink = permalinkCreator.forEvent(predecessor["event_id"]);
let predecessorPermalink: string;
if (predecessor.eventId) {
predecessorPermalink = permalinkCreator.forEvent(predecessor.eventId);
} else {
predecessorPermalink = permalinkCreator.forRoom();
}
const link = (
<a href={predecessorPermalink} onClick={onLinkClicked}>
{_t("Click here to see older messages.")}