diff --git a/playwright/snapshots/crypto/crypto.spec.ts/composer-e2e-icon-linux.png b/playwright/snapshots/crypto/crypto.spec.ts/composer-e2e-icon-linux.png index f954734eb1..1adc91faf0 100644 Binary files a/playwright/snapshots/crypto/crypto.spec.ts/composer-e2e-icon-linux.png and b/playwright/snapshots/crypto/crypto.spec.ts/composer-e2e-icon-linux.png differ diff --git a/res/css/views/rooms/_E2EIcon.pcss b/res/css/views/rooms/_E2EIcon.pcss index 7f399ab45f..efa8b1faff 100644 --- a/res/css/views/rooms/_E2EIcon.pcss +++ b/res/css/views/rooms/_E2EIcon.pcss @@ -9,54 +9,25 @@ Please see LICENSE files in the repository root for full details. width: 16px; height: 16px; margin: 0 9px; - position: relative; display: block; + + svg { + width: inherit; + height: inherit; + display: block; + } } .mx_E2EIcon.mx_E2EIcon_inline { display: inline-block; } -.mx_E2EIcon_warning, -.mx_E2EIcon_normal, -.mx_E2EIcon_verified { - &::before, - &::after { - content: ""; - display: block; - position: absolute; - inset: 0; - mask-repeat: no-repeat; - mask-position: center; - mask-size: contain; - } +.mx_E2EIcon_warning { + color: $e2e-warning-color; } -/* transparent-looking border surrounding the shield for when overlain over avatars */ -.mx_E2EIcon_bordered { - mask-image: url("@vector-im/compound-design-tokens/icons/lock-solid.svg"); - background-color: $header-panel-bg-color; - mask-size: 100%; - - /* shrink the actual badge */ - &::after { - mask-size: 75%; - } - /* shrink the infill of the badge */ - &::before { - mask-size: 60%; - background: var(--cpd-color-bg-canvas-default); - } -} - -.mx_E2EIcon_warning::after { - mask-image: url("@vector-im/compound-design-tokens/icons/error-solid.svg"); - background-color: $e2e-warning-color; -} - -.mx_E2EIcon_normal::after { - mask-image: url("@vector-im/compound-design-tokens/icons/lock-solid.svg"); - background-color: var(--cpd-color-icon-tertiary); +.mx_E2EIcon_normal { + color: var(--cpd-color-icon-tertiary); } .mx_E2EIcon_verified, @@ -66,7 +37,6 @@ Please see LICENSE files in the repository root for full details. } } -.mx_E2EIcon_verified::after { - mask-image: url("@vector-im/compound-design-tokens/icons/shield.svg"); - background-color: $e2e-verified-color; +.mx_E2EIcon_verified { + color: $e2e-verified-color; } diff --git a/res/css/views/rooms/_MessageComposer.pcss b/res/css/views/rooms/_MessageComposer.pcss index 0b11025b1e..0fff6d8721 100644 --- a/res/css/views/rooms/_MessageComposer.pcss +++ b/res/css/views/rooms/_MessageComposer.pcss @@ -38,11 +38,6 @@ Please see LICENSE files in the repository root for full details. font-weight: bold; } -.mx_MessageComposer_autocomplete_wrapper { - position: relative; - height: 0; -} - .mx_MessageComposer_row { display: flex; flex-direction: row; @@ -67,19 +62,20 @@ Please see LICENSE files in the repository root for full details. } } -.mx_MessageComposer_composecontrols { - width: 100%; -} .mx_MessageComposer_e2eIconWrapper { height: 12px; /* Match the height of the E2E icon for alignment */ -} -.mx_MessageComposer_e2eIcon.mx_E2EIcon { + width: 12px; position: absolute; left: 20px; + top: 22px; margin-right: 0; /* Counteract the E2EIcon class */ margin-left: 3px; /* Counteract the E2EIcon class */ - width: 12px; - height: 12px; + + .mx_MessageComposer_e2eIcon { + margin: 0; + width: inherit; + height: inherit; + } } .mx_MessageComposer_noperm_error { @@ -92,13 +88,6 @@ Please see LICENSE files in the repository root for full details. justify-content: center; } -.mx_MessageComposer_input_wrapper { - flex: 1; - display: flex; - flex-direction: column; - cursor: text; -} - .mx_MessageComposer_input { flex: 1; vertical-align: middle; @@ -145,38 +134,6 @@ Please see LICENSE files in the repository root for full details. } } -.mx_MessageComposer_editor { - width: 100%; - max-height: 120px; - min-height: 19px; - overflow-y: auto; - overflow-x: hidden; - word-break: break-word; - - /* FIXME: rather unpleasant hack to get rid of

margins. */ - /* really we should be mixing in markdown-body from github-markdown-css instead */ - > :first-child { - margin-top: 0 !important; - } - - > :last-child { - margin-bottom: 0 !important; - } -} - -@keyframes visualbell { - from { - background-color: $visual-bell-bg-color; - } - to { - background-color: $background; - } -} - -.mx_MessageComposer_input_error { - animation: 0.2s visualbell; -} - .mx_MessageComposer_button_highlight { @mixin composerButtonHighLight; } @@ -198,10 +155,6 @@ Please see LICENSE files in the repository root for full details. z-index: 2; } } - - &.mx_MessageComposer_hangup:not(.mx_AccessibleButton_disabled)::before { - background-color: $alert; - } } .mx_MessageComposer_wysiwyg { .mx_MessageComposer_wrapper { @@ -237,10 +190,6 @@ Please see LICENSE files in the repository root for full details. z-index: 2; } } - - &.mx_MessageComposer_hangup:not(.mx_AccessibleButton_disabled)::before { - background-color: $alert; - } } } @@ -322,6 +271,10 @@ Please see LICENSE files in the repository root for full details. padding: 0 0 0 25px; } + .mx_MessageComposer_e2eIconWrapper { + left: 0; + } + &:not(.mx_MessageComposer_e2eStatus) { .mx_MessageComposer_wrapper { padding: 0; diff --git a/src/components/views/rooms/E2EIcon.tsx b/src/components/views/rooms/E2EIcon.tsx index cd8aeee55a..72b4b36bd3 100644 --- a/src/components/views/rooms/E2EIcon.tsx +++ b/src/components/views/rooms/E2EIcon.tsx @@ -10,6 +10,7 @@ Please see LICENSE files in the repository root for full details. import React, { type JSX, type ComponentProps, type CSSProperties } from "react"; import classNames from "classnames"; import { Tooltip } from "@vector-im/compound-web"; +import { ErrorSolidIcon, ShieldIcon, LockSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import { _t, _td, type TranslationKey } from "../../../languageHandler"; import AccessibleButton from "../elements/AccessibleButton"; @@ -32,31 +33,20 @@ interface Props { onClick?: () => void; hideTooltip?: boolean; tooltipPlacement?: ComponentProps["placement"]; - bordered?: boolean; status: E2EStatus; isUser?: boolean; } -const E2EIcon: React.FC = ({ - isUser, - status, - className, - size, - onClick, - hideTooltip, - tooltipPlacement, - bordered, -}) => { - const classes = classNames( - { - mx_E2EIcon: true, - mx_E2EIcon_bordered: bordered, - mx_E2EIcon_warning: status === E2EStatus.Warning, - mx_E2EIcon_normal: status === E2EStatus.Normal, - mx_E2EIcon_verified: status === E2EStatus.Verified, - }, - className, - ); +const icons: Record = { + [E2EStatus.Warning]: , + [E2EStatus.Normal]: , + [E2EStatus.Verified]: , +}; + +const E2EIcon: React.FC = ({ isUser, status, className, size, onClick, hideTooltip, tooltipPlacement }) => { + const icon = icons[status]; + + const classes = classNames("mx_E2EIcon", className); let e2eTitle: TranslationKey | undefined; if (isUser) { @@ -74,19 +64,17 @@ const E2EIcon: React.FC = ({ let content: JSX.Element; if (onClick) { - content = ; + content = ( + + {icon} + + ); } else { - // Verified and warning icon have a transparent cutout, so add a white background. - // The normal icon already has the correct shape and size, so reuse that. - if (status === E2EStatus.Verified || status === E2EStatus.Warning) { - content = ( -

-
-
- ); - } else { - content =
; - } + content = ( +
+ {icon} +
+ ); } if (!e2eTitle || hideTooltip) { diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index 80cda285c8..d5ec1872f9 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -533,8 +533,8 @@ export class MessageComposer extends React.Component { @@ -544,7 +544,12 @@ export class MessageComposer extends React.Component { } else if (this.props.e2eStatus !== E2EStatus.Normal) { leftIcon = (
- +
); } @@ -587,14 +592,20 @@ export class MessageComposer extends React.Component { ); } + const isTooltipOpen = Boolean(this.state.recordingTimeLeftSeconds); + const secondsLeft = this.state.recordingTimeLeftSeconds + ? Math.round(this.state.recordingTimeLeftSeconds) + : 0; controls.push( - , + + + , ); } else if (this.context.tombstone) { const replacementRoomId = this.context.tombstone.getContent()["replacement_room"]; @@ -636,9 +647,6 @@ export class MessageComposer extends React.Component { ); } - const isTooltipOpen = Boolean(this.state.recordingTimeLeftSeconds); - const secondsLeft = this.state.recordingTimeLeftSeconds ? Math.round(this.state.recordingTimeLeftSeconds) : 0; - const threadId = this.props.relation?.rel_type === THREAD_RELATION_TYPE.name ? this.props.relation.event_id : null; @@ -663,55 +671,51 @@ export class MessageComposer extends React.Component { }); return ( - -
-
- - -
- {leftIcon} - {composer} -
- {controls} - {canSendMessages && ( - - )} - {showSendButton && ( - - )} -
+
+
+ + +
+ {leftIcon} + {composer} +
+ {controls} + {canSendMessages && ( + + )} + {showSendButton && ( + + )}
- +
); } } diff --git a/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx b/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx index e120a76c28..dac930e6e1 100644 --- a/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx +++ b/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx @@ -68,7 +68,7 @@ export default function SendWysiwygComposer({ /> ); } else if (e2eStatus !== E2EStatus.Normal) { - leftIcon = ; + leftIcon = ; } return ( diff --git a/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap b/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap index cd276bbed9..1a0d7722b2 100644 --- a/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap +++ b/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap @@ -363,13 +363,13 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] = >
-
+ + +
@@ -3264,13 +3276,13 @@ exports[`RoomView video rooms should render joined video room view 1`] = ` > should display the dialog for the device of a id="mx_BaseDialog_title" >
-
+ + +
Not Trusted @@ -102,13 +111,22 @@ exports[` should display the dialog for the device of t id="mx_BaseDialog_title" >
-
+ + +
Not Trusted diff --git a/test/unit-tests/components/views/dialogs/__snapshots__/VerificationRequestDialog-test.tsx.snap b/test/unit-tests/components/views/dialogs/__snapshots__/VerificationRequestDialog-test.tsx.snap index 9cf96c255c..54d661c1a8 100644 --- a/test/unit-tests/components/views/dialogs/__snapshots__/VerificationRequestDialog-test.tsx.snap +++ b/test/unit-tests/components/views/dialogs/__snapshots__/VerificationRequestDialog-test.tsx.snap @@ -32,13 +32,24 @@ exports[`VerificationRequestDialog After scanning QR, shows confirmation dialog Check again on your other device to finish verification.

-
+ + +
-
+ + +
should render a single device - signed by owner 1`] = ` Verification status:
+ > + + + +
Signed by owner
@@ -130,12 +143,21 @@ exports[` should render a single device - unsigned 1`] = ` Verification status:
-
+ + +
Not signed by owner @@ -225,12 +247,23 @@ exports[` should render a single device - verified by cross-signing 1`] Verification status:
-
+ + +
Verified by cross-signing @@ -323,12 +356,23 @@ exports[` should render a single user 1`] = ` Verification status:
-
+ + +
Verified @@ -344,12 +388,23 @@ exports[` should render a single user 1`] = ` class="mx_DevTools_button" >
-
+ + +
VERIFIED @@ -359,9 +414,22 @@ exports[` should render a single user 1`] = ` class="mx_DevTools_button" >
+ > + + + +
SIGNED @@ -370,12 +438,21 @@ exports[` should render a single user 1`] = ` class="mx_DevTools_button" >
-
+ + +
UNSIGNED diff --git a/test/unit-tests/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx b/test/unit-tests/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx index a9a66d72f3..c38b95a1a5 100644 --- a/test/unit-tests/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx +++ b/test/unit-tests/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx @@ -340,7 +340,14 @@ describe("SendWysiwygComposer", () => { const leftIcon = screen.getByTestId("e2e-icon"); // Then expect(leftIcon).toBeInTheDocument(); - expect(leftIcon).toHaveClass(expectedClass ? `mx_E2EIcon ${expectedClass}` : `mx_E2EIcon`); + expect(leftIcon).toHaveClass("mx_E2EIcon"); + if (expectedClass) { + // eslint-disable-next-line jest/no-conditional-expect + expect(leftIcon.querySelector("svg")).toHaveClass(expectedClass); + } else { + // eslint-disable-next-line jest/no-conditional-expect + expect(leftIcon.querySelector("svg")).not.toBeInTheDocument(); + } }); }, );