Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Simplify Composer buttons #7678

Merged
merged 14 commits into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions res/css/views/rooms/_MessageComposer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,6 @@ limitations under the License.
mask-image: url('$(res)/img/image-view/more.svg');
}

.mx_MessageComposer_closeButtonMenu::before {
transform: rotate(90deg);
transform-origin: center;
}

.mx_MessageComposer_sendMessage {
cursor: pointer;
position: relative;
Expand Down
4 changes: 1 addition & 3 deletions src/components/views/location/LocationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,11 @@ export const LocationButton: React.FC<IProps> = ({ roomId, sender, menuPosition
},
);

// TODO: replace ContextMenuTooltipButton with a unified representation of
// the header buttons and the right panel buttons
return <React.Fragment>
<CollapsibleButton
className={className}
onClick={openMenu}
title={_t("Share location")}
title={_t("Location")}
/>

{ contextMenu }
Expand Down
13 changes: 10 additions & 3 deletions src/components/views/rooms/CollapsibleButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,25 @@ interface ICollapsibleButtonProps extends ComponentProps<typeof MenuItem> {
title: string;
}

export const CollapsibleButton = ({ title, className, ...props }: ICollapsibleButtonProps) => {
export const CollapsibleButton = ({ title, children, className, ...props }: ICollapsibleButtonProps) => {
const inOverflowMenu = !!useContext(OverflowMenuContext);
if (inOverflowMenu) {
return <MenuItem
{...props}
className={classNames("mx_CallContextMenu_item", className)}
>
{ title }
{ children }
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
</MenuItem>;
} else {
return <AccessibleTooltipButton
{...props}
title={title}
className={className}
>
{ children }
</AccessibleTooltipButton>;
}
andybalaam marked this conversation as resolved.
Show resolved Hide resolved

return <AccessibleTooltipButton {...props} title={title} className={className} />;
};

export default CollapsibleButton;
97 changes: 43 additions & 54 deletions src/components/views/rooms/MessageComposerButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,53 +59,47 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
const matrixClient: MatrixClient = useContext(MatrixClientContext);
const { room, roomId } = useContext(RoomContext);

return (
props.haveRecording
? null
: props.narrowMode
? narrowMode(props, room, roomId, matrixClient)
: wideMode(props, room, roomId, matrixClient)
);
};
if (props.haveRecording) {
return null;
}

function wideMode(
props: IProps,
room: Room,
roomId: string,
matrixClient: MatrixClient,
): ReactElement {
return <>
{ pollButton(props, room) }
{ uploadButton(props, roomId) }
{ showLocationButton(props, room, roomId, matrixClient) }
{ emojiButton(props) }
{ showStickersButton(props) }
{ voiceRecordingButton(props) }
</>;
}
let mainButtons: ReactElement[];
let moreButtons: ReactElement[];
if (props.narrowMode) {
mainButtons = [
emojiButton(props),
];
moreButtons = [
uploadButton(props, roomId),
showStickersButton(props),
voiceRecordingButton(props),
pollButton(room),
showLocationButton(props, room, roomId, matrixClient),
];
} else {
mainButtons = [
emojiButton(props),
uploadButton(props, roomId),
];
moreButtons = [
showStickersButton(props),
voiceRecordingButton(props),
pollButton(room),
showLocationButton(props, room, roomId, matrixClient),
];
}

mainButtons = mainButtons.filter((x: ReactElement) => x);
moreButtons = moreButtons.filter((x: ReactElement) => x);

function narrowMode(
props: IProps,
room: Room,
roomId: string,
matrixClient: MatrixClient,
): ReactElement {
const moreOptionsClasses = classNames({
mx_MessageComposer_button: true,
mx_MessageComposer_buttonMenu: true,
mx_MessageComposer_closeButtonMenu: props.isMenuOpen,
});

const moreButtons = [
pollButton(props, room),
showLocationButton(props, room, roomId, matrixClient),
emojiButton(props),
showStickersButton(props),
voiceRecordingButton(props),
].filter(x => x);

return <>
{ uploadButton(props, roomId) }
{ mainButtons }
<AccessibleTooltipButton
className={moreOptionsClasses}
onClick={props.toggleButtonMenu}
Expand All @@ -123,7 +117,7 @@ function narrowMode(
</ContextMenu>
) }
</>;
}
};

function emojiButton(props: IProps): ReactElement {
return <EmojiButton
Expand Down Expand Up @@ -174,7 +168,7 @@ const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition }) =>
<CollapsibleButton
className={className}
onClick={openMenu}
title={_t("Add emoji")}
title={_t("Emoji")}
/>

{ contextMenu }
Expand Down Expand Up @@ -219,7 +213,7 @@ class UploadButton extends React.Component<IUploadButtonProps> {
dis.dispatch({ action: 'require_registration' });
return;
}
this.uploadInput.current.click();
this.uploadInput.current?.click();
};

private onUploadFileInputChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -250,10 +244,10 @@ class UploadButton extends React.Component<IUploadButtonProps> {
render() {
const uploadInputStyle = { display: 'none' };
return (
<AccessibleTooltipButton
<CollapsibleButton
className="mx_MessageComposer_button mx_MessageComposer_upload"
onClick={this.onUploadClick}
title={_t('Upload file')}
title={_t('Attachment')}
>
<input
andybalaam marked this conversation as resolved.
Show resolved Hide resolved
ref={this.uploadInput}
Expand All @@ -262,7 +256,7 @@ class UploadButton extends React.Component<IUploadButtonProps> {
multiple
onChange={this.onUploadFileInputChange}
/>
</AccessibleTooltipButton>
</CollapsibleButton>
);
}
}
Expand All @@ -275,13 +269,7 @@ function showStickersButton(props: IProps): ReactElement {
key="controls_stickers"
className="mx_MessageComposer_button mx_MessageComposer_stickers"
onClick={() => props.setStickerPickerOpen(!props.isStickerPickerOpen)}
title={
props.narrowMode
? _t("Send a sticker")
: props.isStickerPickerOpen
? _t("Hide Stickers")
: _t("Show Stickers")
}
title={props.isStickerPickerOpen ? _t("Hide stickers") : _t("Sticker")}
/>
: null
);
Expand All @@ -296,12 +284,12 @@ function voiceRecordingButton(props: IProps): ReactElement {
key="voice_message_send"
className="mx_MessageComposer_button mx_MessageComposer_voiceMessage"
onClick={props.onRecordStartEndClick}
title={_t("Send voice message")}
title={_t("Voice Message")}
/>
);
}

