From 3c9ba3e69f743145bf4caf158738a2278a4b0f2b Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Thu, 20 Oct 2022 10:04:14 +0200 Subject: [PATCH] Replace Icon with webpack loaded SVG (#9464) --- res/css/_components.pcss | 3 +- .../{components/atoms => compound}/_Icon.pcss | 23 +--- .../atoms/_VoiceBroadcastControl.pcss | 27 ++++ res/img/element-icons/Stop.svg | 2 +- res/img/element-icons/live.svg | 41 +----- res/img/element-icons/pause.svg | 4 +- res/img/element-icons/play.svg | 2 +- res/img/voip/call-view/mic-on.svg | 2 +- src/components/atoms/Icon.tsx | 83 ------------ src/i18n/strings/en_EN.json | 6 +- .../components/atoms/LiveBadge.tsx | 4 +- .../atoms/PlaybackControlButton.tsx | 53 -------- ...opButton.tsx => VoiceBroadcastControl.tsx} | 17 ++- .../components/atoms/VoiceBroadcastHeader.tsx | 7 +- .../molecules/VoiceBroadcastPlaybackBody.tsx | 37 +++++- .../molecules/VoiceBroadcastRecordingPip.tsx | 9 +- src/voice-broadcast/index.ts | 3 +- test/components/atoms/Icon-test.tsx | 47 ------- .../atoms/__snapshots__/Icon-test.tsx.snap | 34 ----- .../atoms/PlaybackControlButton-test.tsx | 45 ------- .../components/atoms/StopButton-test.tsx | 45 ------- .../atoms/VoiceBroadcastControl-test.tsx | 55 ++++++++ .../__snapshots__/LiveBadge-test.tsx.snap | 7 +- .../PlaybackControlButton-test.tsx.snap | 55 -------- .../__snapshots__/StopButton-test.tsx.snap | 19 --- .../VoiceBroadcastControl-test.tsx.snap | 16 +++ .../VoiceBroadcastHeader-test.tsx.snap | 28 ++-- .../VoiceBroadcastPlaybackBody-test.tsx | 26 ++-- .../VoiceBroadcastRecordingPip-test.tsx | 2 +- .../VoiceBroadcastPlaybackBody-test.tsx.snap | 121 ++++++++++++------ .../VoiceBroadcastRecordingBody-test.tsx.snap | 14 +- .../VoiceBroadcastRecordingPip-test.tsx.snap | 25 ++-- 32 files changed, 298 insertions(+), 564 deletions(-) rename res/css/{components/atoms => compound}/_Icon.pcss (68%) create mode 100644 res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss delete mode 100644 src/components/atoms/Icon.tsx delete mode 100644 src/voice-broadcast/components/atoms/PlaybackControlButton.tsx rename src/voice-broadcast/components/atoms/{StopButton.tsx => VoiceBroadcastControl.tsx} (68%) delete mode 100644 test/components/atoms/Icon-test.tsx delete mode 100644 test/components/atoms/__snapshots__/Icon-test.tsx.snap delete mode 100644 test/voice-broadcast/components/atoms/PlaybackControlButton-test.tsx delete mode 100644 test/voice-broadcast/components/atoms/StopButton-test.tsx create mode 100644 test/voice-broadcast/components/atoms/VoiceBroadcastControl-test.tsx delete mode 100644 test/voice-broadcast/components/atoms/__snapshots__/PlaybackControlButton-test.tsx.snap delete mode 100644 test/voice-broadcast/components/atoms/__snapshots__/StopButton-test.tsx.snap create mode 100644 test/voice-broadcast/components/atoms/__snapshots__/VoiceBroadcastControl-test.tsx.snap diff --git a/res/css/_components.pcss b/res/css/_components.pcss index b2fcb0dd4f..819afe64a4 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -4,7 +4,7 @@ @import "./_font-sizes.pcss"; @import "./_font-weights.pcss"; @import "./_spacing.pcss"; -@import "./components/atoms/_Icon.pcss"; +@import "./compound/_Icon.pcss"; @import "./components/views/beacon/_BeaconListItem.pcss"; @import "./components/views/beacon/_BeaconStatus.pcss"; @import "./components/views/beacon/_BeaconStatusTooltip.pcss"; @@ -369,6 +369,7 @@ @import "./views/voip/_VideoFeed.pcss"; @import "./voice-broadcast/atoms/_LiveBadge.pcss"; @import "./voice-broadcast/atoms/_PlaybackControlButton.pcss"; +@import "./voice-broadcast/atoms/_VoiceBroadcastControl.pcss"; @import "./voice-broadcast/atoms/_VoiceBroadcastHeader.pcss"; @import "./voice-broadcast/molecules/_VoiceBroadcastPlaybackBody.pcss"; @import "./voice-broadcast/molecules/_VoiceBroadcastRecordingBody.pcss"; diff --git a/res/css/components/atoms/_Icon.pcss b/res/css/compound/_Icon.pcss similarity index 68% rename from res/css/components/atoms/_Icon.pcss rename to res/css/compound/_Icon.pcss index b9d994e43f..88f49f9da0 100644 --- a/res/css/components/atoms/_Icon.pcss +++ b/res/css/compound/_Icon.pcss @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ +/* + * Compound icon + + * {@link https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed} + */ + .mx_Icon { box-sizing: border-box; - display: inline-block; - mask-origin: content-box; - mask-position: center; - mask-repeat: no-repeat; - mask-size: contain; padding: 1px; } @@ -28,15 +29,3 @@ limitations under the License. height: 16px; width: 16px; } - -.mx_Icon_accent { - background-color: $accent; -} - -.mx_Icon_live-badge { - background-color: #fff; -} - -.mx_Icon_compound-secondary-content { - background-color: $secondary-content; -} diff --git a/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss b/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss new file mode 100644 index 0000000000..bf07157a68 --- /dev/null +++ b/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss @@ -0,0 +1,27 @@ +/* +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_VoiceBroadcastControl { + align-items: center; + background-color: $background; + border-radius: 50%; + color: $secondary-content; + display: flex; + height: 32px; + justify-content: center; + margin-bottom: $spacing-8; + width: 32px; +} diff --git a/res/img/element-icons/Stop.svg b/res/img/element-icons/Stop.svg index 29c7a0cef7..d63459e1db 100644 --- a/res/img/element-icons/Stop.svg +++ b/res/img/element-icons/Stop.svg @@ -1,3 +1,3 @@ - + diff --git a/res/img/element-icons/live.svg b/res/img/element-icons/live.svg index 40a7a66677..31341f1ef6 100644 --- a/res/img/element-icons/live.svg +++ b/res/img/element-icons/live.svg @@ -5,54 +5,23 @@ viewBox="0 0 21.799 21.799" fill="none" version="1.1" - id="svg12" - sodipodi:docname="live.svg" - inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> - - + fill="currentColor" /> + fill="currentColor" /> + fill="currentColor" /> + fill="currentColor" /> + fill="currentColor" /> diff --git a/res/img/element-icons/pause.svg b/res/img/element-icons/pause.svg index 293c0a10d8..4b7be99e3b 100644 --- a/res/img/element-icons/pause.svg +++ b/res/img/element-icons/pause.svg @@ -1,4 +1,4 @@ - - + + diff --git a/res/img/element-icons/play.svg b/res/img/element-icons/play.svg index 339e20b729..3443ae01fa 100644 --- a/res/img/element-icons/play.svg +++ b/res/img/element-icons/play.svg @@ -1,3 +1,3 @@ - + diff --git a/res/img/voip/call-view/mic-on.svg b/res/img/voip/call-view/mic-on.svg index 57428a3cd8..317d10b296 100644 --- a/res/img/voip/call-view/mic-on.svg +++ b/res/img/voip/call-view/mic-on.svg @@ -1,3 +1,3 @@ - + diff --git a/src/components/atoms/Icon.tsx b/src/components/atoms/Icon.tsx deleted file mode 100644 index 56d8236250..0000000000 --- a/src/components/atoms/Icon.tsx +++ /dev/null @@ -1,83 +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 from "react"; - -import liveIcon from "../../../res/img/element-icons/live.svg"; -import microphoneIcon from "../../../res/img/voip/call-view/mic-on.svg"; -import pauseIcon from "../../../res/img/element-icons/pause.svg"; -import playIcon from "../../../res/img/element-icons/play.svg"; -import stopIcon from "../../../res/img/element-icons/Stop.svg"; - -export enum IconType { - Live, - Microphone, - Pause, - Play, - Stop, -} - -const iconTypeMap = new Map([ - [IconType.Live, liveIcon], - [IconType.Microphone, microphoneIcon], - [IconType.Pause, pauseIcon], - [IconType.Play, playIcon], - [IconType.Stop, stopIcon], -]); - -export enum IconColour { - Accent = "accent", - LiveBadge = "live-badge", - CompoundSecondaryContent = "compound-secondary-content", -} - -export enum IconSize { - S16 = "16", -} - -interface IconProps { - colour?: IconColour; - size?: IconSize; - type: IconType; -} - -export const Icon: React.FC = ({ - size = IconSize.S16, - colour = IconColour.Accent, - type, - ...rest -}) => { - const classes = [ - "mx_Icon", - `mx_Icon_${size}`, - `mx_Icon_${colour}`, - ]; - - const styles: React.CSSProperties = { - maskImage: `url("${iconTypeMap.get(type)}")`, - WebkitMaskImage: `url("${iconTypeMap.get(type)}")`, - }; - - return ( - - ); -}; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index f322c5de8d..f40e165804 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -644,10 +644,10 @@ "Stop live broadcasting?": "Stop live broadcasting?", "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.": "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.", "Yes, stop broadcast": "Yes, stop broadcast", - "Live": "Live", - "pause voice broadcast": "pause voice broadcast", + "play voice broadcast": "play voice broadcast", "resume voice broadcast": "resume voice broadcast", - "stop voice broadcast": "stop voice broadcast", + "pause voice broadcast": "pause voice broadcast", + "Live": "Live", "Voice broadcast": "Voice broadcast", "Cannot reach homeserver": "Cannot reach homeserver", "Ensure you have a stable internet connection, or get in touch with the server admin": "Ensure you have a stable internet connection, or get in touch with the server admin", diff --git a/src/voice-broadcast/components/atoms/LiveBadge.tsx b/src/voice-broadcast/components/atoms/LiveBadge.tsx index cd2a16e797..ba94aa14a9 100644 --- a/src/voice-broadcast/components/atoms/LiveBadge.tsx +++ b/src/voice-broadcast/components/atoms/LiveBadge.tsx @@ -16,12 +16,12 @@ limitations under the License. import React from "react"; -import { Icon, IconColour, IconType } from "../../../components/atoms/Icon"; +import { Icon as LiveIcon } from "../../../../res/img/element-icons/live.svg"; import { _t } from "../../../languageHandler"; export const LiveBadge: React.FC = () => { return
- + { _t("Live") }
; }; diff --git a/src/voice-broadcast/components/atoms/PlaybackControlButton.tsx b/src/voice-broadcast/components/atoms/PlaybackControlButton.tsx deleted file mode 100644 index b67e6b3e24..0000000000 --- a/src/voice-broadcast/components/atoms/PlaybackControlButton.tsx +++ /dev/null @@ -1,53 +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 from "react"; - -import { VoiceBroadcastPlaybackState } from "../.."; -import { Icon, IconColour, IconType } from "../../../components/atoms/Icon"; -import AccessibleButton from "../../../components/views/elements/AccessibleButton"; -import { _t } from "../../../languageHandler"; - -const stateIconMap = new Map([ - [VoiceBroadcastPlaybackState.Playing, IconType.Pause], - [VoiceBroadcastPlaybackState.Paused, IconType.Play], - [VoiceBroadcastPlaybackState.Stopped, IconType.Play], -]); - -interface Props { - onClick: () => void; - state: VoiceBroadcastPlaybackState; -} - -export const PlaybackControlButton: React.FC = ({ - onClick, - state, -}) => { - const ariaLabel = state === VoiceBroadcastPlaybackState.Playing - ? _t("pause voice broadcast") - : _t("resume voice broadcast"); - - return - - ; -}; diff --git a/src/voice-broadcast/components/atoms/StopButton.tsx b/src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx similarity index 68% rename from src/voice-broadcast/components/atoms/StopButton.tsx rename to src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx index 50abb209d0..238d138698 100644 --- a/src/voice-broadcast/components/atoms/StopButton.tsx +++ b/src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx @@ -16,25 +16,24 @@ limitations under the License. import React from "react"; -import { Icon, IconColour, IconType } from "../../../components/atoms/Icon"; import AccessibleButton from "../../../components/views/elements/AccessibleButton"; -import { _t } from "../../../languageHandler"; interface Props { + icon: React.FC>; + label: string; onClick: () => void; } -export const StopButton: React.FC = ({ +export const VoiceBroadcastControl: React.FC = ({ + icon: Icon, + label, onClick, }) => { return - + ; }; diff --git a/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx b/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx index 5abc4d21e4..c83e8e8a0c 100644 --- a/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx +++ b/src/voice-broadcast/components/atoms/VoiceBroadcastHeader.tsx @@ -15,7 +15,8 @@ import React from "react"; import { Room, RoomMember } from "matrix-js-sdk/src/matrix"; import { LiveBadge } from "../.."; -import { Icon, IconColour, IconType } from "../../../components/atoms/Icon"; +import { Icon as LiveIcon } from "../../../../res/img/element-icons/live.svg"; +import { Icon as MicrophoneIcon } from "../../../../res/img/voip/call-view/mic-on.svg"; import { _t } from "../../../languageHandler"; import RoomAvatar from "../../../components/views/avatars/RoomAvatar"; @@ -34,7 +35,7 @@ export const VoiceBroadcastHeader: React.FC = ({ }) => { const broadcast = showBroadcast ?
- + { _t("Voice broadcast") }
: null; @@ -46,7 +47,7 @@ export const VoiceBroadcastHeader: React.FC = ({ { room.name }
- + { sender.name }
{ broadcast } diff --git a/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx b/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx index 035b3ce6e5..e0634636a7 100644 --- a/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx +++ b/src/voice-broadcast/components/molecules/VoiceBroadcastPlaybackBody.tsx @@ -17,13 +17,16 @@ limitations under the License. import React from "react"; import { - PlaybackControlButton, + VoiceBroadcastControl, VoiceBroadcastHeader, VoiceBroadcastPlayback, VoiceBroadcastPlaybackState, } from "../.."; import Spinner from "../../../components/views/elements/Spinner"; import { useVoiceBroadcastPlayback } from "../../hooks/useVoiceBroadcastPlayback"; +import { Icon as PlayIcon } from "../../../../res/img/element-icons/play.svg"; +import { Icon as PauseIcon } from "../../../../res/img/element-icons/pause.svg"; +import { _t } from "../../../languageHandler"; interface VoiceBroadcastPlaybackBodyProps { playback: VoiceBroadcastPlayback; @@ -40,9 +43,35 @@ export const VoiceBroadcastPlaybackBody: React.FC - : ; + let control: React.ReactNode; + + if (playbackState === VoiceBroadcastPlaybackState.Buffering) { + control = ; + } else { + let controlIcon: React.FC>; + let controlLabel: string; + + switch (playbackState) { + case VoiceBroadcastPlaybackState.Stopped: + controlIcon = PlayIcon; + controlLabel = _t("play voice broadcast"); + break; + case VoiceBroadcastPlaybackState.Paused: + controlIcon = PlayIcon; + controlLabel = _t("resume voice broadcast"); + break; + case VoiceBroadcastPlaybackState.Playing: + controlIcon = PauseIcon; + controlLabel = _t("pause voice broadcast"); + break; + } + + control = ; + } return (
diff --git a/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx b/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx index c7604b7d90..7178f65965 100644 --- a/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx +++ b/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx @@ -17,11 +17,12 @@ limitations under the License. import React from "react"; import { - StopButton, + VoiceBroadcastControl, VoiceBroadcastRecording, } from "../.."; import { useVoiceBroadcastRecording } from "../../hooks/useVoiceBroadcastRecording"; import { VoiceBroadcastHeader } from "../atoms/VoiceBroadcastHeader"; +import { Icon as StopIcon } from "../../../../res/img/element-icons/Stop.svg"; interface VoiceBroadcastRecordingPipProps { recording: VoiceBroadcastRecording; @@ -45,7 +46,11 @@ export const VoiceBroadcastRecordingPip: React.FC
- +
; }; diff --git a/src/voice-broadcast/index.ts b/src/voice-broadcast/index.ts index 8f01c089c6..10329e224d 100644 --- a/src/voice-broadcast/index.ts +++ b/src/voice-broadcast/index.ts @@ -26,8 +26,7 @@ export * from "./models/VoiceBroadcastRecording"; export * from "./audio/VoiceBroadcastRecorder"; export * from "./components/VoiceBroadcastBody"; export * from "./components/atoms/LiveBadge"; -export * from "./components/atoms/PlaybackControlButton"; -export * from "./components/atoms/StopButton"; +export * from "./components/atoms/VoiceBroadcastControl"; export * from "./components/atoms/VoiceBroadcastHeader"; export * from "./components/molecules/VoiceBroadcastPlaybackBody"; export * from "./components/molecules/VoiceBroadcastRecordingBody"; diff --git a/test/components/atoms/Icon-test.tsx b/test/components/atoms/Icon-test.tsx deleted file mode 100644 index 57e6e3990c..0000000000 --- a/test/components/atoms/Icon-test.tsx +++ /dev/null @@ -1,47 +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 from "react"; -import { render } from "@testing-library/react"; - -import { Icon, IconColour, IconSize, IconType } from "../../../src/components/atoms/Icon"; - -describe("Icon", () => { - it.each([ - IconColour.Accent, - IconColour.LiveBadge, - ])("should render the colour %s", (colour: IconColour) => { - const { container } = render( - , - ); - expect(container).toMatchSnapshot(); - }); - - it.each([ - IconSize.S16, - ])("should render the size %s", (size: IconSize) => { - const { container } = render( - , - ); - expect(container).toMatchSnapshot(); - }); -}); diff --git a/test/components/atoms/__snapshots__/Icon-test.tsx.snap b/test/components/atoms/__snapshots__/Icon-test.tsx.snap deleted file mode 100644 index c30b4ba332..0000000000 --- a/test/components/atoms/__snapshots__/Icon-test.tsx.snap +++ /dev/null @@ -1,34 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Icon should render the colour accent 1`] = ` -
-