diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js
index 433625419d..3228a862ce 100644
--- a/src/components/views/groups/GroupMemberList.js
+++ b/src/components/views/groups/GroupMemberList.js
@@ -1,6 +1,7 @@
/*
Copyright 2017 Vector Creations Ltd.
Copyright 2017 New Vector Ltd.
+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.
@@ -24,7 +25,7 @@ import PropTypes from 'prop-types';
import { showGroupInviteDialog } from '../../../GroupAddressPicker';
import AccessibleButton from '../elements/AccessibleButton';
import TintableSvg from '../elements/TintableSvg';
-import RightPanel from '../../structures/RightPanel';
+import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
const INITIAL_LOAD_NUM_MEMBERS = 30;
@@ -163,8 +164,8 @@ export default createReactClass({
onInviteToGroupButtonClick() {
showGroupInviteDialog(this.props.groupId).then(() => {
dis.dispatch({
- action: 'view_right_panel_phase',
- phase: RightPanel.Phase.GroupMemberList,
+ action: 'set_right_panel_phase',
+ phase: RIGHT_PANEL_PHASES.GroupMemberList,
groupId: this.props.groupId,
});
});
diff --git a/src/components/views/right_panel/GroupHeaderButtons.js b/src/components/views/right_panel/GroupHeaderButtons.js
index ec14331ad2..c134a5d237 100644
--- a/src/components/views/right_panel/GroupHeaderButtons.js
+++ b/src/components/views/right_panel/GroupHeaderButtons.js
@@ -3,6 +3,7 @@ Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Copyright 2017 New Vector Ltd
Copyright 2018 New Vector Ltd
+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.
@@ -20,21 +21,21 @@ limitations under the License.
import React from 'react';
import { _t } from '../../../languageHandler';
import HeaderButton from './HeaderButton';
-import HeaderButtons from './HeaderButtons';
-import RightPanel from '../../structures/RightPanel';
+import HeaderButtons, {HEADER_KIND_GROUP} from './HeaderButtons';
+import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
const GROUP_PHASES = [
- RightPanel.Phase.GroupMemberInfo,
- RightPanel.Phase.GroupMemberList,
+ RIGHT_PANEL_PHASES.GroupMemberInfo,
+ RIGHT_PANEL_PHASES.GroupMemberList,
];
const ROOM_PHASES = [
- RightPanel.Phase.GroupRoomList,
- RightPanel.Phase.GroupRoomInfo,
+ RIGHT_PANEL_PHASES.GroupRoomList,
+ RIGHT_PANEL_PHASES.GroupRoomInfo,
];
export default class GroupHeaderButtons extends HeaderButtons {
constructor(props) {
- super(props, RightPanel.Phase.GroupMemberList);
+ super(props, HEADER_KIND_GROUP);
this._onMembersClicked = this._onMembersClicked.bind(this);
this._onRoomsClicked = this._onRoomsClicked.bind(this);
}
@@ -44,29 +45,34 @@ export default class GroupHeaderButtons extends HeaderButtons {
if (payload.action === "view_user") {
if (payload.member) {
- this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member});
+ this.setPhase(RIGHT_PANEL_PHASES.RoomMemberInfo, {member: payload.member});
} else {
- this.setPhase(RightPanel.Phase.GroupMemberList);
+ this.setPhase(RIGHT_PANEL_PHASES.GroupMemberList);
}
} else if (payload.action === "view_group") {
- this.setPhase(RightPanel.Phase.GroupMemberList);
+ this.setPhase(RIGHT_PANEL_PHASES.GroupMemberList);
} else if (payload.action === "view_group_room") {
- this.setPhase(RightPanel.Phase.GroupRoomInfo, {groupRoomId: payload.groupRoomId, groupId: payload.groupId});
+ this.setPhase(
+ RIGHT_PANEL_PHASES.GroupRoomInfo,
+ {groupRoomId: payload.groupRoomId, groupId: payload.groupId},
+ );
} else if (payload.action === "view_group_room_list") {
- this.setPhase(RightPanel.Phase.GroupRoomList);
+ this.setPhase(RIGHT_PANEL_PHASES.GroupRoomList);
} else if (payload.action === "view_group_member_list") {
- this.setPhase(RightPanel.Phase.GroupMemberList);
+ this.setPhase(RIGHT_PANEL_PHASES.GroupMemberList);
} else if (payload.action === "view_group_user") {
- this.setPhase(RightPanel.Phase.GroupMemberInfo, {member: payload.member});
+ this.setPhase(RIGHT_PANEL_PHASES.GroupMemberInfo, {member: payload.member});
}
}
_onMembersClicked() {
- this.togglePhase(RightPanel.Phase.GroupMemberList, GROUP_PHASES);
+ // This toggles for us, if needed
+ this.setPhase(RIGHT_PANEL_PHASES.GroupMemberList);
}
_onRoomsClicked() {
- this.togglePhase(RightPanel.Phase.GroupRoomList, ROOM_PHASES);
+ // This toggles for us, if needed
+ this.setPhase(RIGHT_PANEL_PHASES.GroupRoomList);
}
renderButtons() {
diff --git a/src/components/views/right_panel/HeaderButtons.js b/src/components/views/right_panel/HeaderButtons.js
index a01b511dc8..ebe1f5f915 100644
--- a/src/components/views/right_panel/HeaderButtons.js
+++ b/src/components/views/right_panel/HeaderButtons.js
@@ -3,6 +3,7 @@ Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Copyright 2017 New Vector Ltd
Copyright 2018 New Vector Ltd
+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.
@@ -18,62 +19,50 @@ limitations under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import dis from '../../../dispatcher';
+import RightPanelStore from "../../../stores/RightPanelStore";
+
+export const HEADER_KIND_ROOM = "room";
+export const HEADER_KIND_GROUP = "group";
+
+const HEADER_KINDS = [HEADER_KIND_GROUP, HEADER_KIND_ROOM];
export default class HeaderButtons extends React.Component {
- constructor(props, initialPhase) {
+ constructor(props, kind) {
super(props);
+ if (!HEADER_KINDS.includes(kind)) throw new Error(`Invalid header kind: ${kind}`);
+
+ const rps = RightPanelStore.getSharedInstance();
this.state = {
- phase: props.collapsedRhs ? null : initialPhase,
- isUserPrivilegedInGroup: null,
+ headerKind: kind,
+ phase: kind === HEADER_KIND_ROOM ? rps.visibleRoomPanelPhase : rps.visibleGroupPanelPhase,
};
- this.onAction = this.onAction.bind(this);
}
componentWillMount() {
- this.dispatcherRef = dis.register(this.onAction);
+ this._storeToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelUpdate.bind(this));
+ this._dispatcherRef = dis.register(this.onAction.bind(this)); // used by subclasses
}
componentWillUnmount() {
- dis.unregister(this.dispatcherRef);
+ if (this._storeToken) this._storeToken.remove();
+ if (this._dispatcherRef) dis.unregister(this._dispatcherRef);
}
- componentDidUpdate(prevProps) {
- if (!prevProps.collapsedRhs && this.props.collapsedRhs) {
- this.setState({
- phase: null,
- });
- }
+ onAction(payload) {
+ // Ignore - intended to be overridden by subclasses
}
setPhase(phase, extras) {
- if (this.props.collapsedRhs) {
- dis.dispatch({
- action: 'show_right_panel',
- });
- }
- dis.dispatch(Object.assign({
- action: 'view_right_panel_phase',
+ dis.dispatch({
+ action: 'set_right_panel_phase',
phase: phase,
- }, extras));
+ refireParams: extras,
+ });
}
- togglePhase(phase, validPhases = [phase]) {
- if (validPhases.includes(this.state.phase)) {
- dis.dispatch({
- action: 'hide_right_panel',
- });
- } else {
- this.setPhase(phase);
- }
- }
-
- isPhase(phases) {
- if (this.props.collapsedRhs) {
- return false;
- }
+ isPhase(phases: string | string[]) {
if (Array.isArray(phases)) {
return phases.includes(this.state.phase);
} else {
@@ -81,22 +70,19 @@ export default class HeaderButtons extends React.Component {
}
}
- onAction(payload) {
- if (payload.action === "view_right_panel_phase") {
- this.setState({
- phase: payload.phase,
- });
+ onRightPanelUpdate() {
+ const rps = RightPanelStore.getSharedInstance();
+ if (this.state.headerKind === HEADER_KIND_ROOM) {
+ this.setState({phase: rps.visibleRoomPanelPhase});
+ } else if (this.state.head === HEADER_KIND_GROUP) {
+ this.setState({phase: rps.visibleGroupPanelPhase});
}
}
render() {
// inline style as this will be swapped around in future commits
return ,
,
diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js
index 275ec3fafa..eaf2e733ca 100644
--- a/src/components/views/rooms/RoomHeader.js
+++ b/src/components/views/rooms/RoomHeader.js
@@ -39,7 +39,6 @@ module.exports = createReactClass({
room: PropTypes.object,
oobData: PropTypes.object,
inRoom: PropTypes.bool,
- collapsedRhs: PropTypes.bool,
onSettingsClick: PropTypes.func,
onPinnedClick: PropTypes.func,
onSearchClick: PropTypes.func,
@@ -308,7 +307,7 @@ module.exports = createReactClass({
{ topicElement }
{ cancelButton }
{ rightRow }
-
+
);
diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js
index 8a00725718..24f256e706 100644
--- a/src/components/views/rooms/Stickerpicker.js
+++ b/src/components/views/rooms/Stickerpicker.js
@@ -181,8 +181,7 @@ export default class Stickerpicker extends React.Component {
case "stickerpicker_close":
this.setState({showStickers: false});
break;
- case "show_right_panel":
- case "hide_right_panel":
+ case "after_right_panel_phase_change":
case "show_left_panel":
case "hide_left_panel":
this.setState({showStickers: false});
diff --git a/src/settings/Settings.js b/src/settings/Settings.js
index b02ab82400..82dd639819 100644
--- a/src/settings/Settings.js
+++ b/src/settings/Settings.js
@@ -1,6 +1,7 @@
/*
Copyright 2017 Travis Ralston
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");
you may not use this file except in compliance with the License.
@@ -24,6 +25,7 @@ import {
import CustomStatusController from "./controllers/CustomStatusController";
import ThemeController from './controllers/ThemeController';
import ReloadOnChangeController from "./controllers/ReloadOnChangeController";
+import {RIGHT_PANEL_PHASES} from "../stores/RightPanelStorePhases";
// 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'];
@@ -463,4 +465,20 @@ export const SETTINGS = {
displayName: _td("Show previews/thumbnails for images"),
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,
+ },
};
diff --git a/src/settings/handlers/DeviceSettingsHandler.js b/src/settings/handlers/DeviceSettingsHandler.js
index 76c518b97b..ed61e9f3be 100644
--- a/src/settings/handlers/DeviceSettingsHandler.js
+++ b/src/settings/handlers/DeviceSettingsHandler.js
@@ -1,6 +1,7 @@
/*
Copyright 2017 Travis Ralston
Copyright 2019 New Vector Ltd.
+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.
@@ -56,6 +57,17 @@ export default class DeviceSettingsHandler extends SettingsHandler {
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() || {};
return settings[settingName];
}
@@ -81,6 +93,20 @@ export default class DeviceSettingsHandler extends SettingsHandler {
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() || {};
settings[settingName] = newValue;
localStorage.setItem("mx_local_settings", JSON.stringify(settings));
diff --git a/src/stores/RightPanelStore.js b/src/stores/RightPanelStore.js
new file mode 100644
index 0000000000..37e7498141
--- /dev/null
+++ b/src/stores/RightPanelStore.js
@@ -0,0 +1,184 @@
+/*
+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";
+import {RIGHT_PANEL_PHASES, RIGHT_PANEL_PHASES_NO_ARGS} from "./RightPanelStorePhases";
+
+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"),
+
+ // Extra information about the last phase
+ lastRoomPhaseParams: {},
+};
+
+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;
+
+ _inhibitUpdates = false;
+
+ 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;
+ }
+
+ get visibleRoomPanelPhase(): string {
+ return this.isOpenForRoom ? this.roomPanelPhase : null;
+ }
+
+ get visibleGroupPanelPhase(): string {
+ return this.isOpenForGroup ? this.groupPanelPhase : null;
+ }
+
+ get roomPanelPhaseParams(): any {
+ return this._state.lastRoomPhaseParams || {};
+ }
+
+ _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,
+ );
+
+ 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) {
+ if (payload.action === 'panel_disable') {
+ this._inhibitUpdates = payload.rightDisabled || payload.sideDisabled || false;
+ return;
+ }
+
+ if (payload.action === 'view_room' || payload.action === 'view_group') {
+ // Reset to the member list if we're viewing member info
+ const memberInfoPhases = [RIGHT_PANEL_PHASES.RoomMemberInfo, RIGHT_PANEL_PHASES.Room3pidMemberInfo];
+ if (memberInfoPhases.includes(this._state.lastRoomPhase)) {
+ this._setState({lastRoomPhase: RIGHT_PANEL_PHASES.RoomMemberList, lastRoomPhaseParams: {}});
+ }
+
+ // Do the same for groups
+ if (this._state.lastGroupPhase === RIGHT_PANEL_PHASES.GroupMemberInfo) {
+ this._setState({lastGroupPhase: RIGHT_PANEL_PHASES.GroupMemberList});
+ }
+ }
+
+ if (payload.action !== 'set_right_panel_phase' || this._inhibitUpdates) 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,
+ showGroupPanel: true,
+ });
+ }
+ } else {
+ if (targetPhase === this._state.lastRoomPhase) {
+ this._setState({
+ showRoomPanel: !this._state.showRoomPanel,
+ });
+ } else {
+ this._setState({
+ lastRoomPhase: targetPhase,
+ showRoomPanel: true,
+ lastRoomPhaseParams: payload.refireParams || {},
+ });
+ }
+ }
+
+ // Let things like the member info panel actually open to the right member.
+ dis.dispatch({
+ action: 'after_right_panel_phase_change',
+ phase: targetPhase,
+ ...(payload.refireParams || {}),
+ });
+ }
+
+ static getSharedInstance(): RightPanelStore {
+ if (!RightPanelStore._instance) {
+ RightPanelStore._instance = new RightPanelStore();
+ }
+ return RightPanelStore._instance;
+ }
+}
diff --git a/src/stores/RightPanelStorePhases.js b/src/stores/RightPanelStorePhases.js
new file mode 100644
index 0000000000..96807ebf5b
--- /dev/null
+++ b/src/stores/RightPanelStorePhases.js
@@ -0,0 +1,41 @@
+/*
+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.
+*/
+
+// These are in their own file because of circular imports being a problem.
+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',
+});
+
+// These are the phases that are safe to persist (the ones that don't require additional
+// arguments).
+export const RIGHT_PANEL_PHASES_NO_ARGS = [
+ RIGHT_PANEL_PHASES.NotificationPanel,
+ RIGHT_PANEL_PHASES.FilePanel,
+ RIGHT_PANEL_PHASES.RoomMemberList,
+ RIGHT_PANEL_PHASES.GroupMemberList,
+ RIGHT_PANEL_PHASES.GroupRoomList,
+];
diff --git a/test/end-to-end-tests/src/usecases/invite.js b/test/end-to-end-tests/src/usecases/invite.js
index d7e02a38d8..814ecd30a6 100644
--- a/test/end-to-end-tests/src/usecases/invite.js
+++ b/test/end-to-end-tests/src/usecases/invite.js
@@ -17,6 +17,17 @@ limitations under the License.
module.exports = async function invite(session, userId) {
session.log.step(`invites "${userId}" to room`);
await session.delay(1000);
+ const memberPanelButton = await session.query(".mx_RightPanel_membersButton");
+ try {
+ await session.query(".mx_RightPanel_headerButton_highlight", 500);
+ // Right panel is open - toggle it to ensure it's the member list
+ // Sometimes our tests have this opened to MemberInfo
+ await memberPanelButton.click();
+ await memberPanelButton.click();
+ } catch (e) {
+ // Member list is closed - open it
+ await memberPanelButton.click();
+ }
const inviteButton = await session.query(".mx_MemberList_invite");
await inviteButton.click();
const inviteTextArea = await session.query(".mx_AddressPickerDialog textarea");
diff --git a/test/end-to-end-tests/src/usecases/memberlist.js b/test/end-to-end-tests/src/usecases/memberlist.js
index f6b07b3500..42601b6610 100644
--- a/test/end-to-end-tests/src/usecases/memberlist.js
+++ b/test/end-to-end-tests/src/usecases/memberlist.js
@@ -62,6 +62,17 @@ module.exports.verifyDeviceForUser = async function(session, name, expectedDevic
};
async function getMembersInMemberlist(session) {
+ const memberPanelButton = await session.query(".mx_RightPanel_membersButton");
+ try {
+ await session.query(".mx_RightPanel_headerButton_highlight", 500);
+ // Right panel is open - toggle it to ensure it's the member list
+ // Sometimes our tests have this opened to MemberInfo
+ await memberPanelButton.click();
+ await memberPanelButton.click();
+ } catch (e) {
+ // Member list is closed - open it
+ await memberPanelButton.click();
+ }
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
return Promise.all(memberNameElements.map(async (el) => {
return {label: el, displayName: await session.innerText(el)};
- { this.renderButtons() }
+ {this.renderButtons()}
;
}
}
-
-HeaderButtons.propTypes = {
- collapsedRhs: PropTypes.bool,
-};
diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js
index 950fa30e38..f59159d1d9 100644
--- a/src/components/views/right_panel/RoomHeaderButtons.js
+++ b/src/components/views/right_panel/RoomHeaderButtons.js
@@ -3,6 +3,7 @@ Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Copyright 2017 New Vector Ltd
Copyright 2018 New Vector Ltd
+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.
@@ -20,18 +21,18 @@ limitations under the License.
import React from 'react';
import { _t } from '../../../languageHandler';
import HeaderButton from './HeaderButton';
-import HeaderButtons from './HeaderButtons';
-import RightPanel from '../../structures/RightPanel';
+import HeaderButtons, {HEADER_KIND_ROOM} from './HeaderButtons';
+import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
const MEMBER_PHASES = [
- RightPanel.Phase.RoomMemberList,
- RightPanel.Phase.RoomMemberInfo,
- RightPanel.Phase.Room3pidMemberInfo,
+ RIGHT_PANEL_PHASES.RoomMemberList,
+ RIGHT_PANEL_PHASES.RoomMemberInfo,
+ RIGHT_PANEL_PHASES.Room3pidMemberInfo,
];
export default class RoomHeaderButtons extends HeaderButtons {
constructor(props) {
- super(props, RightPanel.Phase.RoomMemberList);
+ super(props, HEADER_KIND_ROOM);
this._onMembersClicked = this._onMembersClicked.bind(this);
this._onFilesClicked = this._onFilesClicked.bind(this);
this._onNotificationsClicked = this._onNotificationsClicked.bind(this);
@@ -41,31 +42,32 @@ export default class RoomHeaderButtons extends HeaderButtons {
super.onAction(payload);
if (payload.action === "view_user") {
if (payload.member) {
- this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member});
+ this.setPhase(RIGHT_PANEL_PHASES.RoomMemberInfo, {member: payload.member});
} else {
- this.setPhase(RightPanel.Phase.RoomMemberList);
+ this.setPhase(RIGHT_PANEL_PHASES.RoomMemberList);
}
- } else if (payload.action === "view_room" && !this.props.collapsedRhs) {
- this.setPhase(RightPanel.Phase.RoomMemberList);
} else if (payload.action === "view_3pid_invite") {
if (payload.event) {
- this.setPhase(RightPanel.Phase.Room3pidMemberInfo, {event: payload.event});
+ this.setPhase(RIGHT_PANEL_PHASES.Room3pidMemberInfo, {event: payload.event});
} else {
- this.setPhase(RightPanel.Phase.RoomMemberList);
+ this.setPhase(RIGHT_PANEL_PHASES.RoomMemberList);
}
}
}
_onMembersClicked() {
- this.togglePhase(RightPanel.Phase.RoomMemberList, MEMBER_PHASES);
+ // This toggles for us, if needed
+ this.setPhase(RIGHT_PANEL_PHASES.RoomMemberList);
}
_onFilesClicked() {
- this.togglePhase(RightPanel.Phase.FilePanel);
+ // This toggles for us, if needed
+ this.setPhase(RIGHT_PANEL_PHASES.FilePanel);
}
_onNotificationsClicked() {
- this.togglePhase(RightPanel.Phase.NotificationPanel);
+ // This toggles for us, if needed
+ this.setPhase(RIGHT_PANEL_PHASES.NotificationPanel);
}
renderButtons() {
@@ -78,13 +80,13 @@ export default class RoomHeaderButtons extends HeaderButtons {
/>,