mirror of
https://github.com/element-hq/element-web.git
synced 2024-11-30 23:31:28 +03:00
243 lines
8.6 KiB
TypeScript
243 lines
8.6 KiB
TypeScript
/*
|
|
Copyright 2019 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.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
import dis from '../dispatcher/dispatcher';
|
|
import { pendingVerificationRequestForUser } from '../verification';
|
|
import { Store } from 'flux/utils';
|
|
import SettingsStore from "../settings/SettingsStore";
|
|
import { RightPanelPhases, RIGHT_PANEL_PHASES_NO_ARGS } from "./RightPanelStorePhases";
|
|
import { ActionPayload } from "../dispatcher/payloads";
|
|
import { Action } from '../dispatcher/actions';
|
|
import { SettingLevel } from "../settings/SettingLevel";
|
|
|
|
interface RightPanelStoreState {
|
|
// Whether or not to show the right panel at all. We split out rooms and groups
|
|
// because they're different flows for the user to follow.
|
|
showRoomPanel: boolean;
|
|
showGroupPanel: boolean;
|
|
|
|
// The last phase (screen) the right panel was showing
|
|
lastRoomPhase: RightPanelPhases;
|
|
lastGroupPhase: RightPanelPhases;
|
|
|
|
previousPhase?: RightPanelPhases;
|
|
|
|
// Extra information about the last phase
|
|
lastRoomPhaseParams: {[key: string]: any};
|
|
}
|
|
|
|
const INITIAL_STATE: RightPanelStoreState = {
|
|
showRoomPanel: SettingsStore.getValue("showRightPanelInRoom"),
|
|
showGroupPanel: SettingsStore.getValue("showRightPanelInGroup"),
|
|
lastRoomPhase: SettingsStore.getValue("lastRightPanelPhaseForRoom"),
|
|
lastGroupPhase: SettingsStore.getValue("lastRightPanelPhaseForGroup"),
|
|
lastRoomPhaseParams: {},
|
|
};
|
|
|
|
const GROUP_PHASES = [
|
|
RightPanelPhases.GroupMemberList,
|
|
RightPanelPhases.GroupRoomList,
|
|
RightPanelPhases.GroupRoomInfo,
|
|
RightPanelPhases.GroupMemberInfo,
|
|
];
|
|
|
|
const MEMBER_INFO_PHASES = [
|
|
RightPanelPhases.RoomMemberInfo,
|
|
RightPanelPhases.Room3pidMemberInfo,
|
|
RightPanelPhases.EncryptionPanel,
|
|
];
|
|
|
|
/**
|
|
* A class for tracking the state of the right panel between layouts and
|
|
* sessions.
|
|
*/
|
|
export default class RightPanelStore extends Store<ActionPayload> {
|
|
private static instance: RightPanelStore;
|
|
private state: RightPanelStoreState;
|
|
private lastRoomId: string;
|
|
|
|
constructor() {
|
|
super(dis);
|
|
|
|
// Initialise state
|
|
this.state = INITIAL_STATE;
|
|
}
|
|
|
|
get isOpenForRoom(): boolean {
|
|
return this.state.showRoomPanel;
|
|
}
|
|
|
|
get isOpenForGroup(): boolean {
|
|
return this.state.showGroupPanel;
|
|
}
|
|
|
|
get roomPanelPhase(): RightPanelPhases {
|
|
return this.state.lastRoomPhase;
|
|
}
|
|
|
|
get groupPanelPhase(): RightPanelPhases {
|
|
return this.state.lastGroupPhase;
|
|
}
|
|
|
|
get previousPhase(): RightPanelPhases | null {
|
|
return RIGHT_PANEL_PHASES_NO_ARGS.includes(this.state.previousPhase) ? this.state.previousPhase : null;
|
|
}
|
|
|
|
get visibleRoomPanelPhase(): RightPanelPhases {
|
|
return this.isOpenForRoom ? this.roomPanelPhase : null;
|
|
}
|
|
|
|
get visibleGroupPanelPhase(): RightPanelPhases {
|
|
return this.isOpenForGroup ? this.groupPanelPhase : null;
|
|
}
|
|
|
|
get roomPanelPhaseParams(): any {
|
|
return this.state.lastRoomPhaseParams || {};
|
|
}
|
|
|
|
private setState(newState: Partial<RightPanelStoreState>) {
|
|
this.state = Object.assign(this.state, newState);
|
|
|
|
SettingsStore.setValue(
|
|
"showRightPanelInRoom",
|
|
null,
|
|
SettingLevel.DEVICE,
|
|
this.state.showRoomPanel,
|
|
);
|
|
SettingsStore.setValue(
|
|
"showRightPanelInGroup",
|
|
null,
|
|
SettingLevel.DEVICE,
|
|
this.state.showGroupPanel,
|
|
);
|
|
|
|
if (RIGHT_PANEL_PHASES_NO_ARGS.includes(this.state.lastRoomPhase)) {
|
|
SettingsStore.setValue(
|
|
"lastRightPanelPhaseForRoom",
|
|
null,
|
|
SettingLevel.DEVICE,
|
|
this.state.lastRoomPhase,
|
|
);
|
|
}
|
|
if (RIGHT_PANEL_PHASES_NO_ARGS.includes(this.state.lastGroupPhase)) {
|
|
SettingsStore.setValue(
|
|
"lastRightPanelPhaseForGroup",
|
|
null,
|
|
SettingLevel.DEVICE,
|
|
this.state.lastGroupPhase,
|
|
);
|
|
}
|
|
|
|
this.__emitChange();
|
|
}
|
|
|
|
__onDispatch(payload: ActionPayload) { // eslint-disable-line @typescript-eslint/naming-convention
|
|
switch (payload.action) {
|
|
case 'view_room':
|
|
if (payload.room_id === this.lastRoomId) break; // skip this transition, probably a permalink
|
|
// fallthrough
|
|
case 'view_group':
|
|
this.lastRoomId = payload.room_id;
|
|
|
|
// Reset to the member list if we're viewing member info
|
|
if (MEMBER_INFO_PHASES.includes(this.state.lastRoomPhase)) {
|
|
this.setState({ lastRoomPhase: RightPanelPhases.RoomMemberList, lastRoomPhaseParams: {} });
|
|
}
|
|
|
|
// Do the same for groups
|
|
if (this.state.lastGroupPhase === RightPanelPhases.GroupMemberInfo) {
|
|
this.setState({ lastGroupPhase: RightPanelPhases.GroupMemberList });
|
|
}
|
|
break;
|
|
|
|
case Action.SetRightPanelPhase: {
|
|
let targetPhase = payload.phase;
|
|
let refireParams = payload.refireParams;
|
|
const allowClose = payload.allowClose ?? true;
|
|
// redirect to EncryptionPanel if there is an ongoing verification request
|
|
if (targetPhase === RightPanelPhases.RoomMemberInfo && payload.refireParams) {
|
|
const { member } = payload.refireParams;
|
|
const pendingRequest = pendingVerificationRequestForUser(member);
|
|
if (pendingRequest) {
|
|
targetPhase = RightPanelPhases.EncryptionPanel;
|
|
refireParams = {
|
|
verificationRequest: pendingRequest,
|
|
member,
|
|
};
|
|
}
|
|
}
|
|
if (!RightPanelPhases[targetPhase]) {
|
|
console.warn(`Tried to switch right panel to unknown phase: ${targetPhase}`);
|
|
return;
|
|
}
|
|
|
|
if (GROUP_PHASES.includes(targetPhase)) {
|
|
if (targetPhase === this.state.lastGroupPhase) {
|
|
this.setState({
|
|
showGroupPanel: !this.state.showGroupPanel,
|
|
previousPhase: null,
|
|
});
|
|
} else {
|
|
this.setState({
|
|
lastGroupPhase: targetPhase,
|
|
showGroupPanel: true,
|
|
previousPhase: this.state.lastGroupPhase,
|
|
});
|
|
}
|
|
} else {
|
|
if (targetPhase === this.state.lastRoomPhase && !refireParams && allowClose) {
|
|
this.setState({
|
|
showRoomPanel: !this.state.showRoomPanel,
|
|
previousPhase: null,
|
|
});
|
|
} else {
|
|
this.setState({
|
|
lastRoomPhase: targetPhase,
|
|
showRoomPanel: true,
|
|
lastRoomPhaseParams: refireParams || {},
|
|
previousPhase: this.state.lastRoomPhase,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Let things like the member info panel actually open to the right member.
|
|
dis.dispatch({
|
|
action: Action.AfterRightPanelPhaseChange,
|
|
phase: targetPhase,
|
|
...(refireParams || {}),
|
|
});
|
|
break;
|
|
}
|
|
|
|
case Action.ToggleRightPanel:
|
|
if (payload.type === "room") {
|
|
this.setState({ showRoomPanel: !this.state.showRoomPanel });
|
|
} else { // group
|
|
this.setState({ showGroupPanel: !this.state.showGroupPanel });
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static getSharedInstance(): RightPanelStore {
|
|
if (!RightPanelStore.instance) {
|
|
RightPanelStore.instance = new RightPanelStore();
|
|
}
|
|
return RightPanelStore.instance;
|
|
}
|
|
}
|
|
|
|
window.mxRightPanelStore = RightPanelStore.getSharedInstance();
|