Merge pull request #4244 from matrix-org/t3chguy/shortcuts3

Add shortcut CmdOrCtrl+. to toggle right panel
This commit is contained in:
Michael Telatynski 2020-03-20 16:26:26 +00:00 committed by GitHub
commit 0212e96938
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 110 additions and 66 deletions

View file

@ -36,6 +36,7 @@ export const Key = {
CONTEXT_MENU: "ContextMenu", CONTEXT_MENU: "ContextMenu",
COMMA: ",", COMMA: ",",
PERIOD: ".",
LESS_THAN: "<", LESS_THAN: "<",
GREATER_THAN: ">", GREATER_THAN: ">",
BACKTICK: "`", BACKTICK: "`",

View file

@ -218,6 +218,12 @@ const shortcuts: Record<Categories, IShortcut[]> = {
key: Key.SPACE, key: Key.SPACE,
}], }],
description: _td("Activate selected button"), description: _td("Activate selected button"),
}, {
keybinds: [{
modifiers: [CMD_OR_CTRL],
key: Key.PERIOD,
}],
description: _td("Toggle right panel"),
}, { }, {
keybinds: [{ keybinds: [{
modifiers: [CMD_OR_CTRL], modifiers: [CMD_OR_CTRL],

View file

@ -424,6 +424,7 @@ export default createReactClass({
membershipBusy: false, membershipBusy: false,
publicityBusy: false, publicityBusy: false,
inviterProfile: null, inviterProfile: null,
showRightPanel: RightPanelStore.getSharedInstance().isOpenForGroup,
}; };
}, },
@ -436,12 +437,18 @@ export default createReactClass({
this._initGroupStore(this.props.groupId, true); this._initGroupStore(this.props.groupId, true);
this._dispatcherRef = dis.register(this._onAction); this._dispatcherRef = dis.register(this._onAction);
this._rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this._onRightPanelStoreUpdate);
}, },
componentWillUnmount: function() { componentWillUnmount: function() {
this._unmounted = true; this._unmounted = true;
this._matrixClient.removeListener("Group.myMembership", this._onGroupMyMembership); this._matrixClient.removeListener("Group.myMembership", this._onGroupMyMembership);
dis.unregister(this._dispatcherRef); dis.unregister(this._dispatcherRef);
// Remove RightPanelStore listener
if (this._rightPanelStoreToken) {
this._rightPanelStoreToken.remove();
}
}, },
componentWillReceiveProps: function(newProps) { componentWillReceiveProps: function(newProps) {
@ -455,6 +462,12 @@ export default createReactClass({
} }
}, },
_onRightPanelStoreUpdate: function() {
this.setState({
showRightPanel: RightPanelStore.getSharedInstance().isOpenForGroup,
});
},
_onGroupMyMembership: function(group) { _onGroupMyMembership: function(group) {
if (this._unmounted || group.groupId !== this.props.groupId) return; if (this._unmounted || group.groupId !== this.props.groupId) return;
if (group.myMembership === 'leave') { if (group.myMembership === 'leave') {
@ -577,10 +590,6 @@ export default createReactClass({
profileForm: null, profileForm: null,
}); });
break; 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: default:
break; break;
} }
@ -1295,9 +1304,7 @@ export default createReactClass({
); );
} }
const rightPanel = RightPanelStore.getSharedInstance().isOpenForGroup const rightPanel = this.state.showRightPanel ? <RightPanel groupId={this.props.groupId} /> : undefined;
? <RightPanel groupId={this.props.groupId} />
: undefined;
const headerClasses = { const headerClasses = {
"mx_GroupView_header": true, "mx_GroupView_header": true,

View file

@ -397,6 +397,15 @@ const LoggedInView = createReactClass({
handled = true; handled = true;
} }
break; break;
case Key.PERIOD:
if (ctrlCmdOnly && (this.props.page_type === "room_view" || this.props.page_type === "group_view")) {
dis.dispatch({
action: 'toggle_right_panel',
type: this.props.page_type === "room_view" ? "room" : "group",
});
handled = true;
}
} }
if (handled) { if (handled) {

View file

@ -132,6 +132,7 @@ export default createReactClass({
isPeeking: false, isPeeking: false,
showingPinned: false, showingPinned: false,
showReadReceipts: true, showReadReceipts: true,
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
// error object, as from the matrix client/server API // error object, as from the matrix client/server API
// If we failed to load information about the room, // If we failed to load information about the room,
@ -177,6 +178,7 @@ export default createReactClass({
MatrixClientPeg.get().on("userTrustStatusChanged", this.onUserVerificationChanged); MatrixClientPeg.get().on("userTrustStatusChanged", this.onUserVerificationChanged);
// Start listening for RoomViewStore updates // Start listening for RoomViewStore updates
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
this._rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this._onRightPanelStoreUpdate);
this._onRoomViewStoreUpdate(true); this._onRoomViewStoreUpdate(true);
WidgetEchoStore.on('update', this._onWidgetEchoStoreUpdate); WidgetEchoStore.on('update', this._onWidgetEchoStoreUpdate);
@ -500,6 +502,10 @@ export default createReactClass({
if (this._roomStoreToken) { if (this._roomStoreToken) {
this._roomStoreToken.remove(); this._roomStoreToken.remove();
} }
// Remove RightPanelStore listener
if (this._rightPanelStoreToken) {
this._rightPanelStoreToken.remove();
}
WidgetEchoStore.removeListener('update', this._onWidgetEchoStoreUpdate); WidgetEchoStore.removeListener('update', this._onWidgetEchoStoreUpdate);
@ -516,6 +522,12 @@ export default createReactClass({
// Tinter.tint(); // reset colourscheme // Tinter.tint(); // reset colourscheme
}, },
_onRightPanelStoreUpdate: function() {
this.setState({
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
});
},
onPageUnload(event) { onPageUnload(event) {
if (ContentMessages.sharedInstance().getCurrentUploads().length > 0) { if (ContentMessages.sharedInstance().getCurrentUploads().length > 0) {
return event.returnValue = return event.returnValue =
@ -555,10 +567,6 @@ export default createReactClass({
onAction: function(payload) { onAction: function(payload) {
switch (payload.action) { 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_send_failed':
case 'message_sent': case 'message_sent':
this._checkIfAlone(this.state.room); this._checkIfAlone(this.state.room);
@ -2014,8 +2022,7 @@ export default createReactClass({
}, },
); );
const showRightPanel = !forceHideRightPanel && this.state.room const showRightPanel = !forceHideRightPanel && this.state.room && this.state.showRightPanel;
&& RightPanelStore.getSharedInstance().isOpenForRoom;
const rightPanel = showRightPanel const rightPanel = showRightPanel
? <RightPanel roomId={this.state.room.roomId} resizeNotifier={this.props.resizeNotifier} /> ? <RightPanel roomId={this.state.room.roomId} resizeNotifier={this.props.resizeNotifier} />
: null; : null;

View file

@ -2213,6 +2213,7 @@
"Toggle the top left menu": "Toggle the top left menu", "Toggle the top left menu": "Toggle the top left menu",
"Close dialog or context menu": "Close dialog or context menu", "Close dialog or context menu": "Close dialog or context menu",
"Activate selected button": "Activate selected button", "Activate selected button": "Activate selected button",
"Toggle right panel": "Toggle right panel",
"Toggle this dialog": "Toggle this dialog", "Toggle this dialog": "Toggle this dialog",
"Move autocomplete selection up/down": "Move autocomplete selection up/down", "Move autocomplete selection up/down": "Move autocomplete selection up/down",
"Cancel autocomplete": "Cancel autocomplete", "Cancel autocomplete": "Cancel autocomplete",

View file

@ -35,6 +35,12 @@ const INITIAL_STATE = {
const GROUP_PHASES = Object.keys(RIGHT_PANEL_PHASES).filter(k => k.startsWith("Group")); const GROUP_PHASES = Object.keys(RIGHT_PANEL_PHASES).filter(k => k.startsWith("Group"));
const MEMBER_INFO_PHASES = [
RIGHT_PANEL_PHASES.RoomMemberInfo,
RIGHT_PANEL_PHASES.Room3pidMemberInfo,
RIGHT_PANEL_PHASES.EncryptionPanel,
];
/** /**
* A class for tracking the state of the right panel between layouts and * A class for tracking the state of the right panel between layouts and
* sessions. * sessions.
@ -114,62 +120,69 @@ export default class RightPanelStore extends Store {
} }
__onDispatch(payload) { __onDispatch(payload) {
if (payload.action === 'view_room' || payload.action === 'view_group') { switch (payload.action) {
// Reset to the member list if we're viewing member info case 'view_room':
const memberInfoPhases = [ case 'view_group':
RIGHT_PANEL_PHASES.RoomMemberInfo, // Reset to the member list if we're viewing member info
RIGHT_PANEL_PHASES.Room3pidMemberInfo, if (MEMBER_INFO_PHASES.includes(this._state.lastRoomPhase)) {
RIGHT_PANEL_PHASES.EncryptionPanel, this._setState({lastRoomPhase: RIGHT_PANEL_PHASES.RoomMemberList, lastRoomPhaseParams: {}});
]; }
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});
}
break;
case 'set_right_panel_phase': {
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 && !payload.refireParams) {
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 || {}),
});
break;
} }
// Do the same for groups case 'toggle_right_panel':
if (this._state.lastGroupPhase === RIGHT_PANEL_PHASES.GroupMemberInfo) { if (payload.type === "room") {
this._setState({lastGroupPhase: RIGHT_PANEL_PHASES.GroupMemberList}); this._setState({ showRoomPanel: !this._state.showRoomPanel });
} } else { // group
this._setState({ showGroupPanel: !this._state.showGroupPanel });
}
break;
} }
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,
showGroupPanel: true,
});
}
} else {
if (targetPhase === this._state.lastRoomPhase && !payload.refireParams) {
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 { static getSharedInstance(): RightPanelStore {