Rework custom status context menu

This updates the custom status context menu to match the latest comps.  A single
button is used for setting / clearing, depending on what is appropriate.

The state logic is also changed to depend on events and storage from js-sdk for
the committed status message.  This makes it easy to distinguish the value being
edited from what's currently committed.
This commit is contained in:
J. Ryan Stinnett 2019-01-14 16:41:14 -06:00
parent fc3055f541
commit 5b88b64950
6 changed files with 103 additions and 77 deletions

View file

@ -19,7 +19,6 @@ import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
import AccessibleButton from '../elements/AccessibleButton';
import classNames from 'classnames';
export default class StatusMessageContextMenu extends React.Component {
static propTypes = {
@ -31,13 +30,42 @@ export default class StatusMessageContextMenu extends React.Component {
super(props, context);
this.state = {
message: props.user ? props.user._unstable_statusMessage : "",
message: this.comittedStatusMessage,
};
}
componentWillMount() {
const { user } = this.props;
if (!user) {
return;
}
user.on("User._unstable_statusMessage", this._onStatusMessageCommitted);
}
componentWillUmount() {
const { user } = this.props;
if (!user) {
return;
}
user.removeListener(
"User._unstable_statusMessage",
this._onStatusMessageCommitted,
);
}
get comittedStatusMessage() {
return this.props.user ? this.props.user._unstable_statusMessage : "";
}
_onStatusMessageCommitted = () => {
// The `User` object has observed a status message change.
this.setState({
message: this.comittedStatusMessage,
});
};
_onClearClick = async (e) => {
await MatrixClientPeg.get()._unstable_setStatusMessage("");
this.setState({message: ""});
};
_onSubmit = (e) => {
@ -46,41 +74,49 @@ export default class StatusMessageContextMenu extends React.Component {
};
_onStatusChange = (e) => {
this.setState({message: e.target.value});
// The input field's value was changed.
this.setState({
message: e.target.value,
});
};
render() {
const formSubmitClasses = classNames({
"mx_StatusMessageContextMenu_submit": true,
"mx_StatusMessageContextMenu_submitFaded": !this.state.message, // no message == faded
});
let actionButton;
if (this.comittedStatusMessage) {
if (this.state.message === this.comittedStatusMessage) {
actionButton = <AccessibleButton className="mx_StatusMessageContextMenu_clear"
onClick={this._onClearClick}
>
<span>{_t("Clear status")}</span>
</AccessibleButton>;
} else {
actionButton = <AccessibleButton className="mx_StatusMessageContextMenu_submit"
onClick={this._onSubmit}
>
<span>{_t("Update status")}</span>
</AccessibleButton>;
}
} else {
actionButton = <AccessibleButton className="mx_StatusMessageContextMenu_submit"
disabled={!this.state.message} onClick={this._onSubmit}
>
<span>{_t("Set status")}</span>
</AccessibleButton>;
}
const form = <form className="mx_StatusMessageContextMenu_form" onSubmit={this._onSubmit} autoComplete="off">
<input type="text" key="message" placeholder={_t("Set a new status...")} autoFocus={true}
className="mx_StatusMessageContextMenu_message"
value={this.state.message} onChange={this._onStatusChange} maxLength="60" />
<AccessibleButton onClick={this._onSubmit} element="div" className={formSubmitClasses}>
<img src="img/icons-checkmark.svg" width="22" height="22" />
</AccessibleButton>
const form = <form className="mx_StatusMessageContextMenu_form"
autoComplete="off" onSubmit={this._onSubmit}
>
<input type="text" className="mx_StatusMessageContextMenu_message"
key="message" placeholder={_t("Set a new status...")}
autoFocus={true} maxLength="60" value={this.state.message}
onChange={this._onStatusChange}
/>
{actionButton}
</form>;
const clearIcon = this.state.message ? "img/cancel-red.svg" : "img/cancel.svg";
const clearButton = <AccessibleButton onClick={this._onClearClick} disabled={!this.state.message}
className="mx_StatusMessageContextMenu_clear">
<img src={clearIcon} alt={_t('Clear status')} width="12" height="12"
className="mx_filterFlipColor mx_StatusMessageContextMenu_clearIcon" />
<span>{_t("Clear status")}</span>
</AccessibleButton>;
const menuClasses = classNames({
"mx_StatusMessageContextMenu": true,
"mx_StatusMessageContextMenu_hasStatus": this.state.message,
});
return <div className={menuClasses}>
return <div className="mx_StatusMessageContextMenu">
{ form }
<hr />
{ clearButton }
</div>;
}
}