function pollButton(props: IProps, room: Room): ReactElement {
function pollButton(room: Room): ReactElement {
return <PollButton key="polls" room={room} />;
}

Expand All @@ -311,6 +299,7 @@ interface IPollButtonProps {

class PollButton extends React.PureComponent<IPollButtonProps> {
static contextType = OverflowMenuContext;
public context!: React.ContextType<typeof OverflowMenuContext>;

private onCreateClick = () => {
this.context?.(); // close overflow menu
Expand Down Expand Up @@ -350,7 +339,7 @@ class PollButton extends React.PureComponent<IPollButtonProps> {
<CollapsibleButton
className="mx_MessageComposer_button mx_MessageComposer_poll"
onClick={this.onCreateClick}
title={_t("Create poll")}
title={_t("Poll")}
/>
);
}
Expand Down
17 changes: 8 additions & 9 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1694,13 +1694,12 @@
"You do not have permission to post to this room": "You do not have permission to post to this room",
"%(seconds)ss left": "%(seconds)ss left",
"Send voice message": "Send voice message",
"Add emoji": "Add emoji",
"Upload file": "Upload file",
"Send a sticker": "Send a sticker",
"Hide Stickers": "Hide Stickers",
"Show Stickers": "Show Stickers",
"Emoji": "Emoji",
"Hide stickers": "Hide stickers",
"Sticker": "Sticker",
"Voice Message": "Voice Message",
"You do not have permission to start polls in this room.": "You do not have permission to start polls in this room.",
"Create poll": "Create poll",
"Poll": "Poll",
"Bold": "Bold",
"Italics": "Italics",
"Strikethrough": "Strikethrough",
Expand Down Expand Up @@ -2095,7 +2094,6 @@
"Invalid file%(extra)s": "Invalid file%(extra)s",
"Error decrypting image": "Error decrypting image",
"Show image": "Show image",
"Sticker": "Sticker",
"Image": "Image",
"Join the conference at the top of this room": "Join the conference at the top of this room",
"Join the conference from the room information card on the right": "Join the conference from the room information card on the right",
Expand Down Expand Up @@ -2153,10 +2151,11 @@
"Submit logs": "Submit logs",
"Can't load this message": "Can't load this message",
"toggle event": "toggle event",
"Share location": "Share location",
"Location": "Location",
"We couldn’t send your location": "We couldn’t send your location",
"Element could not send your location. Please try again later.": "Element could not send your location. Please try again later.",
"Could not fetch location": "Could not fetch location",
"Share location": "Share location",
"Element was denied permission to fetch your location. Please allow location access in your browser settings.": "Element was denied permission to fetch your location. Please allow location access in your browser settings.",
"Failed to fetch your location. Please try again later.": "Failed to fetch your location. Please try again later.",
"Timed out trying to fetch your location. Please try again later.": "Timed out trying to fetch your location. Please try again later.",
Expand Down Expand Up @@ -2295,6 +2294,7 @@
"%(oneUser)schanged the server ACLs %(count)s times|one": "%(oneUser)schanged the server ACLs",
"%(severalUsers)schanged the <a>pinned messages</a> for the room %(count)s times.|other": "%(severalUsers)schanged the <a>pinned messages</a> for the room %(count)s times.",
"%(oneUser)schanged the <a>pinned messages</a> for the room %(count)s times.|other": "%(oneUser)schanged the <a>pinned messages</a> for the room %(count)s times.",
"Create poll": "Create poll",
"Create Poll": "Create Poll",
"Failed to post poll": "Failed to post poll",
"Sorry, the poll you tried to create was not posted.": "Sorry, the poll you tried to create was not posted.",
Expand Down Expand Up @@ -3276,7 +3276,6 @@
"Commands": "Commands",
"Command Autocomplete": "Command Autocomplete",
"Community Autocomplete": "Community Autocomplete",
"Emoji": "Emoji",
"Emoji Autocomplete": "Emoji Autocomplete",
"Notify the whole room": "Notify the whole room",
"Room Notification": "Room Notification",
Expand Down
49 changes: 36 additions & 13 deletions test/components/views/rooms/MessageComposerButtons-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,45 @@ const MessageComposerButtons = TestUtils.wrapInMatrixClientContext(
);

describe("MessageComposerButtons", () => {
it("Renders all buttons in wide mode", () => {
it("Renders emoji and upload buttons in wide mode", () => {
const buttons = wrapAndRender(
<MessageComposerButtons
isMenuOpen={false}
narrowMode={false}
showLocationButton={true}
showStickersButton={true}
toggleButtonMenu={() => {}}
/>,
);

expect(buttonLabels(buttons)).toEqual([
"Emoji",
"Attachment",
"More options",
]);
});

it("Renders other buttons in menu in wide mode", () => {
const buttons = wrapAndRender(
<MessageComposerButtons
isMenuOpen={true}
narrowMode={false}
showLocationButton={true}
showStickersButton={true}
toggleButtonMenu={() => {}}
/>,
);

expect(buttonLabels(buttons)).toEqual([
"Create poll",
"Upload file",
"Share location",
"Add emoji",
"Show Stickers",
"Send voice message",
"Emoji",
"Attachment",
"More options",
[
"Sticker",
"Voice Message",
"Poll",
"Location",
],
]);
});

Expand All @@ -61,11 +83,12 @@ describe("MessageComposerButtons", () => {
narrowMode={true}
showLocationButton={true}
showStickersButton={true}
toggleButtonMenu={() => {}}
/>,
);

expect(buttonLabels(buttons)).toEqual([
"Upload file",
"Emoji",
"More options",
]);
});
Expand All @@ -82,13 +105,13 @@ describe("MessageComposerButtons", () => {
);

expect(buttonLabels(buttons)).toEqual([
"Upload file",
"Emoji",
"More options",
[
"Create poll",
"Share location",
"Add emoji",
"Send a sticker",
"Attachment",
"Sticker",
"Poll",
"Location",
],
]);
});
Expand Down