Merge pull request #3703 from matrix-org/travis/right-panel-v2
Refactor RightPanel to match expected behaviourpull/21833/head
commit
7230d51cca
|
@ -38,6 +38,7 @@ import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
|||
import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks";
|
||||
import {Group} from "matrix-js-sdk";
|
||||
import {allSettled, sleep} from "../../utils/promise";
|
||||
import RightPanelStore from "../../stores/RightPanelStore";
|
||||
|
||||
const LONG_DESC_PLACEHOLDER = _td(
|
||||
`<h1>HTML for your community's page</h1>
|
||||
|
@ -542,10 +543,6 @@ export default createReactClass({
|
|||
});
|
||||
},
|
||||
|
||||
_onShowRhsClick: function(ev) {
|
||||
dis.dispatch({ action: 'show_right_panel' });
|
||||
},
|
||||
|
||||
_onEditClick: function() {
|
||||
this.setState({
|
||||
editing: true,
|
||||
|
@ -583,6 +580,10 @@ export default createReactClass({
|
|||
profileForm: null,
|
||||
});
|
||||
break;
|
||||
case 'after_right_panel_phase_change':
|
||||
// We don't keep state on the right panel, so just re-render to update
|
||||
this.forceUpdate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1298,7 +1299,9 @@ export default createReactClass({
|
|||
);
|
||||
}
|
||||
|
||||
const rightPanel = !this.props.collapsedRhs ? <RightPanel groupId={this.props.groupId} /> : undefined;
|
||||
const rightPanel = !RightPanelStore.getSharedInstance().isOpenForGroup
|
||||
? <RightPanel groupId={this.props.groupId} />
|
||||
: undefined;
|
||||
|
||||
const headerClasses = {
|
||||
"mx_GroupView_header": true,
|
||||
|
@ -1326,9 +1329,9 @@ export default createReactClass({
|
|||
<div className="mx_GroupView_header_rightCol">
|
||||
{ rightButtons }
|
||||
</div>
|
||||
<GroupHeaderButtons collapsedRhs={this.props.collapsedRhs} />
|
||||
<GroupHeaderButtons />
|
||||
</div>
|
||||
<MainSplit collapsedRhs={this.props.collapsedRhs} panel={rightPanel}>
|
||||
<MainSplit panel={rightPanel}>
|
||||
<GeminiScrollbarWrapper className="mx_GroupView_body">
|
||||
{ this._getMembershipSection() }
|
||||
{ this._getGroupSection() }
|
||||
|
|
|
@ -70,7 +70,6 @@ const LoggedInView = createReactClass({
|
|||
// Called with the credentials of a registered user (if they were a ROU that
|
||||
// transitioned to PWLU)
|
||||
onRegistered: PropTypes.func,
|
||||
collapsedRhs: PropTypes.bool,
|
||||
|
||||
// Used by the RoomView to handle joining rooms
|
||||
viaServers: PropTypes.arrayOf(PropTypes.string),
|
||||
|
@ -554,7 +553,6 @@ const LoggedInView = createReactClass({
|
|||
eventPixelOffset={this.props.initialEventPixelOffset}
|
||||
key={this.props.currentRoomId || 'roomview'}
|
||||
disabled={this.props.middleDisabled}
|
||||
collapsedRhs={this.props.collapsedRhs}
|
||||
ConferenceHandler={this.props.ConferenceHandler}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
/>;
|
||||
|
@ -585,7 +583,6 @@ const LoggedInView = createReactClass({
|
|||
pageElement = <GroupView
|
||||
groupId={this.props.currentGroupId}
|
||||
isNew={this.props.currentGroupIsNew}
|
||||
collapsedRhs={this.props.collapsedRhs}
|
||||
/>;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ export default class MainSplit extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.panel && !this.props.collapsedRhs) {
|
||||
if (this.props.panel) {
|
||||
this._createResizer();
|
||||
}
|
||||
}
|
||||
|
@ -74,23 +74,6 @@ export default class MainSplit extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const wasExpanded = !this.props.collapsedRhs && prevProps.collapsedRhs;
|
||||
const wasCollapsed = this.props.collapsedRhs && !prevProps.collapsedRhs;
|
||||
const wasPanelSet = this.props.panel && !prevProps.panel;
|
||||
const wasPanelCleared = !this.props.panel && prevProps.panel;
|
||||
|
||||
if (this.resizeContainer && (wasExpanded || wasPanelSet)) {
|
||||
// The resizer can only be created when **both** expanded and the panel is
|
||||
// set. Once both are true, the container ref will mount, which is required
|
||||
// for the resizer to work.
|
||||
this._createResizer();
|
||||
} else if (this.resizer && (wasCollapsed || wasPanelCleared)) {
|
||||
this.resizer.detach();
|
||||
this.resizer = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const bodyView = React.Children.only(this.props.children);
|
||||
const panelView = this.props.panel;
|
||||
|
|
|
@ -177,10 +177,9 @@ export default createReactClass({
|
|||
viewUserId: null,
|
||||
// this is persisted as mx_lhs_size, loaded in LoggedInView
|
||||
collapseLhs: false,
|
||||
collapsedRhs: window.localStorage.getItem("mx_rhs_collapsed") === "true",
|
||||
leftDisabled: false,
|
||||
middleDisabled: false,
|
||||
rightDisabled: false,
|
||||
// the right panel's disabled state is tracked in its store.
|
||||
|
||||
version: null,
|
||||
newVersion: null,
|
||||
|
@ -659,23 +658,11 @@ export default createReactClass({
|
|||
collapseLhs: false,
|
||||
});
|
||||
break;
|
||||
case 'hide_right_panel':
|
||||
window.localStorage.setItem("mx_rhs_collapsed", true);
|
||||
this.setState({
|
||||
collapsedRhs: true,
|
||||
});
|
||||
break;
|
||||
case 'show_right_panel':
|
||||
window.localStorage.setItem("mx_rhs_collapsed", false);
|
||||
this.setState({
|
||||
collapsedRhs: false,
|
||||
});
|
||||
break;
|
||||
case 'panel_disable': {
|
||||
this.setState({
|
||||
leftDisabled: payload.leftDisabled || payload.sideDisabled || false,
|
||||
middleDisabled: payload.middleDisabled || false,
|
||||
rightDisabled: payload.rightDisabled || payload.sideDisabled || false,
|
||||
// We don't track the right panel being disabled here - it's tracked in the store.
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -1247,7 +1234,6 @@ export default createReactClass({
|
|||
view: VIEWS.LOGIN,
|
||||
ready: false,
|
||||
collapseLhs: false,
|
||||
collapsedRhs: false,
|
||||
currentRoomId: null,
|
||||
});
|
||||
this.subTitleStatus = '';
|
||||
|
@ -1263,7 +1249,6 @@ export default createReactClass({
|
|||
view: VIEWS.SOFT_LOGOUT,
|
||||
ready: false,
|
||||
collapseLhs: false,
|
||||
collapsedRhs: false,
|
||||
currentRoomId: null,
|
||||
});
|
||||
this.subTitleStatus = '';
|
||||
|
@ -1707,8 +1692,6 @@ export default createReactClass({
|
|||
handleResize: function(e) {
|
||||
const hideLhsThreshold = 1000;
|
||||
const showLhsThreshold = 1000;
|
||||
const hideRhsThreshold = 820;
|
||||
const showRhsThreshold = 820;
|
||||
|
||||
if (this._windowWidth > hideLhsThreshold && window.innerWidth <= hideLhsThreshold) {
|
||||
dis.dispatch({ action: 'hide_left_panel' });
|
||||
|
@ -1716,12 +1699,6 @@ export default createReactClass({
|
|||
if (this._windowWidth <= showLhsThreshold && window.innerWidth > showLhsThreshold) {
|
||||
dis.dispatch({ action: 'show_left_panel' });
|
||||
}
|
||||
if (this._windowWidth > hideRhsThreshold && window.innerWidth <= hideRhsThreshold) {
|
||||
dis.dispatch({ action: 'hide_right_panel' });
|
||||
}
|
||||
if (this._windowWidth <= showRhsThreshold && window.innerWidth > showRhsThreshold) {
|
||||
dis.dispatch({ action: 'show_right_panel' });
|
||||
}
|
||||
|
||||
this.state.resizeNotifier.notifyWindowResized();
|
||||
this._windowWidth = window.innerWidth;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2017 New Vector Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2017, 2018 New Vector Ltd
|
||||
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");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -28,13 +28,15 @@ import RateLimitedFunc from '../../ratelimitedfunc';
|
|||
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||
import GroupStore from '../../stores/GroupStore';
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import {RIGHT_PANEL_PHASES, RIGHT_PANEL_PHASES_NO_ARGS} from "../../stores/RightPanelStorePhases";
|
||||
import RightPanelStore from "../../stores/RightPanelStore";
|
||||
|
||||
export default class RightPanel extends React.Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
roomId: PropTypes.string, // if showing panels for a given room, this is set
|
||||
groupId: PropTypes.string, // if showing panels for a given group, this is set
|
||||
user: PropTypes.object,
|
||||
user: PropTypes.object, // used if we know the user ahead of opening the panel
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -44,23 +46,12 @@ export default class RightPanel extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
static Phase = Object.freeze({
|
||||
RoomMemberList: 'RoomMemberList',
|
||||
GroupMemberList: 'GroupMemberList',
|
||||
GroupRoomList: 'GroupRoomList',
|
||||
GroupRoomInfo: 'GroupRoomInfo',
|
||||
FilePanel: 'FilePanel',
|
||||
NotificationPanel: 'NotificationPanel',
|
||||
RoomMemberInfo: 'RoomMemberInfo',
|
||||
Room3pidMemberInfo: 'Room3pidMemberInfo',
|
||||
GroupMemberInfo: 'GroupMemberInfo',
|
||||
});
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
phase: this._getPhaseFromProps(),
|
||||
isUserPrivilegedInGroup: null,
|
||||
member: this._getUserForPanel(),
|
||||
};
|
||||
this.onAction = this.onAction.bind(this);
|
||||
this.onRoomStateMember = this.onRoomStateMember.bind(this);
|
||||
|
@ -73,13 +64,30 @@ export default class RightPanel extends React.Component {
|
|||
}, 500);
|
||||
}
|
||||
|
||||
// Helper function to split out the logic for _getPhaseFromProps() and the constructor
|
||||
// as both are called at the same time in the constructor.
|
||||
_getUserForPanel() {
|
||||
if (this.state && this.state.member) return this.state.member;
|
||||
const lastParams = RightPanelStore.getSharedInstance().roomPanelPhaseParams;
|
||||
return this.props.user || lastParams['member'];
|
||||
}
|
||||
|
||||
_getPhaseFromProps() {
|
||||
const rps = RightPanelStore.getSharedInstance();
|
||||
if (this.props.groupId) {
|
||||
return RightPanel.Phase.GroupMemberList;
|
||||
} else if (this.props.user) {
|
||||
return RightPanel.Phase.RoomMemberInfo;
|
||||
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.groupPanelPhase)) {
|
||||
dis.dispatch({action: "set_right_panel_phase", phase: RIGHT_PANEL_PHASES.GroupMemberList});
|
||||
return RIGHT_PANEL_PHASES.GroupMemberList;
|
||||
}
|
||||
return rps.groupPanelPhase;
|
||||
} else if (this._getUserForPanel()) {
|
||||
return RIGHT_PANEL_PHASES.RoomMemberInfo;
|
||||
} else {
|
||||
return RightPanel.Phase.RoomMemberList;
|
||||
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.roomPanelPhase)) {
|
||||
dis.dispatch({action: "set_right_panel_phase", phase: RIGHT_PANEL_PHASES.RoomMemberList});
|
||||
return RIGHT_PANEL_PHASES.RoomMemberList;
|
||||
}
|
||||
return rps.roomPanelPhase;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,9 +96,6 @@ export default class RightPanel extends React.Component {
|
|||
const cli = this.context.matrixClient;
|
||||
cli.on("RoomState.members", this.onRoomStateMember);
|
||||
this._initGroupStore(this.props.groupId);
|
||||
if (this.props.user) {
|
||||
this.setState({member: this.props.user});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -126,7 +131,7 @@ export default class RightPanel extends React.Component {
|
|||
onInviteToGroupButtonClick() {
|
||||
showGroupInviteDialog(this.props.groupId).then(() => {
|
||||
this.setState({
|
||||
phase: RightPanel.Phase.GroupMemberList,
|
||||
phase: RIGHT_PANEL_PHASES.GroupMemberList,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -142,9 +147,9 @@ export default class RightPanel extends React.Component {
|
|||
return;
|
||||
}
|
||||
// redraw the badge on the membership list
|
||||
if (this.state.phase === RightPanel.Phase.RoomMemberList && member.roomId === this.props.roomId) {
|
||||
if (this.state.phase === RIGHT_PANEL_PHASES.RoomMemberList && member.roomId === this.props.roomId) {
|
||||
this._delayedUpdate();
|
||||
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo && member.roomId === this.props.roomId &&
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.RoomMemberInfo && member.roomId === this.props.roomId &&
|
||||
member.userId === this.state.member.userId) {
|
||||
// refresh the member info (e.g. new power level)
|
||||
this._delayedUpdate();
|
||||
|
@ -152,7 +157,7 @@ export default class RightPanel extends React.Component {
|
|||
}
|
||||
|
||||
onAction(payload) {
|
||||
if (payload.action === "view_right_panel_phase") {
|
||||
if (payload.action === "after_right_panel_phase_change") {
|
||||
this.setState({
|
||||
phase: payload.phase,
|
||||
groupRoomId: payload.groupRoomId,
|
||||
|
@ -178,13 +183,13 @@ export default class RightPanel extends React.Component {
|
|||
|
||||
let panel = <div />;
|
||||
|
||||
if (this.props.roomId && this.state.phase === RightPanel.Phase.RoomMemberList) {
|
||||
if (this.props.roomId && this.state.phase === RIGHT_PANEL_PHASES.RoomMemberList) {
|
||||
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />;
|
||||
} else if (this.props.groupId && this.state.phase === RightPanel.Phase.GroupMemberList) {
|
||||
} else if (this.props.groupId && this.state.phase === RIGHT_PANEL_PHASES.GroupMemberList) {
|
||||
panel = <GroupMemberList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
} else if (this.state.phase === RightPanel.Phase.GroupRoomList) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.GroupRoomList) {
|
||||
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.RoomMemberInfo) {
|
||||
if (SettingsStore.isFeatureEnabled("feature_dm_verification")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
|
@ -201,9 +206,9 @@ export default class RightPanel extends React.Component {
|
|||
} else {
|
||||
panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
||||
}
|
||||
} else if (this.state.phase === RightPanel.Phase.Room3pidMemberInfo) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.Room3pidMemberInfo) {
|
||||
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
|
||||
} else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.GroupMemberInfo) {
|
||||
if (SettingsStore.isFeatureEnabled("feature_dm_verification")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
|
@ -225,14 +230,14 @@ export default class RightPanel extends React.Component {
|
|||
/>
|
||||
);
|
||||
}
|
||||
} else if (this.state.phase === RightPanel.Phase.GroupRoomInfo) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.GroupRoomInfo) {
|
||||
panel = <GroupRoomInfo
|
||||
groupRoomId={this.state.groupRoomId}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.groupRoomId} />;
|
||||
} else if (this.state.phase === RightPanel.Phase.NotificationPanel) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.NotificationPanel) {
|
||||
panel = <NotificationPanel />;
|
||||
} else if (this.state.phase === RightPanel.Phase.FilePanel) {
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.FilePanel) {
|
||||
panel = <FilePanel roomId={this.props.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,20 +108,9 @@ module.exports = createReactClass({
|
|||
),
|
||||
});
|
||||
});
|
||||
|
||||
// dis.dispatch({
|
||||
// action: 'panel_disable',
|
||||
// sideDisabled: true,
|
||||
// middleDisabled: true,
|
||||
// });
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
// dis.dispatch({
|
||||
// action: 'panel_disable',
|
||||
// sideDisabled: false,
|
||||
// middleDisabled: false,
|
||||
// });
|
||||
if (this.filterTimeout) {
|
||||
clearTimeout(this.filterTimeout);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import WidgetEchoStore from '../../stores/WidgetEchoStore';
|
|||
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
||||
import WidgetUtils from '../../utils/WidgetUtils';
|
||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||
import RightPanelStore from "../../stores/RightPanelStore";
|
||||
|
||||
const DEBUG = false;
|
||||
let debuglog = function() {};
|
||||
|
@ -98,9 +99,6 @@ module.exports = createReactClass({
|
|||
// * invited us to the room
|
||||
oobData: PropTypes.object,
|
||||
|
||||
// is the RightPanel collapsed?
|
||||
collapsedRhs: PropTypes.bool,
|
||||
|
||||
// Servers the RoomView can use to try and assist joins
|
||||
viaServers: PropTypes.arrayOf(PropTypes.string),
|
||||
},
|
||||
|
@ -587,6 +585,10 @@ module.exports = createReactClass({
|
|||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
case 'after_right_panel_phase_change':
|
||||
// We don't keep state on the right panel, so just re-render to update
|
||||
this.forceUpdate();
|
||||
break;
|
||||
case 'message_send_failed':
|
||||
case 'message_sent':
|
||||
this._checkIfAlone(this.state.room);
|
||||
|
@ -1717,7 +1719,7 @@ module.exports = createReactClass({
|
|||
let aux = null;
|
||||
let previewBar;
|
||||
let hideCancel = false;
|
||||
let hideRightPanel = false;
|
||||
let forceHideRightPanel = false;
|
||||
if (this.state.forwardingEvent !== null) {
|
||||
aux = <ForwardMessage onCancelClick={this.onCancelClick} />;
|
||||
} else if (this.state.searching) {
|
||||
|
@ -1763,7 +1765,7 @@ module.exports = createReactClass({
|
|||
</div>
|
||||
);
|
||||
} else {
|
||||
hideRightPanel = true;
|
||||
forceHideRightPanel = true;
|
||||
}
|
||||
} else if (hiddenHighlightCount > 0) {
|
||||
aux = (
|
||||
|
@ -1951,9 +1953,11 @@ module.exports = createReactClass({
|
|||
},
|
||||
);
|
||||
|
||||
const rightPanel = !hideRightPanel && this.state.room &&
|
||||
<RightPanel roomId={this.state.room.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
||||
const collapsedRhs = hideRightPanel || this.props.collapsedRhs;
|
||||
const showRightPanel = !forceHideRightPanel && this.state.room
|
||||
&& RightPanelStore.getSharedInstance().isOpenForRoom;
|
||||
const rightPanel = showRightPanel
|
||||
? <RightPanel roomId={this.state.room.roomId} resizeNotifier={this.props.resizeNotifier} />
|
||||
: null;
|
||||
|
||||
return (
|
||||
<main className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref={this._roomView}>
|
||||
|
@ -1963,7 +1967,6 @@ module.exports = createReactClass({
|
|||
searchInfo={searchInfo}
|
||||
oobData={this.props.oobData}
|
||||
inRoom={myMembership === 'join'}
|
||||
collapsedRhs={collapsedRhs}
|
||||
onSearchClick={this.onSearchClick}
|
||||
onSettingsClick={this.onSettingsClick}
|
||||
onPinnedClick={this.onPinnedClick}
|
||||
|
@ -1974,7 +1977,6 @@ module.exports = createReactClass({
|
|||
/>
|
||||
<MainSplit
|
||||
panel={rightPanel}
|
||||
collapsedRhs={collapsedRhs}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
>
|
||||
<div className={fadableSectionClasses}>
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 <div className="mx_HeaderButtons" role="tablist">
|
||||
{ this.renderButtons() }
|
||||
{this.renderButtons()}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
HeaderButtons.propTypes = {
|
||||
collapsedRhs: PropTypes.bool,
|
||||
};
|
||||
|
|
|
@ -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 {
|
|||
/>,
|
||||
<HeaderButton key="filesButton" name="filesButton"
|
||||
title={_t('Files')}
|
||||
isHighlighted={this.isPhase(RightPanel.Phase.FilePanel)}
|
||||
isHighlighted={this.isPhase(RIGHT_PANEL_PHASES.FilePanel)}
|
||||
onClick={this._onFilesClicked}
|
||||
analytics={['Right Panel', 'File List Button', 'click']}
|
||||
/>,
|
||||
<HeaderButton key="notifsButton" name="notifsButton"
|
||||
title={_t('Notifications')}
|
||||
isHighlighted={this.isPhase(RightPanel.Phase.NotificationPanel)}
|
||||
isHighlighted={this.isPhase(RIGHT_PANEL_PHASES.NotificationPanel)}
|
||||
onClick={this._onNotificationsClicked}
|
||||
analytics={['Right Panel', 'Notification List Button', 'click']}
|
||||
/>,
|
||||
|
|
|
@ -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 }
|
||||
<RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} />
|
||||
<RoomHeaderButtons />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
];
|
|
@ -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");
|
||||
|
|
|
@ -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)};
|
||||
|
|
Loading…
Reference in New Issue