Build out a store for the right panel state machine
This should make it easier to funnel the expected behaviour through a central block of code.
This commit is contained in:
parent
625e3ef93a
commit
5253f29928
4 changed files with 175 additions and 13 deletions
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
Copyright 2017 New Vector Ltd
|
Copyright 2017, 2018 New Vector Ltd
|
||||||
Copyright 2018 New Vector Ltd
|
|
||||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -28,6 +28,7 @@ import RateLimitedFunc from '../../ratelimitedfunc';
|
||||||
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||||
import GroupStore from '../../stores/GroupStore';
|
import GroupStore from '../../stores/GroupStore';
|
||||||
import SettingsStore from "../../settings/SettingsStore";
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
|
import {RIGHT_PANEL_PHASES} from "../../stores/RightPanelStore";
|
||||||
|
|
||||||
export default class RightPanel extends React.Component {
|
export default class RightPanel extends React.Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
|
@ -44,17 +45,7 @@ export default class RightPanel extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Phase = Object.freeze({
|
static Phase = RIGHT_PANEL_PHASES;
|
||||||
RoomMemberList: 'RoomMemberList',
|
|
||||||
GroupMemberList: 'GroupMemberList',
|
|
||||||
GroupRoomList: 'GroupRoomList',
|
|
||||||
GroupRoomInfo: 'GroupRoomInfo',
|
|
||||||
FilePanel: 'FilePanel',
|
|
||||||
NotificationPanel: 'NotificationPanel',
|
|
||||||
RoomMemberInfo: 'RoomMemberInfo',
|
|
||||||
Room3pidMemberInfo: 'Room3pidMemberInfo',
|
|
||||||
GroupMemberInfo: 'GroupMemberInfo',
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Travis Ralston
|
Copyright 2017 Travis Ralston
|
||||||
Copyright 2018, 2019 New Vector Ltd.
|
Copyright 2018, 2019 New Vector Ltd.
|
||||||
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -24,6 +25,8 @@ import {
|
||||||
import CustomStatusController from "./controllers/CustomStatusController";
|
import CustomStatusController from "./controllers/CustomStatusController";
|
||||||
import ThemeController from './controllers/ThemeController';
|
import ThemeController from './controllers/ThemeController';
|
||||||
import ReloadOnChangeController from "./controllers/ReloadOnChangeController";
|
import ReloadOnChangeController from "./controllers/ReloadOnChangeController";
|
||||||
|
import RightPanel from "../components/structures/RightPanel";
|
||||||
|
import {RIGHT_PANEL_PHASES} from "../stores/RightPanelStore";
|
||||||
|
|
||||||
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
|
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
|
||||||
const LEVELS_ROOM_SETTINGS = ['device', 'room-device', 'room-account', 'account', 'config'];
|
const LEVELS_ROOM_SETTINGS = ['device', 'room-device', 'room-account', 'account', 'config'];
|
||||||
|
@ -463,4 +466,20 @@ export const SETTINGS = {
|
||||||
displayName: _td("Show previews/thumbnails for images"),
|
displayName: _td("Show previews/thumbnails for images"),
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
"showRightPanelInRoom": {
|
||||||
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
"showRightPanelInGroup": {
|
||||||
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
"lastRightPanelPhaseForRoom": {
|
||||||
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
default: RIGHT_PANEL_PHASES.RoomMemberInfo,
|
||||||
|
},
|
||||||
|
"lastRightPanelPhaseForGroup": {
|
||||||
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
default: RIGHT_PANEL_PHASES.GroupMemberList,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Travis Ralston
|
Copyright 2017 Travis Ralston
|
||||||
Copyright 2019 New Vector Ltd.
|
Copyright 2019 New Vector Ltd.
|
||||||
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -56,6 +57,17 @@ export default class DeviceSettingsHandler extends SettingsHandler {
|
||||||
return null; // wrong type or otherwise not set
|
return null; // wrong type or otherwise not set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case the right panel - see `setValue` for rationale.
|
||||||
|
if ([
|
||||||
|
"showRightPanelInRoom",
|
||||||
|
"showRightPanelInGroup",
|
||||||
|
"lastRightPanelPhaseForRoom",
|
||||||
|
"lastRightPanelPhaseForGroup",
|
||||||
|
].includes(settingName)) {
|
||||||
|
const val = JSON.parse(localStorage.getItem(`mx_${settingName}`) || "{}");
|
||||||
|
return val['value'];
|
||||||
|
}
|
||||||
|
|
||||||
const settings = this._getSettings() || {};
|
const settings = this._getSettings() || {};
|
||||||
return settings[settingName];
|
return settings[settingName];
|
||||||
}
|
}
|
||||||
|
@ -81,6 +93,20 @@ export default class DeviceSettingsHandler extends SettingsHandler {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case the right panel because we want to be able to update these all
|
||||||
|
// concurrently without stomping on one another. We could use async/await, though
|
||||||
|
// that introduces just enough latency to be annoying.
|
||||||
|
if ([
|
||||||
|
"showRightPanelInRoom",
|
||||||
|
"showRightPanelInGroup",
|
||||||
|
"lastRightPanelPhaseForRoom",
|
||||||
|
"lastRightPanelPhaseForGroup",
|
||||||
|
].includes(settingName)) {
|
||||||
|
localStorage.setItem(`mx_${settingName}`, JSON.stringify({value: newValue}));
|
||||||
|
this._watchers.notifyUpdate(settingName, null, SettingLevel.DEVICE, newValue);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
const settings = this._getSettings() || {};
|
const settings = this._getSettings() || {};
|
||||||
settings[settingName] = newValue;
|
settings[settingName] = newValue;
|
||||||
localStorage.setItem("mx_local_settings", JSON.stringify(settings));
|
localStorage.setItem("mx_local_settings", JSON.stringify(settings));
|
||||||
|
|
126
src/stores/RightPanelStore.js
Normal file
126
src/stores/RightPanelStore.js
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
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';
|
||||||
|
import {Store} from 'flux/utils';
|
||||||
|
import SettingsStore, {SettingLevel} from "../settings/SettingsStore";
|
||||||
|
|
||||||
|
const INITIAL_STATE = {
|
||||||
|
// 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: SettingsStore.getValue("showRightPanelInRoom"),
|
||||||
|
showGroupPanel: SettingsStore.getValue("showRightPanelInGroup"),
|
||||||
|
|
||||||
|
// The last phase (screen) the right panel was showing
|
||||||
|
lastRoomPhase: SettingsStore.getValue("lastRightPanelPhaseForRoom"),
|
||||||
|
lastGroupPhase: SettingsStore.getValue("lastRightPanelPhaseForGroup"),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RIGHT_PANEL_PHASES = Object.freeze({
|
||||||
|
// Room stuff
|
||||||
|
RoomMemberList: 'RoomMemberList',
|
||||||
|
FilePanel: 'FilePanel',
|
||||||
|
NotificationPanel: 'NotificationPanel',
|
||||||
|
RoomMemberInfo: 'RoomMemberInfo',
|
||||||
|
Room3pidMemberInfo: 'Room3pidMemberInfo',
|
||||||
|
|
||||||
|
// Group stuff
|
||||||
|
GroupMemberList: 'GroupMemberList',
|
||||||
|
GroupRoomList: 'GroupRoomList',
|
||||||
|
GroupRoomInfo: 'GroupRoomInfo',
|
||||||
|
GroupMemberInfo: 'GroupMemberInfo',
|
||||||
|
});
|
||||||
|
|
||||||
|
const GROUP_PHASES = Object.keys(RIGHT_PANEL_PHASES).filter(k => k.startsWith("Group"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for tracking the state of the right panel between layouts and
|
||||||
|
* sessions.
|
||||||
|
*/
|
||||||
|
export default class RightPanelStore extends Store {
|
||||||
|
static _instance;
|
||||||
|
|
||||||
|
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(): string {
|
||||||
|
return this._state.lastRoomPhase;
|
||||||
|
}
|
||||||
|
|
||||||
|
get groupPanelPhase(): string {
|
||||||
|
return this._state.lastGroupPhase;
|
||||||
|
}
|
||||||
|
|
||||||
|
_setState(newState) {
|
||||||
|
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);
|
||||||
|
SettingsStore.setValue("lastRightPanelPhaseForRoom", null, SettingLevel.DEVICE, this._state.lastRoomPhase);
|
||||||
|
SettingsStore.setValue("lastRightPanelPhaseForGroup", null, SettingLevel.DEVICE, this._state.lastGroupPhase);
|
||||||
|
this.__emitChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
__onDispatch(payload) {
|
||||||
|
if (payload.action !== 'set_right_panel_phase') return;
|
||||||
|
|
||||||
|
const targetPhase = payload.phase;
|
||||||
|
if (!RIGHT_PANEL_PHASES[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,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._setState({
|
||||||
|
lastGroupPhase: targetPhase,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (targetPhase === this._state.lastRoomPhase) {
|
||||||
|
this._setState({
|
||||||
|
showRoomPanel: !this._state.showRoomPanel,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._setState({
|
||||||
|
lastRoomPhase: targetPhase,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSharedInstance(): RightPanelStore {
|
||||||
|
if (!RightPanelStore._instance) {
|
||||||
|
RightPanelStore._instance = new RightPanelStore();
|
||||||
|
}
|
||||||
|
return RightPanelStore._instance;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue