Make label clickable on narrow mode context menu
This commit is contained in:
parent
646ef197fe
commit
bbf66a0011
4 changed files with 53 additions and 31 deletions
|
@ -186,11 +186,14 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposer_button {
|
.mx_MessageComposer_button {
|
||||||
|
--size: 26px;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 26px;
|
height: var(--size);
|
||||||
width: 26px;
|
line-height: var(--size);
|
||||||
|
width: auto;
|
||||||
|
padding-left: calc(var(--size) + 5px);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -207,8 +210,21 @@ limitations under the License.
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 0;
|
||||||
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba($accent-color, 0.1);
|
&::after {
|
||||||
|
background: rgba($accent-color, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
background-color: $accent-color;
|
background-color: $accent-color;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
interface ITooltipProps extends React.ComponentProps<typeof AccessibleButton> {
|
interface ITooltipProps extends React.ComponentProps<typeof AccessibleButton> {
|
||||||
title: string;
|
title: string;
|
||||||
tooltip?: React.ReactNode;
|
tooltip?: React.ReactNode;
|
||||||
|
label?: React.ReactNode;
|
||||||
tooltipClassName?: string;
|
tooltipClassName?: string;
|
||||||
forceHide?: boolean;
|
forceHide?: boolean;
|
||||||
yOffset?: number;
|
yOffset?: number;
|
||||||
|
@ -84,7 +85,8 @@ export default class AccessibleTooltipButton extends React.PureComponent<IToolti
|
||||||
aria-label={title}
|
aria-label={title}
|
||||||
>
|
>
|
||||||
{ children }
|
{ children }
|
||||||
{ tip }
|
{ this.props.label }
|
||||||
|
{ (tooltip || title) && tip }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,13 @@ function SendButton(props: ISendButtonProps) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmojiButton = ({ addEmoji, menuPosition }) => {
|
interface IEmojiButtonProps {
|
||||||
|
addEmoji: (unicode: string) => boolean;
|
||||||
|
menuPosition: any; // TODO: Types
|
||||||
|
narrowMode: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition, narrowMode }) => {
|
||||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
||||||
|
|
||||||
let contextMenu;
|
let contextMenu;
|
||||||
|
@ -103,12 +109,11 @@ const EmojiButton = ({ addEmoji, menuPosition }) => {
|
||||||
// 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>
|
||||||
<ContextMenuTooltipButton
|
<AccessibleTooltipButton
|
||||||
className={className}
|
className={className}
|
||||||
onClick={openMenu}
|
onClick={openMenu}
|
||||||
isExpanded={menuDisplayed}
|
title={!narrowMode && _t('Emoji picker')}
|
||||||
title={_t('Emoji picker')}
|
label={narrowMode && _t("Send an emoji")}
|
||||||
inputRef={button}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{ contextMenu }
|
{ contextMenu }
|
||||||
|
@ -364,11 +369,12 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private addEmoji(emoji: string) {
|
private addEmoji(emoji: string): boolean {
|
||||||
dis.dispatch<ComposerInsertPayload>({
|
dis.dispatch<ComposerInsertPayload>({
|
||||||
action: Action.ComposerInsert,
|
action: Action.ComposerInsert,
|
||||||
text: emoji,
|
text: emoji,
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sendMessage = async () => {
|
private sendMessage = async () => {
|
||||||
|
@ -424,32 +430,34 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderButtons(menuPosition): JSX.Element | JSX.Element[] {
|
private renderButtons(menuPosition): JSX.Element | JSX.Element[] {
|
||||||
const buttons = new Map<string, JSX.Element>();
|
const buttons: JSX.Element[] = [];
|
||||||
if (!this.state.haveRecording) {
|
if (!this.state.haveRecording) {
|
||||||
buttons.set(
|
buttons.push(
|
||||||
_t("Send a file"),
|
|
||||||
<UploadButton key="controls_upload" roomId={this.props.room.roomId} />,
|
<UploadButton key="controls_upload" roomId={this.props.room.roomId} />,
|
||||||
);
|
);
|
||||||
buttons.set(
|
buttons.push(
|
||||||
_t("Add emoji"),
|
<EmojiButton key="emoji_button" addEmoji={this.addEmoji} menuPosition={menuPosition} narrowMode={this.state.narrowMode} />,
|
||||||
<EmojiButton key="emoji_button" addEmoji={this.addEmoji} menuPosition={menuPosition} />,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.shouldShowStickerPicker()) {
|
if (this.shouldShowStickerPicker()) {
|
||||||
buttons.set(
|
let title;
|
||||||
_t("Send a sticker"),
|
if (!this.state.narrowMode) {
|
||||||
|
title = this.state.showStickers ? _t("Hide Stickers") : _t("Show Stickers");
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.push(
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
id='stickersButton'
|
id='stickersButton'
|
||||||
key="controls_stickers"
|
key="controls_stickers"
|
||||||
className="mx_MessageComposer_button mx_MessageComposer_stickers"
|
className="mx_MessageComposer_button mx_MessageComposer_stickers"
|
||||||
onClick={() => this.showStickers(!this.state.showStickers)}
|
onClick={() => this.showStickers(!this.state.showStickers)}
|
||||||
title={this.state.showStickers ? _t("Hide Stickers") : _t("Show Stickers")}
|
title={title}
|
||||||
|
label={this.state.narrowMode && _t("Send a sticker")}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!this.state.haveRecording && !this.state.narrowMode) {
|
if (!this.state.haveRecording && !this.state.narrowMode) {
|
||||||
buttons.set(
|
buttons.push(
|
||||||
_t("Send a voice message"),
|
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className="mx_MessageComposer_button mx_MessageComposer_voiceMessage"
|
className="mx_MessageComposer_button mx_MessageComposer_voiceMessage"
|
||||||
onClick={() => this.voiceRecordingButton?.onRecordStartEndClick()}
|
onClick={() => this.voiceRecordingButton?.onRecordStartEndClick()}
|
||||||
|
@ -458,9 +466,8 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonsArray = Array.from(buttons.values());
|
|
||||||
if (!this.state.narrowMode) {
|
if (!this.state.narrowMode) {
|
||||||
return buttonsArray;
|
return buttons;
|
||||||
} else {
|
} else {
|
||||||
const classnames = classNames({
|
const classnames = classNames({
|
||||||
mx_MessageComposer_button: true,
|
mx_MessageComposer_button: true,
|
||||||
|
@ -469,7 +476,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
});
|
});
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{ buttonsArray[0] }
|
{ buttons[0] }
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className={classnames}
|
className={classnames}
|
||||||
onClick={this.toggleButtonMenu}
|
onClick={this.toggleButtonMenu}
|
||||||
|
@ -486,10 +493,9 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
||||||
menuWidth={150}
|
menuWidth={150}
|
||||||
wrapperClassName="mx_MessageComposer_Menu"
|
wrapperClassName="mx_MessageComposer_Menu"
|
||||||
>
|
>
|
||||||
{ Array.from(buttons).slice(1).map(([label, button]) => (
|
{ buttons.slice(1).map((button, index) => (
|
||||||
<MenuItem className="mx_CallContextMenu_item" key={label} onClick={this.toggleButtonMenu}>
|
<MenuItem className="mx_CallContextMenu_item" key={index} onClick={this.toggleButtonMenu}>
|
||||||
{ button }
|
{ button }
|
||||||
{ label }
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)) }
|
)) }
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
|
|
|
@ -1559,6 +1559,7 @@
|
||||||
"%(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",
|
"Emoji picker": "Emoji picker",
|
||||||
|
"Send an emoji": "Send an emoji",
|
||||||
"Upload file": "Upload file",
|
"Upload file": "Upload file",
|
||||||
"Reply to encrypted thread…": "Reply to encrypted thread…",
|
"Reply to encrypted thread…": "Reply to encrypted thread…",
|
||||||
"Reply to thread…": "Reply to thread…",
|
"Reply to thread…": "Reply to thread…",
|
||||||
|
@ -1566,12 +1567,9 @@
|
||||||
"Send a reply…": "Send a reply…",
|
"Send a reply…": "Send a reply…",
|
||||||
"Send an encrypted message…": "Send an encrypted message…",
|
"Send an encrypted message…": "Send an encrypted message…",
|
||||||
"Send a message…": "Send a message…",
|
"Send a message…": "Send a message…",
|
||||||
"Send a file": "Send a file",
|
|
||||||
"Add emoji": "Add emoji",
|
|
||||||
"Send a sticker": "Send a sticker",
|
|
||||||
"Hide Stickers": "Hide Stickers",
|
"Hide Stickers": "Hide Stickers",
|
||||||
"Show Stickers": "Show Stickers",
|
"Show Stickers": "Show Stickers",
|
||||||
"Send a voice message": "Send a voice message",
|
"Send an sticker": "Send an sticker",
|
||||||
"Send voice message": "Send voice message",
|
"Send voice message": "Send voice message",
|
||||||
"More options": "More options",
|
"More options": "More options",
|
||||||
"The conversation continues here.": "The conversation continues here.",
|
"The conversation continues here.": "The conversation continues here.",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue