Fix narrow mode composer buttons for polls labs (#7386)

This commit is contained in:
Michael Telatynski 2021-12-15 16:15:09 +00:00 committed by GitHub
parent b174cc8963
commit 3c9c82ee0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 54 deletions

View file

@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { createRef } from 'react'; import React, { ComponentProps, createRef } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { MatrixEvent, IEventRelation } from "matrix-js-sdk/src/models/event"; import { MatrixEvent, IEventRelation } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
@ -80,10 +80,22 @@ function SendButton(props: ISendButtonProps) {
); );
} }
interface IEmojiButtonProps { interface ICollapsibleButtonProps extends ComponentProps<typeof AccessibleTooltipButton> {
narrowMode: boolean;
title: string;
}
const CollapsibleButton = ({ narrowMode, title, ...props }: ICollapsibleButtonProps) => {
return <AccessibleTooltipButton
{...props}
title={narrowMode ? undefined : title}
label={narrowMode ? title : undefined}
/>;
};
interface IEmojiButtonProps extends Pick<ICollapsibleButtonProps, "narrowMode"> {
addEmoji: (unicode: string) => boolean; addEmoji: (unicode: string) => boolean;
menuPosition: AboveLeftOf; menuPosition: AboveLeftOf;
narrowMode: boolean;
} }
const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition, narrowMode }) => { const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition, narrowMode }) => {
@ -108,18 +120,18 @@ const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition, narr
// TODO: replace ContextMenuTooltipButton with a unified representation of // TODO: replace ContextMenuTooltipButton with a unified representation of
// the header buttons and the right panel buttons // the header buttons and the right panel buttons
return <React.Fragment> return <React.Fragment>
<AccessibleTooltipButton <CollapsibleButton
className={className} className={className}
onClick={openMenu} onClick={openMenu}
title={!narrowMode && _t('Emoji picker')} narrowMode={narrowMode}
label={narrowMode ? _t("Add emoji") : null} title={_t("Add emoji")}
/> />
{ contextMenu } { contextMenu }
</React.Fragment>; </React.Fragment>;
}; };
interface ILocationButtonProps { interface ILocationButtonProps extends Pick<ICollapsibleButtonProps, "narrowMode"> {
room: Room; room: Room;
shareLocation: (uri: string, ts: number, type: LocationShareType, description: string) => boolean; shareLocation: (uri: string, ts: number, type: LocationShareType, description: string) => boolean;
menuPosition: AboveLeftOf; menuPosition: AboveLeftOf;
@ -148,11 +160,11 @@ const LocationButton: React.FC<ILocationButtonProps> = ({ shareLocation, menuPos
// TODO: replace ContextMenuTooltipButton with a unified representation of // TODO: replace ContextMenuTooltipButton with a unified representation of
// the header buttons and the right panel buttons // the header buttons and the right panel buttons
return <React.Fragment> return <React.Fragment>
<AccessibleTooltipButton <CollapsibleButton
className={className} className={className}
onClick={openMenu} onClick={openMenu}
title={!narrowMode && _t('Share location')} narrowMode={narrowMode}
label={narrowMode ? _t('Share location') : null} title={_t("Share location")}
/> />
{ contextMenu } { contextMenu }
@ -233,7 +245,7 @@ class UploadButton extends React.Component<IUploadButtonProps> {
} }
} }
interface IPollButtonProps { interface IPollButtonProps extends Pick<ICollapsibleButtonProps, "narrowMode"> {
room: Room; room: Room;
} }
@ -265,10 +277,11 @@ class PollButton extends React.PureComponent<IPollButtonProps> {
render() { render() {
return ( return (
<AccessibleTooltipButton <CollapsibleButton
className="mx_MessageComposer_button mx_MessageComposer_poll" className="mx_MessageComposer_button mx_MessageComposer_poll"
onClick={this.onCreateClick} onClick={this.onCreateClick}
title={_t('Create poll')} narrowMode={this.props.narrowMode}
title={_t("Create poll")}
/> />
); );
} }
@ -567,16 +580,12 @@ export default class MessageComposer extends React.Component<IProps, IState> {
if (!this.state.haveRecording) { if (!this.state.haveRecording) {
if (this.state.showPollsButton) { if (this.state.showPollsButton) {
buttons.push( buttons.push(
<PollButton key="polls" room={this.props.room} />, <PollButton key="polls" room={this.props.room} narrowMode={this.state.narrowMode} />,
); );
} }
uploadButtonIndex = buttons.length; uploadButtonIndex = buttons.length;
buttons.push( buttons.push(
<UploadButton <UploadButton key="controls_upload" roomId={this.props.room.roomId} relation={this.props.relation} />,
key="controls_upload"
roomId={this.props.room.roomId}
relation={this.props.relation}
/>,
); );
if (SettingsStore.getValue("feature_location_share")) { if (SettingsStore.getValue("feature_location_share")) {
buttons.push( buttons.push(
@ -610,53 +619,58 @@ export default class MessageComposer extends React.Component<IProps, IState> {
/>, />,
); );
} }
// XXX: the recording UI does not work well in narrow mode, so we hide this button for now
if (!this.state.haveRecording && !this.state.narrowMode) { if (!this.state.haveRecording && !this.state.narrowMode) {
buttons.push( buttons.push(
<AccessibleTooltipButton <CollapsibleButton
key="voice_message_send" key="voice_message_send"
className="mx_MessageComposer_button mx_MessageComposer_voiceMessage" className="mx_MessageComposer_button mx_MessageComposer_voiceMessage"
onClick={() => this.voiceRecordingButton.current?.onRecordStartEndClick()} onClick={() => this.voiceRecordingButton.current?.onRecordStartEndClick()}
title={_t("Send voice message")} title={_t("Send voice message")}
narrowMode={this.state.narrowMode}
/>, />,
); );
} }
if (!this.state.narrowMode) { if (!this.state.narrowMode) {
return buttons; return buttons;
} else {
const classnames = classNames({
mx_MessageComposer_button: true,
mx_MessageComposer_buttonMenu: true,
mx_MessageComposer_closeButtonMenu: this.state.isMenuOpen,
});
return <>
{ buttons[uploadButtonIndex] }
<AccessibleTooltipButton
className={classnames}
onClick={this.toggleButtonMenu}
title={_t("More options")}
tooltip={false}
/>
{ this.state.isMenuOpen && (
<ContextMenu
onFinished={this.toggleButtonMenu}
{...menuPosition}
menuPaddingRight={10}
menuPaddingTop={5}
menuPaddingBottom={5}
menuWidth={150}
wrapperClassName="mx_MessageComposer_Menu"
>
{ buttons.slice(1).map((button, index) => (
<MenuItem className="mx_CallContextMenu_item" key={index} onClick={this.toggleButtonMenu}>
{ button }
</MenuItem>
)) }
</ContextMenu>
) }
</>;
} }
const classnames = classNames({
mx_MessageComposer_button: true,
mx_MessageComposer_buttonMenu: true,
mx_MessageComposer_closeButtonMenu: this.state.isMenuOpen,
});
// we render the uploadButton at top level as it is a very common interaction, splice it out of the rest
const [uploadButton] = buttons.splice(uploadButtonIndex, 1);
return <>
{ uploadButton }
<AccessibleTooltipButton
className={classnames}
onClick={this.toggleButtonMenu}
title={_t("More options")}
tooltip={false}
/>
{ this.state.isMenuOpen && (
<ContextMenu
onFinished={this.toggleButtonMenu}
{...menuPosition}
menuPaddingRight={10}
menuPaddingTop={5}
menuPaddingBottom={5}
menuWidth={150}
wrapperClassName="mx_MessageComposer_Menu"
>
{ buttons.map((button, index) => (
<MenuItem className="mx_CallContextMenu_item" key={index} onClick={this.toggleButtonMenu}>
{ button }
</MenuItem>
)) }
</ContextMenu>
) }
</>;
} }
render() { render() {

View file

@ -1649,7 +1649,6 @@
"Filter room members": "Filter room members", "Filter room members": "Filter room members",
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)",
"Send message": "Send message", "Send message": "Send message",
"Emoji picker": "Emoji picker",
"Add emoji": "Add emoji", "Add emoji": "Add emoji",
"Share location": "Share location", "Share location": "Share location",
"Upload file": "Upload file", "Upload file": "Upload file",