Revert recent composer changes (#8840)
* Revert "Prevent new composer from overflowing from non-breakable text (#8829)" This reverts commit57dff8131c
. * Revert "Fix scroll jump issue with the composer (#8791)" This reverts commit5167521ea4
. * Revert "Fix scroll jump issue with the composer (#8788)" This reverts commitf568a76dc6
. * Revert "Revert link color change in composer (#8784)" This reverts commitaedbeb2995
. * Revert "Improve composer visiblity (#8578)" This reverts commitf14374a51c
.
|
@ -84,7 +84,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";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -20,50 +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_MessageComposer_replaced_wrapper {
|
||||
margin-left: auto;
|
||||
margin-right: 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_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 {
|
||||
min-width: 0;
|
||||
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_VoiceMessagePrimaryContainer {
|
||||
margin-right: $spacing-8;
|
||||
}
|
||||
.mx_MessageComposer_roomReplaced_header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_autocomplete_wrapper {
|
||||
|
@ -75,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 {
|
||||
|
@ -121,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 {
|
||||
|
@ -166,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 {
|
||||
|
@ -214,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;
|
||||
|
@ -238,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;
|
||||
|
@ -312,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;
|
||||
|
||||
|
@ -428,6 +358,10 @@ limitations under the License.
|
|||
.mx_MessageComposer_input {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_noperm_error {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -437,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
.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;
|
||||
|
||||
> svg {
|
||||
width: 1em;
|
||||
vertical-align: middle;
|
||||
margin-right: $spacing-8;
|
||||
}
|
||||
.mx_ReplyPreview_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
column-gap: 8px;
|
||||
|
||||
.mx_CancelButton {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<path d="M9.74464309,-3.02908503 L8.14106175,-3.02908503 L8.14106175,8.19448443 L-3.03028759,8.19448443 L-3.03028759,9.7978515 L8.14106175,9.7978515 L8.14106175,20.9685098 L9.74464309,20.9685098 L9.74464309,9.7978515 L20.9697124,9.7978515 L20.9697124,8.19448443 L9.74464309,8.19448443 L9.74464309,-3.02908503" id="Fill-108" opacity="0.9" fill="currentColor" sketch:type="MSShapeGroup" transform="translate(8.969712, 8.969712) rotate(-315.000000) translate(-8.969712, -8.969712) "></path>
|
||||
<path d="M9.74464309,-3.02908503 L8.14106175,-3.02908503 L8.14106175,8.19448443 L-3.03028759,8.19448443 L-3.03028759,9.7978515 L8.14106175,9.7978515 L8.14106175,20.9685098 L9.74464309,20.9685098 L9.74464309,9.7978515 L20.9697124,9.7978515 L20.9697124,8.19448443 L9.74464309,8.19448443 L9.74464309,-3.02908503" id="Fill-108" opacity="0.9" fill="#454545" sketch:type="MSShapeGroup" transform="translate(8.969712, 8.969712) rotate(-315.000000) translate(-8.969712, -8.969712) "></path>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
@ -1,4 +1,4 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.0663 14.25H11.636C13.4938 14.25 14.9998 12.683 14.9998 10.75C14.9998 8.817 13.4938 7.25 11.636 7.25H4.53369" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M6.52417 3.75L3.00006 7.28553L6.52417 10.8211" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10.0663 14.25H11.636C13.4938 14.25 14.9998 12.683 14.9998 10.75C14.9998 8.817 13.4938 7.25 11.636 7.25H4.53369" stroke="black" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M6.52417 3.75L3.00006 7.28553L6.52417 10.8211" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 423 B |
|
@ -1,3 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM10 12C10 12.5523 10.4477 13 11 13V16.5C11 17.0523 11.4477 17.5 12 17.5H13.5C14.0523 17.5 14.5 17.0523 14.5 16.5C14.5 15.9477 14.0523 15.5 13.5 15.5H13V12C13 11.4477 12.5523 11 12 11H11C10.4477 11 10 11.4477 10 12ZM12 10C12.8284 10 13.5 9.32843 13.5 8.5C13.5 7.67157 12.8284 7 12 7C11.1716 7 10.5 7.67157 10.5 8.5C10.5 9.32843 11.1716 10 12 10Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM10 12C10 12.5523 10.4477 13 11 13V16.5C11 17.0523 11.4477 17.5 12 17.5H13.5C14.0523 17.5 14.5 17.0523 14.5 16.5C14.5 15.9477 14.0523 15.5 13.5 15.5H13V12C13 11.4477 12.5523 11 12 11H11C10.4477 11 10 11.4477 10 12ZM12 10C12.8284 10 13.5 9.32843 13.5 8.5C13.5 7.67157 12.8284 7 12 7C11.1716 7 10.5 7.67157 10.5 8.5C10.5 9.32843 11.1716 10 12 10Z" fill="black"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 630 B |
|
@ -1,4 +1,4 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.999756 0.999756L8.99975 8.99975" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M9.00049 0.999756L1.00049 8.99975" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M0.999756 0.999756L8.99975 8.99975" stroke="#737D8C" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M9.00049 0.999756L1.00049 8.99975" stroke="#737D8C" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 310 B |
|
@ -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<typeof AccessibleButton>) {
|
||||
const classNames = classnames("mx_CancelButton", props.className ?? "");
|
||||
const vars = {
|
||||
"--size": `${props.size}px`,
|
||||
} as React.CSSProperties;
|
||||
|
||||
return <AccessibleButton
|
||||
{...props}
|
||||
className={classNames}
|
||||
style={vars}
|
||||
>
|
||||
<CancelIcon />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
CancelButton.defaultProps = {
|
||||
size: "16",
|
||||
};
|
|
@ -28,14 +28,9 @@ interface IProps {
|
|||
onClick?(): void;
|
||||
colored?: boolean;
|
||||
emphasizeDisplayName?: boolean;
|
||||
as?: string;
|
||||
}
|
||||
|
||||
export default class DisambiguatedProfile extends React.Component<IProps> {
|
||||
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<IProps> {
|
|||
[colorClass]: true,
|
||||
});
|
||||
|
||||
return React.createElement(this.props.as, {
|
||||
className: "mx_DisambiguatedProfile",
|
||||
onClick,
|
||||
}, <>
|
||||
<span className={displayNameClasses} dir="auto">
|
||||
{ rawDisplayName }
|
||||
</span>
|
||||
{ mxidElement }
|
||||
</>);
|
||||
return (
|
||||
<div className="mx_DisambiguatedProfile" onClick={onClick}>
|
||||
<span className={displayNameClasses} dir="auto">
|
||||
{ rawDisplayName }
|
||||
</span>
|
||||
{ mxidElement }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,17 +27,12 @@ import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
|||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
onClick?(): void;
|
||||
as?: string;
|
||||
}
|
||||
|
||||
export default class SenderProfile extends React.PureComponent<IProps> {
|
||||
public static contextType = MatrixClientContext;
|
||||
public context!: React.ContextType<typeof MatrixClientContext>;
|
||||
|
||||
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<IProps> {
|
|||
member={member}
|
||||
colored={true}
|
||||
emphasizeDisplayName={true}
|
||||
as={this.props.as}
|
||||
/>
|
||||
);
|
||||
} }
|
||||
|
|
|
@ -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<IProps, IState> {
|
|||
} 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<IProps, IState> {
|
|||
};
|
||||
|
||||
public render() {
|
||||
const controls = [];
|
||||
const controls = [
|
||||
this.props.e2eStatus ?
|
||||
<E2EIcon key="e2eIcon" status={this.props.e2eStatus} className="mx_MessageComposer_e2eIcon" /> :
|
||||
null,
|
||||
];
|
||||
|
||||
let menuPosition: AboveLeftOf | undefined;
|
||||
if (this.ref.current) {
|
||||
|
@ -363,8 +363,6 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
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<IProps, IState> {
|
|||
toggleStickerPickerOpen={this.toggleStickerPickerOpen}
|
||||
/>,
|
||||
);
|
||||
} else if (roomReplaced) {
|
||||
|
||||
controls.push(<VoiceRecordComposerTile
|
||||
key="controls_voice_record"
|
||||
ref={this.voiceRecordingButton}
|
||||
room={this.props.room} />);
|
||||
} else if (this.context.tombstone) {
|
||||
const replacementRoomId = this.context.tombstone.getContent()['replacement_room'];
|
||||
|
||||
controls.push(<p key="room_replaced">
|
||||
<InfoIcon width={24} />
|
||||
|
||||
{ _t("This room has been replaced and is no longer active.") }
|
||||
|
||||
{ replacementRoomId && (
|
||||
<a href={makeRoomPermalink(replacementRoomId)}
|
||||
className="mx_linkButton"
|
||||
onClick={this.onTombstoneClick}
|
||||
>
|
||||
{ _t("The conversation continues here.") }
|
||||
</a>
|
||||
) }
|
||||
</p>);
|
||||
const continuesLink = replacementRoomId ? (
|
||||
<a href={makeRoomPermalink(replacementRoomId)}
|
||||
className="mx_MessageComposer_roomReplaced_link"
|
||||
onClick={this.onTombstoneClick}
|
||||
>
|
||||
{ _t("The conversation continues here.") }
|
||||
</a>
|
||||
) : '';
|
||||
|
||||
controls.push(<div className="mx_MessageComposer_replaced_wrapper" key="room_replaced">
|
||||
<div className="mx_MessageComposer_replaced_valign">
|
||||
<img className="mx_MessageComposer_roomReplaced_icon"
|
||||
src={require("../../../../res/img/room_replaced.svg").default}
|
||||
/>
|
||||
<span className="mx_MessageComposer_roomReplaced_header">
|
||||
{ _t("This room has been replaced and is no longer active.") }
|
||||
</span><br />
|
||||
{ continuesLink }
|
||||
</div>
|
||||
</div>);
|
||||
} else {
|
||||
controls.push(
|
||||
<div key="controls_error" className="mx_MessageComposer_noperm_error">
|
||||
|
@ -432,12 +441,6 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
|
||||
const showSendButton = !this.state.isComposerEmpty || this.state.haveRecording;
|
||||
|
||||
if (this.props.e2eStatus) {
|
||||
controls.push(
|
||||
<E2EIcon key="e2eIcon" status={this.props.e2eStatus} className="mx_MessageComposer_e2eIcon" />,
|
||||
);
|
||||
}
|
||||
|
||||
const classes = classNames({
|
||||
"mx_MessageComposer": true,
|
||||
"mx_MessageComposer--compact": this.props.compact,
|
||||
|
@ -451,17 +454,8 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
<ReplyPreview
|
||||
replyToEvent={this.props.replyToEvent}
|
||||
permalinkCreator={this.props.permalinkCreator} />
|
||||
<div
|
||||
className="mx_MessageComposer_row"
|
||||
aria-disabled={!canSendMessages && !roomReplaced}
|
||||
data-notice={roomReplaced}>
|
||||
<div className="mx_MessageComposer_row">
|
||||
{ controls }
|
||||
</div>
|
||||
<div className="mx_MessageComposer_controls">
|
||||
{ canSendMessages && <VoiceRecordComposerTile
|
||||
key="controls_voice_record"
|
||||
ref={this.voiceRecordingButton}
|
||||
room={this.props.room} /> }
|
||||
{ canSendMessages && <MessageComposerButtons
|
||||
addEmoji={this.addEmoji}
|
||||
haveRecording={this.state.haveRecording}
|
||||
|
@ -481,20 +475,13 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
showStickersButton={this.state.showStickersButton}
|
||||
toggleButtonMenu={this.toggleButtonMenu}
|
||||
/> }
|
||||
<CSSTransition
|
||||
in={showSendButton}
|
||||
classNames="mx_MessageComposer_sendMessageWrapper"
|
||||
addEndListener={() => {}}
|
||||
>
|
||||
<div className='mx_MessageComposer_sendMessageWrapper'>
|
||||
<SendButton
|
||||
key="controls_send"
|
||||
onClick={this.sendMessage}
|
||||
title={this.state.haveRecording ? _t("Send voice message") : undefined}
|
||||
aria-hidden={!showSendButton}
|
||||
/>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
{ showSendButton && (
|
||||
<SendButton
|
||||
key="controls_send"
|
||||
onClick={this.sendMessage}
|
||||
title={this.state.haveRecording ? _t("Send voice message") : undefined}
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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<IProps> {
|
|||
if (!this.props.replyToEvent) return null;
|
||||
|
||||
return <div className="mx_ReplyPreview">
|
||||
<div className="mx_ReplyPreview_header">
|
||||
<ReplyIcon />
|
||||
{ _t('Reply to <User />', {}, {
|
||||
'User': () => <SenderProfile mxEvent={this.props.replyToEvent} as="span" />,
|
||||
}) }
|
||||
|
||||
<CancelButton onClick={() => cancelQuoting(this.context.timelineRenderingType)} />
|
||||
<div className="mx_ReplyPreview_section">
|
||||
<div className="mx_ReplyPreview_header">
|
||||
<span>{ _t('Replying') }</span>
|
||||
<AccessibleButton
|
||||
className="mx_ReplyPreview_header_cancel"
|
||||
onClick={() => cancelQuoting(this.context.timelineRenderingType)}
|
||||
/>
|
||||
</div>
|
||||
<ReplyTile
|
||||
mxEvent={this.props.replyToEvent}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
/>
|
||||
</div>
|
||||
<ReplyTile
|
||||
mxEvent={this.props.replyToEvent}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
showSenderProfile={false}
|
||||
/>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ interface IProps {
|
|||
getRelationsForEvent?: (
|
||||
(eventId: string, relationType: string, eventType: string) => Relations
|
||||
);
|
||||
showSenderProfile?: boolean;
|
||||
}
|
||||
|
||||
export default class ReplyTile extends React.PureComponent<IProps> {
|
||||
|
@ -52,7 +51,6 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
|
||||
static defaultProps = {
|
||||
onHeightChanged: () => {},
|
||||
showSenderProfile: true,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -138,8 +136,7 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
|
||||
let sender;
|
||||
const needsSenderProfile = (
|
||||
this.props.showSenderProfile
|
||||
&& !isInfoMessage
|
||||
!isInfoMessage
|
||||
&& msgType !== MsgType.Image
|
||||
&& evType !== EventType.Sticker
|
||||
&& evType !== EventType.RoomCreate
|
||||
|
|
|
@ -1700,12 +1700,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",
|
||||
|
@ -1758,7 +1758,7 @@
|
|||
"Seen by %(count)s people|one": "Seen by %(count)s person",
|
||||
"Read receipts": "Read receipts",
|
||||
"Recently viewed": "Recently viewed",
|
||||
"Reply to <User />": "Reply to <User />",
|
||||
"Replying": "Replying",
|
||||
"Room %(name)s": "Room %(name)s",
|
||||
"Recently visited rooms": "Recently visited rooms",
|
||||
"No recently visited rooms": "No recently visited rooms",
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
|