From 951d61375cea8ac1f07031f67f876beb18b9f50a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Jun 2022 13:21:00 +0100 Subject: [PATCH 01/10] Revert "Prevent new composer from overflowing from non-breakable text (#8829)" This reverts commit 57dff8131c6ecbd708011004928d2c943ad02cab. --- res/css/views/rooms/_MessageComposer.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 41faff2b038..5c34f78a8be 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -37,7 +37,6 @@ limitations under the License. } .mx_MessageComposer_row { - min-width: 0; grid-area: composer; } From 2df3699810297ab653bff31d8b89a3b8e007ba75 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Jun 2022 13:21:10 +0100 Subject: [PATCH 02/10] Revert "Fix scroll jump issue with the composer (#8791)" This reverts commit 5167521ea42c4593820e02d015b7d20a71bd96aa. --- res/css/views/rooms/_MessageComposer.scss | 5 ----- res/css/views/rooms/_SendMessageComposer.scss | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 5c34f78a8be..0d714f68fc0 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -27,11 +27,6 @@ limitations under the License. "composer controls" auto / 1fr auto; - /* the below is required, without this some unexpected scroll jump - will occur when erasing the composer content or jumping to voice note - recording */ - min-height: 45px; - .mx_ReplyPreview { grid-area: reply; } diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss index 6805f158ed7..efa8a6c841c 100644 --- a/res/css/views/rooms/_SendMessageComposer.scss +++ b/res/css/views/rooms/_SendMessageComposer.scss @@ -31,6 +31,11 @@ limitations under the License. display: flex; flex-direction: column; + /* the below is required, without this some unexpected scroll jump + will occur when erasing the composer content or jumping to voice note + recording */ + min-height: 45px; + .mx_BasicMessageComposer_input { // this will center the contenteditable // in it's parent vertically From c9b5ee7f45dc84b104e13b9c8366b0a3e2359277 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Jun 2022 13:21:18 +0100 Subject: [PATCH 03/10] Revert "Fix scroll jump issue with the composer (#8788)" This reverts commit f568a76dc6444ef04fe2dc3809c0d8e38f94c079. --- res/css/views/rooms/_SendMessageComposer.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss index efa8a6c841c..6805f158ed7 100644 --- a/res/css/views/rooms/_SendMessageComposer.scss +++ b/res/css/views/rooms/_SendMessageComposer.scss @@ -31,11 +31,6 @@ limitations under the License. display: flex; flex-direction: column; - /* the below is required, without this some unexpected scroll jump - will occur when erasing the composer content or jumping to voice note - recording */ - min-height: 45px; - .mx_BasicMessageComposer_input { // this will center the contenteditable // in it's parent vertically From cdbdfdb450b9dfc810f67425dd3bffbcfc2b3b09 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Jun 2022 13:21:25 +0100 Subject: [PATCH 04/10] Revert "Revert link color change in composer (#8784)" This reverts commit aedbeb299595a29efbfa73a08489118115d3654a. --- res/css/views/rooms/_MessageComposer.scss | 4 ++++ src/components/views/rooms/MessageComposer.tsx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 0d714f68fc0..6de32107478 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -58,6 +58,10 @@ limitations under the License. .mx_VoiceMessagePrimaryContainer { margin-right: $spacing-8; } + + a { + color: $accent; + } } .mx_MessageComposer_autocomplete_wrapper { diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index 781121d57be..adba298d73b 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -391,7 +391,7 @@ export default class MessageComposer extends React.Component {   { replacementRoomId && ( { _t("The conversation continues here.") } From 9e8115a1ec9394f8c363ee69728e49f35725692b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Jun 2022 13:21:34 +0100 Subject: [PATCH 05/10] Revert "Improve composer visiblity (#8578)" This reverts commit f14374a51c153f64f313243f2df6ea4971db4e15. --- res/css/_components.scss | 1 - res/css/structures/_RoomView.scss | 8 +- res/css/views/buttons/_Cancel.scss | 32 ---- res/css/views/rooms/_MessageComposer.scss | 158 ++++++------------ res/css/views/rooms/_ReplyPreview.scss | 68 ++++---- res/css/views/rooms/_SendMessageComposer.scss | 6 + res/img/cancel.svg | 4 +- .../element-icons/room/message-bar/reply.svg | 4 +- res/img/element-icons/room/room-summary.svg | 2 +- res/img/element-icons/x-8px.svg | 4 +- src/components/views/buttons/Cancel.tsx | 40 ----- .../views/messages/DisambiguatedProfile.tsx | 22 +-- .../views/messages/SenderProfile.tsx | 6 - .../views/rooms/MessageComposer.tsx | 99 +++++------ src/components/views/rooms/ReplyPreview.tsx | 28 ++-- src/components/views/rooms/ReplyTile.tsx | 5 +- src/i18n/strings/en_EN.json | 12 +- .../views/rooms/MessageComposer-test.tsx | 2 +- 18 files changed, 176 insertions(+), 325 deletions(-) delete mode 100644 res/css/views/buttons/_Cancel.scss delete mode 100644 src/components/views/buttons/Cancel.tsx diff --git a/res/css/_components.scss b/res/css/_components.scss index 566122a6823..ee0079aa165 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -83,7 +83,6 @@ @import "./views/avatars/_DecoratedRoomAvatar.scss"; @import "./views/avatars/_WidgetAvatar.scss"; @import "./views/beta/_BetaCard.scss"; -@import "./views/buttons/_Cancel.scss"; @import "./views/context_menus/_CallContextMenu.scss"; @import "./views/context_menus/_DeviceContextMenu.scss"; @import "./views/context_menus/_IconizedContextMenu.scss"; diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index a3172e39d72..eba8ae8f6e8 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -32,12 +32,6 @@ limitations under the License. position: relative; } -.mx_MainSplit_timeline { - .mx_MessageComposer_wrapper { - margin: $spacing-8 $spacing-16; - } -} - .mx_RoomView_auxPanel { min-width: 0px; width: 100%; @@ -161,7 +155,7 @@ limitations under the License. .mx_RoomView_messageListWrapper { justify-content: flex-start; - > .mx_RoomView_MessageList > li > ol { + >.mx_RoomView_MessageList > li > ol { list-style-type: none; } } diff --git a/res/css/views/buttons/_Cancel.scss b/res/css/views/buttons/_Cancel.scss deleted file mode 100644 index 50e2cd0931a..00000000000 --- a/res/css/views/buttons/_Cancel.scss +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_CancelButton { - width: var(--size); - height: var(--size); - - box-sizing: border-box; - padding: calc(var(--size) / 4); - border-radius: 50%; - - line-height: 0; - background: $quinary-content; - - svg { - width: calc(var(--size) / 2); - color: $secondary-content; - } -} diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 6de32107478..9619bad3fe8 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -20,48 +20,31 @@ limitations under the License. margin: auto; border-top: 1px solid $primary-hairline-color; position: relative; + padding-left: 42px; + padding-right: 16px; +} - display: grid; - grid-template: - "reply reply" auto - "composer controls" auto - / 1fr auto; - - .mx_ReplyPreview { - grid-area: reply; - } - - .mx_MessageComposer_row { - grid-area: composer; - } - - .mx_MessageComposer_controls { - grid-area: controls; - display: flex; - align-items: flex-end; - margin-bottom: 2px; - } - - >[role=button] { - margin-bottom: 7px; - } - - .mx_VoiceRecordComposerTile_delete { - margin-bottom: 9px; - } +.mx_MessageComposer_replaced_wrapper { + margin-left: auto; + margin-right: auto; +} - .mx_VoiceRecordComposerTile_stop, - .mx_MessageComposer_sendMessage { - margin-bottom: $spacing-4; - } +.mx_MessageComposer_replaced_valign { + height: 60px; + display: table-cell; + vertical-align: middle; +} - .mx_VoiceMessagePrimaryContainer { - margin-right: $spacing-8; - } +.mx_MessageComposer_roomReplaced_icon { + float: left; + margin-right: 20px; + margin-top: 5px; + width: 31px; + height: 31px; +} - a { - color: $accent; - } +.mx_MessageComposer_roomReplaced_header { + font-weight: bold; } .mx_MessageComposer_autocomplete_wrapper { @@ -73,36 +56,7 @@ limitations under the License. display: flex; flex-direction: row; align-items: center; - border: 1px solid $quaternary-content; - border-radius: 12px; - padding: $spacing-12 $spacing-8; - margin-right: $spacing-16; - - transition: border-color var(--transition-short); - - &[data-notice=true] { - border-color: transparent; - color: $secondary-content; - - p { - margin: 0; - line-height: 0; - } - - svg { - vertical-align: middle; - position: relative; - top: -2px; - } - } - - &:focus-within { - border-color: $tertiary-content; - } - - &[aria-disabled=true] { - cursor: not-allowed; - } + width: 100%; } .mx_MessageComposer .mx_MessageComposer_avatar { @@ -119,16 +73,22 @@ limitations under the License. } .mx_MessageComposer_e2eIcon.mx_E2EIcon { - margin: 0 0 2px; + position: absolute; + left: 20px; + margin-right: 0; // Counteract the E2EIcon class + margin-left: 3px; // Counteract the E2EIcon class width: 12px; height: 12px; - align-self: end; } .mx_MessageComposer_noperm_error { + width: 100%; + height: 60px; font-style: italic; - color: $tertiary-content; - font-size: $font-12px; + color: $info-plinth-fg-color; + display: flex; + align-items: center; + justify-content: center; } .mx_MessageComposer_input_wrapper { @@ -164,19 +124,13 @@ limitations under the License. .mx_MessageComposer_editor > :first-child { margin-top: 0 !important; } - .mx_MessageComposer_editor > :last-child { margin-bottom: 0 !important; } @keyframes visualbell { - from { - background-color: $visual-bell-bg-color; - } - - to { - background-color: $background; - } + from { background-color: $visual-bell-bg-color; } + to { background-color: $background; } } .mx_MessageComposer_input_error { @@ -212,14 +166,12 @@ limitations under the License. color: $accent; opacity: 1.0; } - .mx_MessageComposer_input textarea::-webkit-input-placeholder { color: $accent; } .mx_MessageComposer_button_highlight { background: rgba($accent, 0.25); - // make the icon the accent color too &::before { background-color: $accent !important; @@ -236,7 +188,6 @@ limitations under the License. padding-left: var(--size); border-radius: 50%; margin-right: 6px; - margin-bottom: 7px; &:last-child { margin-right: auto; @@ -310,30 +261,11 @@ limitations under the License. mask-image: url('$(res)/img/image-view/more.svg'); } -.mx_MessageComposer_sendMessageWrapper { - --sendMessageSize: 32px; - transition: all var(--transition-short); -} - -.mx_MessageComposer_sendMessageWrapper, -.mx_MessageComposer_sendMessageWrapper-enter, -.mx_MessageComposer_sendMessageWrapper-exit { - width: 0; - transform: scale(.6); - opacity: 0; -} - -.mx_MessageComposer_sendMessageWrapper-enter-active { - width: var(--sendMessageSize); - transform: scale(1); - opacity: 1; -} - .mx_MessageComposer_sendMessage { cursor: pointer; position: relative; - width: var(--sendMessageSize); - height: var(--sendMessageSize); + width: 32px; + height: 32px; border-radius: 100%; background-color: $accent; @@ -426,6 +358,10 @@ limitations under the License. .mx_MessageComposer_input { min-height: 50px; } + + .mx_MessageComposer_noperm_error { + height: 50px; + } } /** @@ -435,7 +371,21 @@ limitations under the License. .mx_MessageComposer.mx_MessageComposer--compact { margin-right: 0; + .mx_MessageComposer_wrapper { + padding: 0 0 0 25px; + } + + &:not(.mx_MessageComposer_e2eStatus) { + .mx_MessageComposer_wrapper { + padding: 0; + } + } + .mx_MessageComposer_button:last-child { margin-right: 0; } + + .mx_MessageComposer_e2eIcon { + left: 0; + } } diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss index e303a22c028..50abcc738ba 100644 --- a/res/css/views/rooms/_ReplyPreview.scss +++ b/res/css/views/rooms/_ReplyPreview.scss @@ -15,44 +15,48 @@ limitations under the License. */ .mx_ReplyPreview { - border: 1px solid $system; - - margin-left: calc(-1 * $spacing-16); - margin-right: calc(-1 * $spacing-16); - padding: $spacing-8 $spacing-16 0 $spacing-16; - - border-top-left-radius: 16px; - border-top-right-radius: 16px; - + border: 1px solid $primary-hairline-color; border-bottom: none; background: $background; max-height: 50vh; overflow: auto; -} -.mx_ReplyPreview_header { - display: flex; - font-size: $font-12px; - color: $secondary-content; - position: relative; - - > svg { - width: 1em; - vertical-align: middle; - margin-right: $spacing-8; - } - - .mx_CancelButton { - position: absolute; - right: 0; - top: 50%; - transform: translateY(-50%); + .mx_ReplyPreview_section { + border-bottom: 1px solid $primary-hairline-color; + display: flex; + flex-flow: column; + row-gap: $spacing-8; + padding: $spacing-8 $spacing-8 0 $spacing-8; + + .mx_ReplyPreview_header { + display: flex; + justify-content: space-between; + column-gap: 8px; + + color: $primary-content; + font-weight: 400; + opacity: 0.4; + + .mx_ReplyPreview_header_cancel { + background-color: $primary-content; + mask: url('$(res)/img/cancel.svg'); + mask-repeat: no-repeat; + mask-position: center; + mask-size: 18px; + width: 18px; + height: 18px; + min-width: 18px; + min-height: 18px; + } + } } } -.mx_ReplyPreview_header_cancel { - position: absolute; - right: 0; - color: $primary-content; - width: 18px; +.mx_RoomView_body { + .mx_ReplyPreview { + // Add box-shadow to the reply preview on the main (left) panel only. + // It is not added to the preview on the (right) panel for threads and a chat with a maximized widget. + box-shadow: 0px -16px 32px $composer-shadow-color; + border-radius: 8px 8px 0 0; + } } diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss index 6805f158ed7..3e2cf68f1db 100644 --- a/res/css/views/rooms/_SendMessageComposer.scss +++ b/res/css/views/rooms/_SendMessageComposer.scss @@ -30,8 +30,14 @@ limitations under the License. flex: 1; display: flex; flex-direction: column; + // min-height at this level so the mx_BasicMessageComposer_input + // still stays vertically centered when less than 55px. + // We also set this to ensure the voice message recording widget + // doesn't cause a jump. + min-height: 55px; .mx_BasicMessageComposer_input { + padding: 3px 0; // this will center the contenteditable // in it's parent vertically // while keeping the autocomplete at the top diff --git a/res/img/cancel.svg b/res/img/cancel.svg index 82e38925615..e32060025ea 100644 --- a/res/img/cancel.svg +++ b/res/img/cancel.svg @@ -5,6 +5,6 @@ Created with Sketch. - + - + \ No newline at end of file diff --git a/res/img/element-icons/room/message-bar/reply.svg b/res/img/element-icons/room/message-bar/reply.svg index c32848a0b00..9900d4d19d4 100644 --- a/res/img/element-icons/room/message-bar/reply.svg +++ b/res/img/element-icons/room/message-bar/reply.svg @@ -1,4 +1,4 @@ - - + + diff --git a/res/img/element-icons/room/room-summary.svg b/res/img/element-icons/room/room-summary.svg index 1f43428ffc8..b6ac258b189 100644 --- a/res/img/element-icons/room/room-summary.svg +++ b/res/img/element-icons/room/room-summary.svg @@ -1,3 +1,3 @@ - + diff --git a/res/img/element-icons/x-8px.svg b/res/img/element-icons/x-8px.svg index 8a706c3446f..c9730ed6192 100644 --- a/res/img/element-icons/x-8px.svg +++ b/res/img/element-icons/x-8px.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/components/views/buttons/Cancel.tsx b/src/components/views/buttons/Cancel.tsx deleted file mode 100644 index f0fbee56dbd..00000000000 --- a/src/components/views/buttons/Cancel.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React, { ComponentProps } from "react"; -import classnames from "classnames"; - -import AccessibleButton from "../elements/AccessibleButton"; -import { Icon as CancelIcon } from "../../../../res/img/cancel.svg"; - -export default function CancelButton(props: ComponentProps) { - const classNames = classnames("mx_CancelButton", props.className ?? ""); - const vars = { - "--size": `${props.size}px`, - } as React.CSSProperties; - - return - - ; -} - -CancelButton.defaultProps = { - size: "16", -}; diff --git a/src/components/views/messages/DisambiguatedProfile.tsx b/src/components/views/messages/DisambiguatedProfile.tsx index d634277bc61..36850e916ea 100644 --- a/src/components/views/messages/DisambiguatedProfile.tsx +++ b/src/components/views/messages/DisambiguatedProfile.tsx @@ -28,14 +28,9 @@ interface IProps { onClick?(): void; colored?: boolean; emphasizeDisplayName?: boolean; - as?: string; } export default class DisambiguatedProfile extends React.Component { - public static defaultProps = { - as: "div", - }; - render() { const { fallbackName, member, colored, emphasizeDisplayName, onClick } = this.props; const rawDisplayName = member?.rawDisplayName || fallbackName; @@ -62,14 +57,13 @@ export default class DisambiguatedProfile extends React.Component { [colorClass]: true, }); - return React.createElement(this.props.as, { - className: "mx_DisambiguatedProfile", - onClick, - }, <> - - { rawDisplayName } - - { mxidElement } - ); + return ( +
+ + { rawDisplayName } + + { mxidElement } +
+ ); } } diff --git a/src/components/views/messages/SenderProfile.tsx b/src/components/views/messages/SenderProfile.tsx index a9c77f9ebee..da7d1206d11 100644 --- a/src/components/views/messages/SenderProfile.tsx +++ b/src/components/views/messages/SenderProfile.tsx @@ -27,17 +27,12 @@ import { MatrixClientPeg } from "../../../MatrixClientPeg"; interface IProps { mxEvent: MatrixEvent; onClick?(): void; - as?: string; } export default class SenderProfile extends React.PureComponent { public static contextType = MatrixClientContext; public context!: React.ContextType; - public static defaultProps = { - as: "div", - }; - render() { const { mxEvent, onClick } = this.props; const msgtype = mxEvent.getContent().msgtype; @@ -65,7 +60,6 @@ export default class SenderProfile extends React.PureComponent { member={member} colored={true} emphasizeDisplayName={true} - as={this.props.as} /> ); } } diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index adba298d73b..07912586378 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -22,7 +22,6 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { EventType } from 'matrix-js-sdk/src/@types/event'; import { Optional } from "matrix-events-sdk"; import { THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread'; -import { CSSTransition } from 'react-transition-group'; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; @@ -52,14 +51,12 @@ import { SettingUpdatedPayload } from "../../../dispatcher/payloads/SettingUpdat import MessageComposerButtons from './MessageComposerButtons'; import { ButtonEvent } from '../elements/AccessibleButton'; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; -import { Icon as InfoIcon } from "../../../../res/img/element-icons/room/room-summary.svg"; let instanceCount = 0; interface ISendButtonProps { onClick: (ev: ButtonEvent) => void; title?: string; // defaults to something generic - "aria-hidden"?: boolean; } function SendButton(props: ISendButtonProps) { @@ -68,7 +65,6 @@ function SendButton(props: ISendButtonProps) { className="mx_MessageComposer_sendMessage" onClick={props.onClick} title={props.title ?? _t('Send message')} - aria-hidden={props['aria-hidden'] ?? false} /> ); } @@ -267,15 +263,15 @@ export default class MessageComposer extends React.Component { } else if (replyingToThread) { return _t('Reply to thread…'); } else if (this.props.e2eStatus) { - return _t('Send encrypted reply…'); + return _t('Send an encrypted reply…'); } else { - return _t('Send reply…'); + return _t('Send a reply…'); } } else { if (this.props.e2eStatus) { - return _t('Send encrypted message…'); + return _t('Send an encrypted message…'); } else { - return _t('Send message…'); + return _t('Send a message…'); } } }; @@ -355,7 +351,11 @@ export default class MessageComposer extends React.Component { }; public render() { - const controls = []; + const controls = [ + this.props.e2eStatus ? + : + null, + ]; let menuPosition: AboveLeftOf | undefined; if (this.ref.current) { @@ -363,8 +363,6 @@ export default class MessageComposer extends React.Component { menuPosition = aboveLeftOf(contentRect); } - const roomReplaced = !!this.context.tombstone; - const canSendMessages = this.context.canSendMessages && !this.context.tombstone; if (canSendMessages) { controls.push( @@ -381,23 +379,34 @@ export default class MessageComposer extends React.Component { toggleStickerPickerOpen={this.toggleStickerPickerOpen} />, ); - } else if (roomReplaced) { + + controls.push(); + } else if (this.context.tombstone) { const replacementRoomId = this.context.tombstone.getContent()['replacement_room']; - controls.push(

- -   - { _t("This room has been replaced and is no longer active.") } -   - { replacementRoomId && ( - - { _t("The conversation continues here.") } - - ) } -

); + const continuesLink = replacementRoomId ? ( + + { _t("The conversation continues here.") } + + ) : ''; + + controls.push(
+
+ + + { _t("This room has been replaced and is no longer active.") } +
+ { continuesLink } +
+
); } else { controls.push(
@@ -432,12 +441,6 @@ export default class MessageComposer extends React.Component { const showSendButton = !this.state.isComposerEmpty || this.state.haveRecording; - if (this.props.e2eStatus) { - controls.push( - , - ); - } - const classes = classNames({ "mx_MessageComposer": true, "mx_GroupLayout": true, @@ -452,17 +455,8 @@ export default class MessageComposer extends React.Component { -
+
{ controls } -
-
- { canSendMessages && } { canSendMessages && { showStickersButton={this.state.showStickersButton} toggleButtonMenu={this.toggleButtonMenu} /> } - {}} - > -
- -
-
+ { showSendButton && ( + + ) }
diff --git a/src/components/views/rooms/ReplyPreview.tsx b/src/components/views/rooms/ReplyPreview.tsx index 345ce83c211..611c58f8529 100644 --- a/src/components/views/rooms/ReplyPreview.tsx +++ b/src/components/views/rooms/ReplyPreview.tsx @@ -22,9 +22,7 @@ import { _t } from '../../../languageHandler'; import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import ReplyTile from './ReplyTile'; import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext'; -import SenderProfile from '../messages/SenderProfile'; -import { Icon as ReplyIcon } from "../../../../res/img/element-icons/room/message-bar/reply.svg"; -import CancelButton from '../buttons/Cancel'; +import AccessibleButton from "../elements/AccessibleButton"; function cancelQuoting(context: TimelineRenderingType) { dis.dispatch({ @@ -46,19 +44,19 @@ export default class ReplyPreview extends React.Component { if (!this.props.replyToEvent) return null; return
-
- - { _t('Reply to ', {}, { - 'User': () => , - }) }   - - cancelQuoting(this.context.timelineRenderingType)} /> +
+
+ { _t('Replying') } + cancelQuoting(this.context.timelineRenderingType)} + /> +
+
-
; } } diff --git a/src/components/views/rooms/ReplyTile.tsx b/src/components/views/rooms/ReplyTile.tsx index bc26c02c238..2b973abfca5 100644 --- a/src/components/views/rooms/ReplyTile.tsx +++ b/src/components/views/rooms/ReplyTile.tsx @@ -44,7 +44,6 @@ interface IProps { getRelationsForEvent?: ( (eventId: string, relationType: string, eventType: string) => Relations ); - showSenderProfile?: boolean; } export default class ReplyTile extends React.PureComponent { @@ -52,7 +51,6 @@ export default class ReplyTile extends React.PureComponent { static defaultProps = { onHeightChanged: () => {}, - showSenderProfile: true, }; componentDidMount() { @@ -138,8 +136,7 @@ export default class ReplyTile extends React.PureComponent { let sender; const needsSenderProfile = ( - this.props.showSenderProfile - && !isInfoMessage + !isInfoMessage && msgType !== MsgType.Image && evType !== EventType.Sticker && evType !== EventType.RoomCreate diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 829d361fb64..779bcbaa5f9 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1720,12 +1720,12 @@ "Send message": "Send message", "Reply to encrypted thread…": "Reply to encrypted thread…", "Reply to thread…": "Reply to thread…", - "Send encrypted reply…": "Send encrypted reply…", - "Send reply…": "Send reply…", - "Send encrypted message…": "Send encrypted message…", - "Send message…": "Send message…", - "This room has been replaced and is no longer active.": "This room has been replaced and is no longer active.", + "Send an encrypted reply…": "Send an encrypted reply…", + "Send a reply…": "Send a reply…", + "Send an encrypted message…": "Send an encrypted message…", + "Send a message…": "Send a message…", "The conversation continues here.": "The conversation continues here.", + "This room has been replaced and is no longer active.": "This room has been replaced and is no longer active.", "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", @@ -1778,7 +1778,7 @@ "Seen by %(count)s people|one": "Seen by %(count)s person", "Read receipts": "Read receipts", "Recently viewed": "Recently viewed", - "Reply to ": "Reply to ", + "Replying": "Replying", "Room %(name)s": "Room %(name)s", "Recently visited rooms": "Recently visited rooms", "No recently visited rooms": "No recently visited rooms", diff --git a/test/components/views/rooms/MessageComposer-test.tsx b/test/components/views/rooms/MessageComposer-test.tsx index d774aa80604..e756a7653c4 100644 --- a/test/components/views/rooms/MessageComposer-test.tsx +++ b/test/components/views/rooms/MessageComposer-test.tsx @@ -61,7 +61,7 @@ describe("MessageComposer", () => { expect(wrapper.find("SendMessageComposer")).toHaveLength(0); expect(wrapper.find("MessageComposerButtons")).toHaveLength(0); - expect(wrapper.find("p").text()).toContain("room has been replaced"); + expect(wrapper.find(".mx_MessageComposer_roomReplaced_header")).toHaveLength(1); }); }); From d34565568db3c078a5dfb5abbd7692ab1af65777 Mon Sep 17 00:00:00 2001 From: Germain Date: Tue, 7 Jun 2022 08:28:29 +0100 Subject: [PATCH 06/10] Improve composer visiblity (#8578) Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> (cherry picked from commit f14374a51c153f64f313243f2df6ea4971db4e15) --- res/css/_components.scss | 1 + res/css/structures/_RoomView.scss | 8 +- res/css/views/buttons/_Cancel.scss | 32 ++++ res/css/views/rooms/_MessageComposer.scss | 158 ++++++++++++------ res/css/views/rooms/_ReplyPreview.scss | 68 ++++---- res/css/views/rooms/_SendMessageComposer.scss | 6 - res/img/cancel.svg | 4 +- .../element-icons/room/message-bar/reply.svg | 4 +- res/img/element-icons/room/room-summary.svg | 2 +- res/img/element-icons/x-8px.svg | 4 +- src/components/views/buttons/Cancel.tsx | 40 +++++ .../views/messages/DisambiguatedProfile.tsx | 22 ++- .../views/messages/SenderProfile.tsx | 6 + .../views/rooms/MessageComposer.tsx | 99 ++++++----- src/components/views/rooms/ReplyPreview.tsx | 28 ++-- src/components/views/rooms/ReplyTile.tsx | 5 +- src/i18n/strings/en_EN.json | 12 +- .../views/rooms/MessageComposer-test.tsx | 2 +- 18 files changed, 325 insertions(+), 176 deletions(-) create mode 100644 res/css/views/buttons/_Cancel.scss create mode 100644 src/components/views/buttons/Cancel.tsx diff --git a/res/css/_components.scss b/res/css/_components.scss index ee0079aa165..566122a6823 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -83,6 +83,7 @@ @import "./views/avatars/_DecoratedRoomAvatar.scss"; @import "./views/avatars/_WidgetAvatar.scss"; @import "./views/beta/_BetaCard.scss"; +@import "./views/buttons/_Cancel.scss"; @import "./views/context_menus/_CallContextMenu.scss"; @import "./views/context_menus/_DeviceContextMenu.scss"; @import "./views/context_menus/_IconizedContextMenu.scss"; diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index eba8ae8f6e8..a3172e39d72 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -32,6 +32,12 @@ limitations under the License. position: relative; } +.mx_MainSplit_timeline { + .mx_MessageComposer_wrapper { + margin: $spacing-8 $spacing-16; + } +} + .mx_RoomView_auxPanel { min-width: 0px; width: 100%; @@ -155,7 +161,7 @@ limitations under the License. .mx_RoomView_messageListWrapper { justify-content: flex-start; - >.mx_RoomView_MessageList > li > ol { + > .mx_RoomView_MessageList > li > ol { list-style-type: none; } } diff --git a/res/css/views/buttons/_Cancel.scss b/res/css/views/buttons/_Cancel.scss new file mode 100644 index 00000000000..50e2cd0931a --- /dev/null +++ b/res/css/views/buttons/_Cancel.scss @@ -0,0 +1,32 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_CancelButton { + width: var(--size); + height: var(--size); + + box-sizing: border-box; + padding: calc(var(--size) / 4); + border-radius: 50%; + + line-height: 0; + background: $quinary-content; + + svg { + width: calc(var(--size) / 2); + color: $secondary-content; + } +} diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 9619bad3fe8..6de32107478 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -20,31 +20,48 @@ limitations under the License. margin: auto; border-top: 1px solid $primary-hairline-color; position: relative; - padding-left: 42px; - padding-right: 16px; -} -.mx_MessageComposer_replaced_wrapper { - margin-left: auto; - margin-right: auto; -} + display: grid; + grid-template: + "reply reply" auto + "composer controls" auto + / 1fr auto; -.mx_MessageComposer_replaced_valign { - height: 60px; - display: table-cell; - vertical-align: middle; -} + .mx_ReplyPreview { + grid-area: reply; + } -.mx_MessageComposer_roomReplaced_icon { - float: left; - margin-right: 20px; - margin-top: 5px; - width: 31px; - height: 31px; -} + .mx_MessageComposer_row { + grid-area: composer; + } + + .mx_MessageComposer_controls { + grid-area: controls; + display: flex; + align-items: flex-end; + margin-bottom: 2px; + } + + >[role=button] { + margin-bottom: 7px; + } + + .mx_VoiceRecordComposerTile_delete { + margin-bottom: 9px; + } + + .mx_VoiceRecordComposerTile_stop, + .mx_MessageComposer_sendMessage { + margin-bottom: $spacing-4; + } -.mx_MessageComposer_roomReplaced_header { - font-weight: bold; + .mx_VoiceMessagePrimaryContainer { + margin-right: $spacing-8; + } + + a { + color: $accent; + } } .mx_MessageComposer_autocomplete_wrapper { @@ -56,7 +73,36 @@ limitations under the License. display: flex; flex-direction: row; align-items: center; - width: 100%; + border: 1px solid $quaternary-content; + border-radius: 12px; + padding: $spacing-12 $spacing-8; + margin-right: $spacing-16; + + transition: border-color var(--transition-short); + + &[data-notice=true] { + border-color: transparent; + color: $secondary-content; + + p { + margin: 0; + line-height: 0; + } + + svg { + vertical-align: middle; + position: relative; + top: -2px; + } + } + + &:focus-within { + border-color: $tertiary-content; + } + + &[aria-disabled=true] { + cursor: not-allowed; + } } .mx_MessageComposer .mx_MessageComposer_avatar { @@ -73,22 +119,16 @@ limitations under the License. } .mx_MessageComposer_e2eIcon.mx_E2EIcon { - position: absolute; - left: 20px; - margin-right: 0; // Counteract the E2EIcon class - margin-left: 3px; // Counteract the E2EIcon class + margin: 0 0 2px; width: 12px; height: 12px; + align-self: end; } .mx_MessageComposer_noperm_error { - width: 100%; - height: 60px; font-style: italic; - color: $info-plinth-fg-color; - display: flex; - align-items: center; - justify-content: center; + color: $tertiary-content; + font-size: $font-12px; } .mx_MessageComposer_input_wrapper { @@ -124,13 +164,19 @@ limitations under the License. .mx_MessageComposer_editor > :first-child { margin-top: 0 !important; } + .mx_MessageComposer_editor > :last-child { margin-bottom: 0 !important; } @keyframes visualbell { - from { background-color: $visual-bell-bg-color; } - to { background-color: $background; } + from { + background-color: $visual-bell-bg-color; + } + + to { + background-color: $background; + } } .mx_MessageComposer_input_error { @@ -166,12 +212,14 @@ limitations under the License. color: $accent; opacity: 1.0; } + .mx_MessageComposer_input textarea::-webkit-input-placeholder { color: $accent; } .mx_MessageComposer_button_highlight { background: rgba($accent, 0.25); + // make the icon the accent color too &::before { background-color: $accent !important; @@ -188,6 +236,7 @@ limitations under the License. padding-left: var(--size); border-radius: 50%; margin-right: 6px; + margin-bottom: 7px; &:last-child { margin-right: auto; @@ -261,11 +310,30 @@ limitations under the License. mask-image: url('$(res)/img/image-view/more.svg'); } +.mx_MessageComposer_sendMessageWrapper { + --sendMessageSize: 32px; + transition: all var(--transition-short); +} + +.mx_MessageComposer_sendMessageWrapper, +.mx_MessageComposer_sendMessageWrapper-enter, +.mx_MessageComposer_sendMessageWrapper-exit { + width: 0; + transform: scale(.6); + opacity: 0; +} + +.mx_MessageComposer_sendMessageWrapper-enter-active { + width: var(--sendMessageSize); + transform: scale(1); + opacity: 1; +} + .mx_MessageComposer_sendMessage { cursor: pointer; position: relative; - width: 32px; - height: 32px; + width: var(--sendMessageSize); + height: var(--sendMessageSize); border-radius: 100%; background-color: $accent; @@ -358,10 +426,6 @@ limitations under the License. .mx_MessageComposer_input { min-height: 50px; } - - .mx_MessageComposer_noperm_error { - height: 50px; - } } /** @@ -371,21 +435,7 @@ limitations under the License. .mx_MessageComposer.mx_MessageComposer--compact { margin-right: 0; - .mx_MessageComposer_wrapper { - padding: 0 0 0 25px; - } - - &:not(.mx_MessageComposer_e2eStatus) { - .mx_MessageComposer_wrapper { - padding: 0; - } - } - .mx_MessageComposer_button:last-child { margin-right: 0; } - - .mx_MessageComposer_e2eIcon { - left: 0; - } } diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss index 50abcc738ba..e303a22c028 100644 --- a/res/css/views/rooms/_ReplyPreview.scss +++ b/res/css/views/rooms/_ReplyPreview.scss @@ -15,48 +15,44 @@ limitations under the License. */ .mx_ReplyPreview { - border: 1px solid $primary-hairline-color; + border: 1px solid $system; + + margin-left: calc(-1 * $spacing-16); + margin-right: calc(-1 * $spacing-16); + padding: $spacing-8 $spacing-16 0 $spacing-16; + + border-top-left-radius: 16px; + border-top-right-radius: 16px; + border-bottom: none; background: $background; max-height: 50vh; overflow: auto; +} - .mx_ReplyPreview_section { - border-bottom: 1px solid $primary-hairline-color; - display: flex; - flex-flow: column; - row-gap: $spacing-8; - padding: $spacing-8 $spacing-8 0 $spacing-8; - - .mx_ReplyPreview_header { - display: flex; - justify-content: space-between; - column-gap: 8px; - - color: $primary-content; - font-weight: 400; - opacity: 0.4; - - .mx_ReplyPreview_header_cancel { - background-color: $primary-content; - mask: url('$(res)/img/cancel.svg'); - mask-repeat: no-repeat; - mask-position: center; - mask-size: 18px; - width: 18px; - height: 18px; - min-width: 18px; - min-height: 18px; - } - } +.mx_ReplyPreview_header { + display: flex; + font-size: $font-12px; + color: $secondary-content; + position: relative; + + > svg { + width: 1em; + vertical-align: middle; + margin-right: $spacing-8; } -} -.mx_RoomView_body { - .mx_ReplyPreview { - // Add box-shadow to the reply preview on the main (left) panel only. - // It is not added to the preview on the (right) panel for threads and a chat with a maximized widget. - box-shadow: 0px -16px 32px $composer-shadow-color; - border-radius: 8px 8px 0 0; + .mx_CancelButton { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); } } + +.mx_ReplyPreview_header_cancel { + position: absolute; + right: 0; + color: $primary-content; + width: 18px; +} diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss index 3e2cf68f1db..6805f158ed7 100644 --- a/res/css/views/rooms/_SendMessageComposer.scss +++ b/res/css/views/rooms/_SendMessageComposer.scss @@ -30,14 +30,8 @@ limitations under the License. flex: 1; display: flex; flex-direction: column; - // min-height at this level so the mx_BasicMessageComposer_input - // still stays vertically centered when less than 55px. - // We also set this to ensure the voice message recording widget - // doesn't cause a jump. - min-height: 55px; .mx_BasicMessageComposer_input { - padding: 3px 0; // this will center the contenteditable // in it's parent vertically // while keeping the autocomplete at the top diff --git a/res/img/cancel.svg b/res/img/cancel.svg index e32060025ea..82e38925615 100644 --- a/res/img/cancel.svg +++ b/res/img/cancel.svg @@ -5,6 +5,6 @@ Created with Sketch. - + - \ No newline at end of file + diff --git a/res/img/element-icons/room/message-bar/reply.svg b/res/img/element-icons/room/message-bar/reply.svg index 9900d4d19d4..c32848a0b00 100644 --- a/res/img/element-icons/room/message-bar/reply.svg +++ b/res/img/element-icons/room/message-bar/reply.svg @@ -1,4 +1,4 @@ - - + + diff --git a/res/img/element-icons/room/room-summary.svg b/res/img/element-icons/room/room-summary.svg index b6ac258b189..1f43428ffc8 100644 --- a/res/img/element-icons/room/room-summary.svg +++ b/res/img/element-icons/room/room-summary.svg @@ -1,3 +1,3 @@ - + diff --git a/res/img/element-icons/x-8px.svg b/res/img/element-icons/x-8px.svg index c9730ed6192..8a706c3446f 100644 --- a/res/img/element-icons/x-8px.svg +++ b/res/img/element-icons/x-8px.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/components/views/buttons/Cancel.tsx b/src/components/views/buttons/Cancel.tsx new file mode 100644 index 00000000000..f0fbee56dbd --- /dev/null +++ b/src/components/views/buttons/Cancel.tsx @@ -0,0 +1,40 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React, { ComponentProps } from "react"; +import classnames from "classnames"; + +import AccessibleButton from "../elements/AccessibleButton"; +import { Icon as CancelIcon } from "../../../../res/img/cancel.svg"; + +export default function CancelButton(props: ComponentProps) { + const classNames = classnames("mx_CancelButton", props.className ?? ""); + const vars = { + "--size": `${props.size}px`, + } as React.CSSProperties; + + return + + ; +} + +CancelButton.defaultProps = { + size: "16", +}; diff --git a/src/components/views/messages/DisambiguatedProfile.tsx b/src/components/views/messages/DisambiguatedProfile.tsx index 36850e916ea..d634277bc61 100644 --- a/src/components/views/messages/DisambiguatedProfile.tsx +++ b/src/components/views/messages/DisambiguatedProfile.tsx @@ -28,9 +28,14 @@ interface IProps { onClick?(): void; colored?: boolean; emphasizeDisplayName?: boolean; + as?: string; } export default class DisambiguatedProfile extends React.Component { + public static defaultProps = { + as: "div", + }; + render() { const { fallbackName, member, colored, emphasizeDisplayName, onClick } = this.props; const rawDisplayName = member?.rawDisplayName || fallbackName; @@ -57,13 +62,14 @@ export default class DisambiguatedProfile extends React.Component { [colorClass]: true, }); - return ( -
- - { rawDisplayName } - - { mxidElement } -
- ); + return React.createElement(this.props.as, { + className: "mx_DisambiguatedProfile", + onClick, + }, <> + + { rawDisplayName } + + { mxidElement } + ); } } diff --git a/src/components/views/messages/SenderProfile.tsx b/src/components/views/messages/SenderProfile.tsx index da7d1206d11..a9c77f9ebee 100644 --- a/src/components/views/messages/SenderProfile.tsx +++ b/src/components/views/messages/SenderProfile.tsx @@ -27,12 +27,17 @@ import { MatrixClientPeg } from "../../../MatrixClientPeg"; interface IProps { mxEvent: MatrixEvent; onClick?(): void; + as?: string; } export default class SenderProfile extends React.PureComponent { public static contextType = MatrixClientContext; public context!: React.ContextType; + public static defaultProps = { + as: "div", + }; + render() { const { mxEvent, onClick } = this.props; const msgtype = mxEvent.getContent().msgtype; @@ -60,6 +65,7 @@ export default class SenderProfile extends React.PureComponent { member={member} colored={true} emphasizeDisplayName={true} + as={this.props.as} /> ); } } diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index 07912586378..adba298d73b 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -22,6 +22,7 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { EventType } from 'matrix-js-sdk/src/@types/event'; import { Optional } from "matrix-events-sdk"; import { THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread'; +import { CSSTransition } from 'react-transition-group'; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; @@ -51,12 +52,14 @@ import { SettingUpdatedPayload } from "../../../dispatcher/payloads/SettingUpdat import MessageComposerButtons from './MessageComposerButtons'; import { ButtonEvent } from '../elements/AccessibleButton'; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; +import { Icon as InfoIcon } from "../../../../res/img/element-icons/room/room-summary.svg"; let instanceCount = 0; interface ISendButtonProps { onClick: (ev: ButtonEvent) => void; title?: string; // defaults to something generic + "aria-hidden"?: boolean; } function SendButton(props: ISendButtonProps) { @@ -65,6 +68,7 @@ function SendButton(props: ISendButtonProps) { className="mx_MessageComposer_sendMessage" onClick={props.onClick} title={props.title ?? _t('Send message')} + aria-hidden={props['aria-hidden'] ?? false} /> ); } @@ -263,15 +267,15 @@ export default class MessageComposer extends React.Component { } else if (replyingToThread) { return _t('Reply to thread…'); } else if (this.props.e2eStatus) { - return _t('Send an encrypted reply…'); + return _t('Send encrypted reply…'); } else { - return _t('Send a reply…'); + return _t('Send reply…'); } } else { if (this.props.e2eStatus) { - return _t('Send an encrypted message…'); + return _t('Send encrypted message…'); } else { - return _t('Send a message…'); + return _t('Send message…'); } } }; @@ -351,11 +355,7 @@ export default class MessageComposer extends React.Component { }; public render() { - const controls = [ - this.props.e2eStatus ? - : - null, - ]; + const controls = []; let menuPosition: AboveLeftOf | undefined; if (this.ref.current) { @@ -363,6 +363,8 @@ export default class MessageComposer extends React.Component { menuPosition = aboveLeftOf(contentRect); } + const roomReplaced = !!this.context.tombstone; + const canSendMessages = this.context.canSendMessages && !this.context.tombstone; if (canSendMessages) { controls.push( @@ -379,34 +381,23 @@ export default class MessageComposer extends React.Component { toggleStickerPickerOpen={this.toggleStickerPickerOpen} />, ); - - controls.push(); - } else if (this.context.tombstone) { + } else if (roomReplaced) { const replacementRoomId = this.context.tombstone.getContent()['replacement_room']; - const continuesLink = replacementRoomId ? ( - - { _t("The conversation continues here.") } - - ) : ''; - - controls.push(
-
- - - { _t("This room has been replaced and is no longer active.") } -
- { continuesLink } -
-
); + controls.push(

+ +   + { _t("This room has been replaced and is no longer active.") } +   + { replacementRoomId && ( + + { _t("The conversation continues here.") } + + ) } +

); } else { controls.push(
@@ -441,6 +432,12 @@ export default class MessageComposer extends React.Component { const showSendButton = !this.state.isComposerEmpty || this.state.haveRecording; + if (this.props.e2eStatus) { + controls.push( + , + ); + } + const classes = classNames({ "mx_MessageComposer": true, "mx_GroupLayout": true, @@ -455,8 +452,17 @@ export default class MessageComposer extends React.Component { -
+
{ controls } +
+
+ { canSendMessages && } { canSendMessages && { showStickersButton={this.state.showStickersButton} toggleButtonMenu={this.toggleButtonMenu} /> } - { showSendButton && ( - - ) } + {}} + > +
+ +
+
diff --git a/src/components/views/rooms/ReplyPreview.tsx b/src/components/views/rooms/ReplyPreview.tsx index 611c58f8529..345ce83c211 100644 --- a/src/components/views/rooms/ReplyPreview.tsx +++ b/src/components/views/rooms/ReplyPreview.tsx @@ -22,7 +22,9 @@ import { _t } from '../../../languageHandler'; import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import ReplyTile from './ReplyTile'; import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext'; -import AccessibleButton from "../elements/AccessibleButton"; +import SenderProfile from '../messages/SenderProfile'; +import { Icon as ReplyIcon } from "../../../../res/img/element-icons/room/message-bar/reply.svg"; +import CancelButton from '../buttons/Cancel'; function cancelQuoting(context: TimelineRenderingType) { dis.dispatch({ @@ -44,19 +46,19 @@ export default class ReplyPreview extends React.Component { if (!this.props.replyToEvent) return null; return
-
-
- { _t('Replying') } - cancelQuoting(this.context.timelineRenderingType)} - /> -
- +
+ + { _t('Reply to ', {}, { + 'User': () => , + }) }   + + cancelQuoting(this.context.timelineRenderingType)} />
+
; } } diff --git a/src/components/views/rooms/ReplyTile.tsx b/src/components/views/rooms/ReplyTile.tsx index 2b973abfca5..bc26c02c238 100644 --- a/src/components/views/rooms/ReplyTile.tsx +++ b/src/components/views/rooms/ReplyTile.tsx @@ -44,6 +44,7 @@ interface IProps { getRelationsForEvent?: ( (eventId: string, relationType: string, eventType: string) => Relations ); + showSenderProfile?: boolean; } export default class ReplyTile extends React.PureComponent { @@ -51,6 +52,7 @@ export default class ReplyTile extends React.PureComponent { static defaultProps = { onHeightChanged: () => {}, + showSenderProfile: true, }; componentDidMount() { @@ -136,7 +138,8 @@ export default class ReplyTile extends React.PureComponent { let sender; const needsSenderProfile = ( - !isInfoMessage + this.props.showSenderProfile + && !isInfoMessage && msgType !== MsgType.Image && evType !== EventType.Sticker && evType !== EventType.RoomCreate diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 779bcbaa5f9..829d361fb64 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1720,12 +1720,12 @@ "Send message": "Send message", "Reply to encrypted thread…": "Reply to encrypted thread…", "Reply to thread…": "Reply to thread…", - "Send an encrypted reply…": "Send an encrypted reply…", - "Send a reply…": "Send a reply…", - "Send an encrypted message…": "Send an encrypted message…", - "Send a message…": "Send a message…", - "The conversation continues here.": "The conversation continues here.", + "Send encrypted reply…": "Send encrypted reply…", + "Send reply…": "Send reply…", + "Send encrypted message…": "Send encrypted message…", + "Send message…": "Send message…", "This room has been replaced and is no longer active.": "This room has been replaced and is no longer active.", + "The conversation continues here.": "The conversation continues here.", "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", @@ -1778,7 +1778,7 @@ "Seen by %(count)s people|one": "Seen by %(count)s person", "Read receipts": "Read receipts", "Recently viewed": "Recently viewed", - "Replying": "Replying", + "Reply to ": "Reply to ", "Room %(name)s": "Room %(name)s", "Recently visited rooms": "Recently visited rooms", "No recently visited rooms": "No recently visited rooms", diff --git a/test/components/views/rooms/MessageComposer-test.tsx b/test/components/views/rooms/MessageComposer-test.tsx index e756a7653c4..d774aa80604 100644 --- a/test/components/views/rooms/MessageComposer-test.tsx +++ b/test/components/views/rooms/MessageComposer-test.tsx @@ -61,7 +61,7 @@ describe("MessageComposer", () => { expect(wrapper.find("SendMessageComposer")).toHaveLength(0); expect(wrapper.find("MessageComposerButtons")).toHaveLength(0); - expect(wrapper.find(".mx_MessageComposer_roomReplaced_header")).toHaveLength(1); + expect(wrapper.find("p").text()).toContain("room has been replaced"); }); }); From 75477882d15f1d21a5382513db19a45183efa885 Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 8 Jun 2022 10:11:14 +0100 Subject: [PATCH 07/10] Revert link color change in composer (#8784) (cherry picked from commit aedbeb299595a29efbfa73a08489118115d3654a) --- res/css/views/rooms/_MessageComposer.scss | 4 ---- src/components/views/rooms/MessageComposer.tsx | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 6de32107478..0d714f68fc0 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -58,10 +58,6 @@ limitations under the License. .mx_VoiceMessagePrimaryContainer { margin-right: $spacing-8; } - - a { - color: $accent; - } } .mx_MessageComposer_autocomplete_wrapper { diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index adba298d73b..781121d57be 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -391,7 +391,7 @@ export default class MessageComposer extends React.Component {   { replacementRoomId && ( { _t("The conversation continues here.") } From 731f4752b7bbe077a3322158456421b4919ab7e1 Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 8 Jun 2022 13:29:16 +0100 Subject: [PATCH 08/10] Fix scroll jump issue with the composer (#8788) (cherry picked from commit f568a76dc6444ef04fe2dc3809c0d8e38f94c079) --- res/css/views/rooms/_SendMessageComposer.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss index 6805f158ed7..efa8a6c841c 100644 --- a/res/css/views/rooms/_SendMessageComposer.scss +++ b/res/css/views/rooms/_SendMessageComposer.scss @@ -31,6 +31,11 @@ limitations under the License. display: flex; flex-direction: column; + /* the below is required, without this some unexpected scroll jump + will occur when erasing the composer content or jumping to voice note + recording */ + min-height: 45px; + .mx_BasicMessageComposer_input { // this will center the contenteditable // in it's parent vertically From 1587561b4d44521c187485db91720e2e3cc1a651 Mon Sep 17 00:00:00 2001 From: Germain Date: Wed, 8 Jun 2022 15:02:15 +0100 Subject: [PATCH 09/10] Fix scroll jump issue with the composer (#8791) (cherry picked from commit 5167521ea42c4593820e02d015b7d20a71bd96aa) --- res/css/views/rooms/_MessageComposer.scss | 5 +++++ res/css/views/rooms/_SendMessageComposer.scss | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 0d714f68fc0..5c34f78a8be 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -27,6 +27,11 @@ limitations under the License. "composer controls" auto / 1fr auto; + /* the below is required, without this some unexpected scroll jump + will occur when erasing the composer content or jumping to voice note + recording */ + min-height: 45px; + .mx_ReplyPreview { grid-area: reply; } diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss index efa8a6c841c..6805f158ed7 100644 --- a/res/css/views/rooms/_SendMessageComposer.scss +++ b/res/css/views/rooms/_SendMessageComposer.scss @@ -31,11 +31,6 @@ limitations under the License. display: flex; flex-direction: column; - /* the below is required, without this some unexpected scroll jump - will occur when erasing the composer content or jumping to voice note - recording */ - min-height: 45px; - .mx_BasicMessageComposer_input { // this will center the contenteditable // in it's parent vertically From 385db61d3f72024d6fd48ac03bc010e14ae691c2 Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski Date: Mon, 13 Jun 2022 13:05:41 +0200 Subject: [PATCH 10/10] Prevent new composer from overflowing from non-breakable text (#8829) (cherry picked from commit 57dff8131c6ecbd708011004928d2c943ad02cab) --- res/css/views/rooms/_MessageComposer.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 5c34f78a8be..41faff2b038 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -37,6 +37,7 @@ limitations under the License. } .mx_MessageComposer_row { + min-width: 0; grid-area: composer; }