Support CTRL+I for opening TopLeftMenu
This commit is contained in:
parent
f1aa2875e1
commit
c5757d8303
4 changed files with 45 additions and 5 deletions
|
@ -322,6 +322,14 @@ const LoggedInView = React.createClass({
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KeyCode.KEY_I:
|
||||||
|
if (ctrlCmdOnly) {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'toggle_top_left_menu',
|
||||||
|
});
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled) {
|
if (handled) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import BaseAvatar from '../views/avatars/BaseAvatar';
|
||||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||||
import Avatar from '../../Avatar';
|
import Avatar from '../../Avatar';
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
|
import dis from "../../dispatcher";
|
||||||
|
|
||||||
const AVATAR_SIZE = 28;
|
const AVATAR_SIZE = 28;
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ export default class TopLeftMenuButton extends React.Component {
|
||||||
super();
|
super();
|
||||||
this.state = {
|
this.state = {
|
||||||
menuDisplayed: false,
|
menuDisplayed: false,
|
||||||
|
menuFunctions: null, // should be { close: fn }
|
||||||
profileInfo: null,
|
profileInfo: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +61,8 @@ export default class TopLeftMenuButton extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
this._dispatcherRef = dis.register(this.onAction);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const profileInfo = await this._getProfileInfo();
|
const profileInfo = await this._getProfileInfo();
|
||||||
this.setState({profileInfo});
|
this.setState({profileInfo});
|
||||||
|
@ -68,6 +72,17 @@ export default class TopLeftMenuButton extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
dis.unregister(this._dispatcherRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
onAction = (payload) => {
|
||||||
|
// For accessibility
|
||||||
|
if (payload.action === "toggle_top_left_menu") {
|
||||||
|
if (this._buttonRef) this._buttonRef.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
_getDisplayName() {
|
_getDisplayName() {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return _t("Guest");
|
return _t("Guest");
|
||||||
|
@ -88,7 +103,13 @@ export default class TopLeftMenuButton extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AccessibleButton className="mx_TopLeftMenuButton" onClick={this.onToggleMenu}>
|
<AccessibleButton
|
||||||
|
className="mx_TopLeftMenuButton"
|
||||||
|
role="button"
|
||||||
|
onClick={this.onToggleMenu}
|
||||||
|
inputRef={(r) => this._buttonRef = r}
|
||||||
|
aria-label={_t("Your profile")}
|
||||||
|
>
|
||||||
<BaseAvatar
|
<BaseAvatar
|
||||||
idName={MatrixClientPeg.get().getUserId()}
|
idName={MatrixClientPeg.get().getUserId()}
|
||||||
name={name}
|
name={name}
|
||||||
|
@ -98,7 +119,7 @@ export default class TopLeftMenuButton extends React.Component {
|
||||||
resizeMethod="crop"
|
resizeMethod="crop"
|
||||||
/>
|
/>
|
||||||
{ nameElement }
|
{ nameElement }
|
||||||
<span className="mx_TopLeftMenuButton_chevron"></span>
|
<span className="mx_TopLeftMenuButton_chevron" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -107,20 +128,25 @@ export default class TopLeftMenuButton extends React.Component {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (this.state.menuDisplayed && this.state.menuFunctions) {
|
||||||
|
this.state.menuFunctions.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const elementRect = e.currentTarget.getBoundingClientRect();
|
const elementRect = e.currentTarget.getBoundingClientRect();
|
||||||
const x = elementRect.left;
|
const x = elementRect.left;
|
||||||
const y = elementRect.top + elementRect.height;
|
const y = elementRect.top + elementRect.height;
|
||||||
|
|
||||||
ContextualMenu.createMenu(TopLeftMenu, {
|
const menuFunctions = ContextualMenu.createMenu(TopLeftMenu, {
|
||||||
chevronFace: "none",
|
chevronFace: "none",
|
||||||
left: x,
|
left: x,
|
||||||
top: y,
|
top: y,
|
||||||
userId: MatrixClientPeg.get().getUserId(),
|
userId: MatrixClientPeg.get().getUserId(),
|
||||||
displayName: this._getDisplayName(),
|
displayName: this._getDisplayName(),
|
||||||
onFinished: () => {
|
onFinished: () => {
|
||||||
this.setState({ menuDisplayed: false });
|
this.setState({ menuDisplayed: false, menuFunctions: null });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.setState({ menuDisplayed: true });
|
this.setState({ menuDisplayed: true, menuFunctions });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,10 @@ export default function AccessibleButton(props) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass through the ref - used for keyboard shortcut access to some buttons
|
||||||
|
restProps.ref = restProps.inputRef;
|
||||||
|
delete restProps.inputRef;
|
||||||
|
|
||||||
restProps.tabIndex = restProps.tabIndex || "0";
|
restProps.tabIndex = restProps.tabIndex || "0";
|
||||||
restProps.role = "button";
|
restProps.role = "button";
|
||||||
restProps.className = (restProps.className ? restProps.className + " " : "") +
|
restProps.className = (restProps.className ? restProps.className + " " : "") +
|
||||||
|
@ -89,6 +93,7 @@ export default function AccessibleButton(props) {
|
||||||
*/
|
*/
|
||||||
AccessibleButton.propTypes = {
|
AccessibleButton.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
|
inputRef: PropTypes.func,
|
||||||
element: PropTypes.string,
|
element: PropTypes.string,
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
|
|
@ -1493,6 +1493,7 @@
|
||||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
||||||
"Failed to load timeline position": "Failed to load timeline position",
|
"Failed to load timeline position": "Failed to load timeline position",
|
||||||
"Guest": "Guest",
|
"Guest": "Guest",
|
||||||
|
"Your profile": "Your profile",
|
||||||
"Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others",
|
"Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others",
|
||||||
"Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s",
|
"Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s",
|
||||||
"Uploading %(filename)s and %(count)s others|one": "Uploading %(filename)s and %(count)s other",
|
"Uploading %(filename)s and %(count)s others|one": "Uploading %(filename)s and %(count)s other",
|
||||||
|
|
Loading…
Reference in a new issue