Task - replace img icons with svg components (#8963)

* add role=presentation to backdrop panle image

* replace img icons with svg components in InviteDialog

* replace img icon with svg component

* img icons to svg icons in MImageBody

* remove log

* img icon to svg in SecurityRoomSettingsTab

* use shared error message for media message tiles

* remove nbsp

* dont snapshot test entire rtl render response

* use aria-describedby for uploadconfirm preview

* use aria-labelledby instead
pull/28217/head
Kerry 2022-07-06 13:29:26 +02:00 committed by GitHub
parent afa8b01601
commit 7afc8c5869
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 135 additions and 23 deletions

View File

@ -26,6 +26,7 @@
@import "./components/views/location/_ShareType.scss";
@import "./components/views/location/_ZoomButtons.scss";
@import "./components/views/messages/_MBeaconBody.scss";
@import "./components/views/messages/shared/_MediaProcessingError.scss";
@import "./components/views/spaces/_QuickThemeSwitcher.scss";
@import "./structures/_AutoHideScrollbar.scss";
@import "./structures/_BackdropPanel.scss";

View File

@ -0,0 +1,20 @@
/*
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_MediaProcessingError_Icon {
margin-right: $spacing-4;
vertical-align: text-top;
}

View File

@ -36,6 +36,8 @@ export const BackdropPanel: React.FC<IProps> = ({ backgroundImage, blurMultiplie
}
return <div className="mx_BackdropPanel">
<img
role="presentation"
alt=""
style={styles}
className="mx_BackdropPanel--image"
src={backgroundImage} />

View File

@ -21,6 +21,8 @@ import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
import { logger } from "matrix-js-sdk/src/logger";
import { Icon as InfoIcon } from "../../../../res/img/element-icons/info.svg";
import { Icon as EmailPillAvatarIcon } from "../../../../res/img/icon-email-pill-avatar.svg";
import { _t, _td } from "../../../languageHandler";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { makeRoomPermalink, makeUserPermalink } from "../../../utils/permalinks/Permalinks";
@ -186,8 +188,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
const avatarSize = 36;
const avatar = (this.props.member as ThreepidMember).isEmail
? <img
src={require("../../../../res/img/icon-email-pill-avatar.svg").default}
? <EmailPillAvatarIcon
width={avatarSize}
height={avatarSize}
/>
@ -1152,10 +1153,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
if (visibility === "world_readable" || visibility === "shared") {
keySharingWarning =
<p className='mx_InviteDialog_helpText'>
<img
src={require("../../../../res/img/element-icons/info.svg").default}
width={14}
height={14} />
<InfoIcon height={14} width={14} />
{ " " + _t("Invited people will be able to read old messages.") }
</p>;
}

View File

@ -18,6 +18,7 @@ limitations under the License.
import React from 'react';
import filesize from "filesize";
import { Icon as FileIcon } from '../../../../res/img/feather-customised/files.svg';
import { _t } from '../../../languageHandler';
import { getBlobSafeMimeType } from '../../../utils/blobs';
import BaseDialog from "./BaseDialog";
@ -80,11 +81,16 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
title = _t('Upload files');
}
const fileId = `mx-uploadconfirmdialog-${this.props.file.name}`;
let preview: JSX.Element;
let placeholder: JSX.Element;
if (this.mimeType.startsWith("image/")) {
preview = (
<img className="mx_UploadConfirmDialog_imagePreview" src={this.objectUrl} />
<img
className="mx_UploadConfirmDialog_imagePreview"
src={this.objectUrl}
aria-labelledby={fileId}
/>
);
} else if (this.mimeType.startsWith("video/")) {
preview = (
@ -92,9 +98,10 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
);
} else {
placeholder = (
<img
<FileIcon
className="mx_UploadConfirmDialog_fileIcon"
src={require("../../../../res/img/feather-customised/files.svg").default}
height={18}
width={18}
/>
);
}
@ -118,7 +125,7 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
<div className="mx_UploadConfirmDialog_previewOuter">
<div className="mx_UploadConfirmDialog_previewInner">
{ preview && <div>{ preview }</div> }
<div>
<div id={fileId}>
{ placeholder }
{ this.props.file.name } ({ filesize(this.props.file.size) })
</div>

View File

@ -28,6 +28,7 @@ import { PlaybackManager } from "../../../audio/PlaybackManager";
import { isVoiceMessage } from "../../../utils/EventUtils";
import { PlaybackQueue } from "../../../audio/PlaybackQueue";
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
import MediaProcessingError from "./shared/MediaProcessingError";
interface IState {
error?: Error;
@ -93,10 +94,9 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
public render() {
if (this.state.error) {
return (
<span className="mx_MAudioBody">
<img src={require("../../../../res/img/warning.svg").default} width="16" height="16" />
<MediaProcessingError className="mx_MAudioBody">
{ _t("Error processing audio message") }
</span>
</MediaProcessingError>
);
}

View File

@ -38,6 +38,7 @@ import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContex
import { blobIsAnimated, mayBeAnimated } from '../../../utils/Image';
import { presentableTextForFile } from "../../../utils/FileUtils";
import { createReconnectedListener } from '../../../utils/connection';
import MediaProcessingError from './shared/MediaProcessingError';
enum Placeholder {
NoImage,
@ -552,10 +553,9 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
if (this.state.error) {
return (
<div className="mx_MImageBody">
<img src={require("../../../../res/img/warning.svg").default} width="16" height="16" />
<MediaProcessingError className="mx_MImageBody">
{ _t("Error decrypting image") }
</div>
</MediaProcessingError>
);
}

View File

@ -28,6 +28,7 @@ import { IBodyProps } from "./IBodyProps";
import MFileBody from "./MFileBody";
import { ImageSize, suggestedSize as suggestedVideoSize } from "../../../settings/enums/ImageSize";
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
import MediaProcessingError from './shared/MediaProcessingError';
interface IState {
decryptedUrl?: string;
@ -244,10 +245,9 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
if (this.state.error !== null) {
return (
<span className="mx_MVideoBody">
<img src={require("../../../../res/img/warning.svg").default} width="16" height="16" />
<MediaProcessingError className="mx_MVideoBody">
{ _t("Error decrypting video") }
</span>
</MediaProcessingError>
);
}

View File

@ -21,16 +21,16 @@ import { _t } from "../../../languageHandler";
import RecordingPlayback from "../audio_messages/RecordingPlayback";
import MAudioBody from "./MAudioBody";
import MFileBody from "./MFileBody";
import MediaProcessingError from "./shared/MediaProcessingError";
export default class MVoiceMessageBody extends MAudioBody {
// A voice message is an audio file but rendered in a special way.
public render() {
if (this.state.error) {
return (
<span className="mx_MVoiceMessageBody">
<img src={require("../../../../res/img/warning.svg").default} width="16" height="16" />
<MediaProcessingError className="mx_MVoiceMessageBody">
{ _t("Error processing voice message") }
</span>
</MediaProcessingError>
);
}

View File

@ -0,0 +1,33 @@
/*
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 { Icon as WarningIcon } from '../../../../../res/img/warning.svg';
interface Props {
className?: string;
children: React.ReactNode;
}
const MediaProcessingError: React.FC<Props> = ({ className, children }) => (
<span className={className}>
<WarningIcon className='mx_MediaProcessingError_Icon' width="16" height="16" />
{ children }
</span>
);
export default MediaProcessingError;

View File

@ -21,6 +21,7 @@ import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { EventType } from 'matrix-js-sdk/src/@types/event';
import { logger } from "matrix-js-sdk/src/logger";
import { Icon as WarningIcon } from "../../../../../../res/img/warning.svg";
import { _t } from "../../../../../languageHandler";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import Modal from "../../../../../Modal";
@ -231,7 +232,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
if (room.getJoinRule() === JoinRule.Public && !this.state.hasAliases) {
aliasWarning = (
<div className='mx_SecurityRoomSettingsTab_warning'>
<img src={require("../../../../../../res/img/warning.svg").default} width={15} height={15} />
<WarningIcon width={15} height={15} />
<span>
{ _t("To link to this room, please add an address.") }
</span>

View File

@ -0,0 +1,34 @@
/*
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 MediaProcessingError from '../../../../../src/components/views/messages/shared/MediaProcessingError';
describe('<MediaProcessingError />', () => {
const defaultProps = {
className: 'test-classname',
children: 'Something went wrong',
};
const getComponent = (props = {}) =>
render(<MediaProcessingError {...defaultProps} {...props} />);
it('renders', () => {
const { container } = getComponent();
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<MediaProcessingError /> renders 1`] = `
<div>
<span
class="test-classname"
>
<div
class="mx_MediaProcessingError_Icon"
height="16"
width="16"
/>
Something went wrong
</span>
</div>
`;