Replace Icon with webpack loaded SVG (#9464)

This commit is contained in:
Michael Weimann 2022-10-20 10:04:14 +02:00 committed by GitHub
parent 6fe8744e4d
commit 3c9ba3e69f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 298 additions and 564 deletions

View file

@ -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<IconProps> = ({
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 (
<i
aria-hidden
className={classes.join(" ")}
role="presentation"
style={styles}
{...rest}
/>
);
};

View file

@ -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",

View file

@ -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 <div className="mx_LiveBadge">
<Icon type={IconType.Live} colour={IconColour.LiveBadge} />
<LiveIcon className="mx_Icon mx_Icon_16" />
{ _t("Live") }
</div>;
};

View file

@ -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<Props> = ({
onClick,
state,
}) => {
const ariaLabel = state === VoiceBroadcastPlaybackState.Playing
? _t("pause voice broadcast")
: _t("resume voice broadcast");
return <AccessibleButton
className="mx_BroadcastPlaybackControlButton"
onClick={onClick}
aria-label={ariaLabel}
>
<Icon
colour={IconColour.CompoundSecondaryContent}
type={stateIconMap.get(state)}
/>
</AccessibleButton>;
};

View file

@ -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<React.SVGProps<SVGSVGElement>>;
label: string;
onClick: () => void;
}
export const StopButton: React.FC<Props> = ({
export const VoiceBroadcastControl: React.FC<Props> = ({
icon: Icon,
label,
onClick,
}) => {
return <AccessibleButton
className="mx_BroadcastPlaybackControlButton"
className="mx_VoiceBroadcastControl"
onClick={onClick}
aria-label={_t("stop voice broadcast")}
aria-label={label}
>
<Icon
colour={IconColour.CompoundSecondaryContent}
type={IconType.Stop}
/>
<Icon className="mx_Icon mx_Icon_16" />
</AccessibleButton>;
};

View file

@ -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<VoiceBroadcastHeaderProps> = ({
}) => {
const broadcast = showBroadcast
? <div className="mx_VoiceBroadcastHeader_line">
<Icon type={IconType.Live} colour={IconColour.CompoundSecondaryContent} />
<LiveIcon className="mx_Icon mx_Icon_16" />
{ _t("Voice broadcast") }
</div>
: null;
@ -46,7 +47,7 @@ export const VoiceBroadcastHeader: React.FC<VoiceBroadcastHeaderProps> = ({
{ room.name }
</div>
<div className="mx_VoiceBroadcastHeader_line">
<Icon type={IconType.Microphone} colour={IconColour.CompoundSecondaryContent} />
<MicrophoneIcon className="mx_Icon mx_Icon_16" />
<span>{ sender.name }</span>
</div>
{ broadcast }

View file

@ -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<VoiceBroadcastPlaybackBodyProp
playbackState,
} = useVoiceBroadcastPlayback(playback);
const control = playbackState === VoiceBroadcastPlaybackState.Buffering
? <Spinner />
: <PlaybackControlButton onClick={toggle} state={playbackState} />;
let control: React.ReactNode;
if (playbackState === VoiceBroadcastPlaybackState.Buffering) {
control = <Spinner />;
} else {
let controlIcon: React.FC<React.SVGProps<SVGSVGElement>>;
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 = <VoiceBroadcastControl
label={controlLabel}
icon={controlIcon}
onClick={toggle}
/>;
}
return (
<div className="mx_VoiceBroadcastPlaybackBody">

View file

@ -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<VoiceBroadcastRecordingPipProp
/>
<hr className="mx_VoiceBroadcastRecordingPip_divider" />
<div className="mx_VoiceBroadcastRecordingPip_controls">
<StopButton onClick={stopRecording} />
<VoiceBroadcastControl
icon={StopIcon}
label="Stop Recording"
onClick={stopRecording}
/>
</div>
</div>;
};

View file

@ -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";