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 12 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
2 changes: 1 addition & 1 deletion res/css/structures/_ContextualMenu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ limitations under the License.
}

.mx_ContextualMenu_right {
right: 0;
right: 16px;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might affect more than just the expected menu, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I checked through the code looking for cases it affected, and visually inspecting places that showed a ContextMenu with position.right set. They looked OK, but I am not certain I have found all the cases.

The cases I found were:

  • ThreadPanel's context menu, which has a chevron, so doesn't use this class
  • WidgetCard's context menu which I think is this one
    image
    ... and looked OK to me
  • RoomSummaryCard's context menu, which I couldn't find.

}

.mx_ContextualMenu.mx_ContextualMenu_withChevron_right {
Expand Down
9 changes: 3 additions & 6 deletions res/css/views/rooms/_MessageComposer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ limitations under the License.
border-top: 1px solid $primary-hairline-color;
position: relative;
padding-left: 42px;
padding-right: 6px;
padding-right: 16px;
}

.mx_MessageComposer_replaced_wrapper {
Expand Down 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 Expand Up @@ -417,4 +412,6 @@ limitations under the License.
min-width: 150px;
width: max-content;
padding: 5px 10px 5px 0;
box-shadow: 0px 2px 9px rgba(0, 0, 0, 0.25);
border-radius: 8px;
}
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
11 changes: 9 additions & 2 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>;
}

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

export default CollapsibleButton;
116 changes: 52 additions & 64 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 @@ -249,21 +243,20 @@ class UploadButton extends React.Component<IUploadButtonProps> {

render() {
const uploadInputStyle = { display: 'none' };
return (
<AccessibleTooltipButton
return <>
<CollapsibleButton
className="mx_MessageComposer_button mx_MessageComposer_upload"
onClick={this.onUploadClick}
title={_t('Upload file')}
>
<input
ref={this.uploadInput}
type="file"
style={uploadInputStyle}
multiple
onChange={this.onUploadFileInputChange}
/>
</AccessibleTooltipButton>
);
title={_t('Attachment')}
/>
<input
ref={this.uploadInput}
type="file"
style={uploadInputStyle}
multiple
onChange={this.onUploadFileInputChange}
/>
</>;
}
}

Expand All @@ -275,13 +268,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 +283,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 +298,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 +338,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 @@ -3277,7 +3277,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
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ exports[`PollCreateDialog renders a blank poll 1`] = `
"filteredTimelineSets": Object {},
"getTypeWarning": false,
"getVersionWarning": false,
"lastThread": undefined,
"membersPromise": Promise {},
"myUserId": "@name:example.com",
"name": "roomid",
Expand Down Expand Up @@ -257,7 +256,6 @@ exports[`PollCreateDialog renders a blank poll 1`] = `
"filteredTimelineSets": Object {},
"getTypeWarning": false,
"getVersionWarning": false,
"lastThread": undefined,
"membersPromise": Promise {},
"myUserId": "@name:example.com",
"name": "roomid",
Expand Down Expand Up @@ -1159,7 +1157,6 @@ exports[`PollCreateDialog renders a question and some options 1`] = `
"filteredTimelineSets": Object {},
"getTypeWarning": false,
"getVersionWarning": false,
"lastThread": undefined,
"membersPromise": Promise {},
"myUserId": "@name:example.com",
"name": "roomid",
Expand Down Expand Up @@ -1380,7 +1377,6 @@ exports[`PollCreateDialog renders a question and some options 1`] = `
"filteredTimelineSets": Object {},
"getTypeWarning": false,
"getVersionWarning": false,
"lastThread": undefined,
"membersPromise": Promise {},
"myUserId": "@name:example.com",
"name": "roomid",
Expand Down
Loading