Update URL when room aliases are modified (#7289)

This commit is contained in:
Michael Telatynski 2021-12-06 09:25:05 +00:00 committed by GitHub
parent c222c5511d
commit 336f159004
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 59 deletions

View file

@ -114,6 +114,7 @@ import GenericToast from "../views/toasts/GenericToast";
import InfoDialog from "../views/dialogs/InfoDialog"; import InfoDialog from "../views/dialogs/InfoDialog";
import FeedbackDialog from "../views/dialogs/FeedbackDialog"; import FeedbackDialog from "../views/dialogs/FeedbackDialog";
import AccessibleButton from "../views/elements/AccessibleButton"; import AccessibleButton from "../views/elements/AccessibleButton";
import { ActionPayload } from "../../dispatcher/payloads";
/** constants for MatrixChat.state.view */ /** constants for MatrixChat.state.view */
export enum Views { export enum Views {
@ -542,13 +543,11 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.setState(newState); this.setState(newState);
} }
onAction = (payload) => { private onAction = (payload: ActionPayload) => {
// console.log(`MatrixClientPeg.onAction: ${payload.action}`); // console.log(`MatrixClientPeg.onAction: ${payload.action}`);
// Start the onboarding process for certain actions // Start the onboarding process for certain actions
if (MatrixClientPeg.get() && MatrixClientPeg.get().isGuest() && if (MatrixClientPeg.get()?.isGuest() && ONBOARDING_FLOW_STARTERS.includes(payload.action)) {
ONBOARDING_FLOW_STARTERS.includes(payload.action)
) {
// This will cause `payload` to be dispatched later, once a // This will cause `payload` to be dispatched later, once a
// sync has reached the "prepared" state. Setting a matrix ID // sync has reached the "prepared" state. Setting a matrix ID
// will cause a full login and sync and finally the deferred // will cause a full login and sync and finally the deferred
@ -590,7 +589,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
Lifecycle.logout(); Lifecycle.logout();
break; break;
case 'require_registration': case 'require_registration':
startAnyRegistrationFlow(payload); startAnyRegistrationFlow(payload as any);
break; break;
case 'start_registration': case 'start_registration':
if (Lifecycle.isSoftLogout()) { if (Lifecycle.isSoftLogout()) {
@ -666,7 +665,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
// known to be in (eg. user clicks on a room in the recents panel), supply the ID // known to be in (eg. user clicks on a room in the recents panel), supply the ID
// If the user is clicking on a room in the context of the alias being presented // If the user is clicking on a room in the context of the alias being presented
// to them, supply the room alias. If both are supplied, the room ID will be ignored. // to them, supply the room alias. If both are supplied, the room ID will be ignored.
const promise = this.viewRoom(payload); const promise = this.viewRoom(payload as any);
if (payload.deferred_action) { if (payload.deferred_action) {
promise.then(() => { promise.then(() => {
dis.dispatch(payload.deferred_action); dis.dispatch(payload.deferred_action);
@ -897,73 +896,73 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
// @param {Object=} roomInfo.oob_data Object of additional data about the room // @param {Object=} roomInfo.oob_data Object of additional data about the room
// that has been passed out-of-band (eg. // that has been passed out-of-band (eg.
// room name and avatar from an invite email) // room name and avatar from an invite email)
private viewRoom(roomInfo: IRoomInfo) { private async viewRoom(roomInfo: IRoomInfo) {
this.focusComposer = true; this.focusComposer = true;
if (roomInfo.room_alias) { if (roomInfo.room_alias) {
logger.log( logger.log(`Switching to room alias ${roomInfo.room_alias} at event ${roomInfo.event_id}`);
`Switching to room alias ${roomInfo.room_alias} at event ` +
roomInfo.event_id,
);
} else { } else {
logger.log(`Switching to room id ${roomInfo.room_id} at event ` + logger.log(`Switching to room id ${roomInfo.room_id} at event ${roomInfo.event_id}`);
roomInfo.event_id,
);
} }
// Wait for the first sync to complete so that if a room does have an alias, // Wait for the first sync to complete so that if a room does have an alias,
// it would have been retrieved. // it would have been retrieved.
let waitFor = Promise.resolve(null);
if (!this.firstSyncComplete) { if (!this.firstSyncComplete) {
if (!this.firstSyncPromise) { if (!this.firstSyncPromise) {
logger.warn('Cannot view a room before first sync. room_id:', roomInfo.room_id); logger.warn('Cannot view a room before first sync. room_id:', roomInfo.room_id);
return; return;
} }
waitFor = this.firstSyncPromise.promise; await this.firstSyncPromise.promise;
} }
return waitFor.then(() => { let presentedId = roomInfo.room_alias || roomInfo.room_id;
let presentedId = roomInfo.room_alias || roomInfo.room_id; const room = MatrixClientPeg.get().getRoom(roomInfo.room_id);
const room = MatrixClientPeg.get().getRoom(roomInfo.room_id); if (room) {
if (room) { // Not all timeline events are decrypted ahead of time anymore
// Not all timeline events are decrypted ahead of time anymore // Only the critical ones for a typical UI are
// Only the critical ones for a typical UI are // This will start the decryption process for all events when a
// This will start the decryption process for all events when a // user views a room
// user views a room room.decryptAllEvents();
room.decryptAllEvents(); const theAlias = Rooms.getDisplayAliasForRoom(room);
const theAlias = Rooms.getDisplayAliasForRoom(room); if (theAlias) {
if (theAlias) { presentedId = theAlias;
presentedId = theAlias; // Store display alias of the presented room in cache to speed future
// Store display alias of the presented room in cache to speed future // navigation.
// navigation. storeRoomAliasInCache(theAlias, room.roomId);
storeRoomAliasInCache(theAlias, room.roomId);
}
// Store this as the ID of the last room accessed. This is so that we can
// persist which room is being stored across refreshes and browser quits.
if (localStorage) {
localStorage.setItem('mx_last_room_id', room.roomId);
}
} }
// If we are redirecting to a Room Alias and it is for the room we already showing then replace history item // Store this as the ID of the last room accessed. This is so that we can
const replaceLast = presentedId[0] === "#" && roomInfo.room_id === this.state.currentRoomId; // persist which room is being stored across refreshes and browser quits.
if (localStorage) {
if (roomInfo.event_id && roomInfo.highlighted) { localStorage.setItem('mx_last_room_id', room.roomId);
presentedId += "/" + roomInfo.event_id;
} }
this.setState({ }
view: Views.LOGGED_IN,
currentRoomId: roomInfo.room_id || null, // If we are redirecting to a Room Alias and it is for the room we already showing then replace history item
page_type: PageType.RoomView, const replaceLast = presentedId[0] === "#" && roomInfo.room_id === this.state.currentRoomId;
threepidInvite: roomInfo.threepid_invite,
roomOobData: roomInfo.oob_data, if (roomInfo.room_id === this.state.currentRoomId) {
forceTimeline: roomInfo.forceTimeline, // if we are re-viewing the same room then copy any state we already know
ready: true, roomInfo.threepid_invite = roomInfo.threepid_invite ?? this.state.threepidInvite;
roomJustCreatedOpts: roomInfo.justCreatedOpts, roomInfo.oob_data = roomInfo.oob_data ?? this.state.roomOobData;
}, () => { roomInfo.forceTimeline = roomInfo.forceTimeline ?? this.state.forceTimeline;
this.notifyNewScreen('room/' + presentedId, replaceLast); roomInfo.justCreatedOpts = roomInfo.justCreatedOpts ?? this.state.roomJustCreatedOpts;
}); }
if (roomInfo.event_id && roomInfo.highlighted) {
presentedId += "/" + roomInfo.event_id;
}
this.setState({
view: Views.LOGGED_IN,
currentRoomId: roomInfo.room_id || null,
page_type: PageType.RoomView,
threepidInvite: roomInfo.threepid_invite,
roomOobData: roomInfo.oob_data,
forceTimeline: roomInfo.forceTimeline,
ready: true,
roomJustCreatedOpts: roomInfo.justCreatedOpts,
}, () => {
this.notifyNewScreen('room/' + presentedId, replaceLast);
}); });
} }

View file

@ -27,6 +27,10 @@ import { IRecommendedVersion, NotificationCountType, Room } from "matrix-js-sdk/
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { EventSubscription } from "fbemitter"; import { EventSubscription } from "fbemitter";
import { ISearchResults } from 'matrix-js-sdk/src/@types/search'; import { ISearchResults } from 'matrix-js-sdk/src/@types/search';
import { logger } from "matrix-js-sdk/src/logger";
import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
import { EventType } from 'matrix-js-sdk/src/@types/event';
import { RoomState } from 'matrix-js-sdk/src/models/room-state';
import shouldHideEvent from '../../shouldHideEvent'; import shouldHideEvent from '../../shouldHideEvent';
import { _t } from '../../languageHandler'; import { _t } from '../../languageHandler';
@ -89,9 +93,6 @@ import MessageComposer from '../views/rooms/MessageComposer';
import JumpToBottomButton from "../views/rooms/JumpToBottomButton"; import JumpToBottomButton from "../views/rooms/JumpToBottomButton";
import TopUnreadMessagesBar from "../views/rooms/TopUnreadMessagesBar"; import TopUnreadMessagesBar from "../views/rooms/TopUnreadMessagesBar";
import SpaceStore from "../../stores/spaces/SpaceStore"; import SpaceStore from "../../stores/spaces/SpaceStore";
import { logger } from "matrix-js-sdk/src/logger";
import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
import { dispatchShowThreadEvent } from '../../dispatcher/dispatch-actions/threads'; import { dispatchShowThreadEvent } from '../../dispatcher/dispatch-actions/threads';
import { fetchInitialEvent } from "../../utils/EventUtils"; import { fetchInitialEvent } from "../../utils/EventUtils";
import { ComposerType } from "../../dispatcher/payloads/ComposerInsertPayload"; import { ComposerType } from "../../dispatcher/payloads/ComposerInsertPayload";
@ -1164,12 +1165,21 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
} }
}; };
private onRoomStateEvents = (ev: MatrixEvent, state) => { private onRoomStateEvents = (ev: MatrixEvent, state: RoomState) => {
// ignore if we don't have a room yet // ignore if we don't have a room yet
if (!this.state.room || this.state.room.roomId !== state.roomId) { if (!this.state.room || this.state.room.roomId !== state.roomId) {
return; return;
} }
if (ev.getType() === EventType.RoomCanonicalAlias) {
// re-view the room so MatrixChat can manage the alias in the URL properly
dis.dispatch({
action: Action.ViewRoom,
room_id: this.state.room.roomId,
});
return; // this event cannot affect permissions so bail
}
this.updatePermissions(this.state.room); this.updatePermissions(this.state.room);
}; };