Merge branch 'develop' into dbkr/stateafter
|
@ -20,7 +20,7 @@ import { randB64Bytes } from "../../utils/rand";
|
|||
// Docker tag to use for synapse docker image.
|
||||
// We target a specific digest as every now and then a Synapse update will break our CI.
|
||||
// This digest is updated by the playwright-image-updates.yaml workflow periodically.
|
||||
const DOCKER_TAG = "develop@sha256:6c33604ee62f009f3b34454a3c3e85f7e3ff5de63e45011fcd79e0ddc54a4e51";
|
||||
const DOCKER_TAG = "develop@sha256:d1a89bd0fcdc2bf2900dac30696d53bb9e44da1231faacd5c2d3b9f539ce9586";
|
||||
|
||||
async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
|
||||
const templateDir = path.join(__dirname, "templates", opts.template);
|
||||
|
|
|
@ -102,3 +102,5 @@ experimental_features:
|
|||
# messages > non-joined historical messages.
|
||||
# Can be removed after Synapse enables it by default
|
||||
msc4115_membership_on_events: true
|
||||
|
||||
enable_authenticated_media: true
|
||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -125,7 +125,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
padding-left: 34px; /* 28px from above, but +6px to account for the wider icon */
|
||||
|
||||
&::before {
|
||||
mask-image: url("$(res)/img/element-icons/retry.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
height: 16px;
|
||||
width: 16px;
|
||||
left: 0;
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReport::before {
|
||||
mask-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconLink::before {
|
||||
|
@ -61,7 +61,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_MessageContextMenu_iconResend::before {
|
||||
mask-image: url("$(res)/img/element-icons/retry.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconSource::before {
|
||||
|
|
|
@ -125,7 +125,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-image: url("$(res)/img/element-icons/retry.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
left: 0;
|
||||
|
|
|
@ -21,7 +21,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
&.mx_AccessSecretStorageDialog_resetBadge::before {
|
||||
/* The image isn't capable of masking, so we use a background instead. */
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
background-size: 24px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
width: 16px;
|
||||
left: 0;
|
||||
top: 2px; /* alignment */
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,5 +29,5 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_InfoTooltip_icon_warning::before {
|
||||
mask-image: url("$(res)/img/element-icons/warning.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
}
|
||||
|
|
|
@ -108,6 +108,10 @@ Please see LICENSE files in the repository root for full details.
|
|||
color: var(--cpd-color-icon-primary);
|
||||
}
|
||||
|
||||
&.mx_MessageActionBar_retryButton {
|
||||
--MessageActionBar-icon-size: 16px;
|
||||
}
|
||||
|
||||
&.mx_MessageActionBar_downloadButton {
|
||||
--MessageActionBar-icon-size: 14px;
|
||||
|
||||
|
|
|
@ -31,8 +31,9 @@ Please see LICENSE files in the repository root for full details.
|
|||
position: absolute;
|
||||
top: calc(50% - 8px); /* center */
|
||||
right: -8px;
|
||||
mask: url("$(res)/img/member_chevron.png");
|
||||
mask: url("@vector-im/compound-design-tokens/icons/chevron-right.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: $header-panel-text-primary-color;
|
||||
|
|
|
@ -53,11 +53,11 @@ Please see LICENSE files in the repository root for full details.
|
|||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: $spacing-12;
|
||||
right: var(--cpd-space-1x);
|
||||
transform: translateY(-50%);
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
mask-image: url("$(res)/img/compound/chevron-right-12px.svg");
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-right.svg");
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1692_80)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.96967 10.7197C3.67678 10.4268 3.67601 9.95114 3.96795 9.6573L7.66823 5.933L3.95592 2.22069C3.66303 1.92779 3.66226 1.45215 3.9542 1.15831C4.24615 0.864473 4.72025 0.863706 5.01315 1.1566L9.25579 5.39924C9.54868 5.69213 9.54945 6.16777 9.2575 6.46161L5.02861 10.718C4.73667 11.0118 4.26256 11.0126 3.96967 10.7197Z" fill="#737D8C"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1692_80">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 629 B |
|
@ -1,3 +0,0 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.02266 2.96455C5.11589 2.10004 6.49866 1.5835 8 1.5835C11.3187 1.5835 14.049 4.10294 14.3825 7.3335H15.6723C15.9336 7.3335 16.0894 7.62498 15.9445 7.8426L13.9388 10.8543C13.8094 11.0488 13.524 11.0488 13.3945 10.8543L11.3888 7.8426C11.2439 7.62498 11.3997 7.3335 11.661 7.3335H12.8719C12.5465 4.93343 10.4893 3.0835 8 3.0835C6.84828 3.0835 5.79092 3.47857 4.95308 4.14112C4.8969 4.18555 4.84851 4.22129 4.81295 4.24673C4.7951 4.2595 4.78032 4.26979 4.7692 4.27743L4.75529 4.28689L4.75051 4.2901L4.74868 4.29132L4.74791 4.29183L4.74756 4.29206L4.74739 4.29217L4.74731 4.29223L4.33341 3.66694L4.74723 4.29228C4.40181 4.52087 3.93648 4.42616 3.70788 4.08073C3.47976 3.736 3.57362 3.27185 3.91734 3.04277L3.92021 3.04081L3.94013 3.02682C3.95912 3.01323 3.988 2.99197 4.02266 2.96455ZM3.12815 8.66683H4.33901C4.60027 8.66683 4.7561 8.37534 4.61118 8.15772L2.60551 5.14598C2.47603 4.95156 2.19064 4.95156 2.06116 5.14598L0.0554881 8.15772C-0.0894338 8.37534 0.0663988 8.66683 0.327661 8.66683H1.61755C1.95103 11.8974 4.68129 14.4168 8 14.4168C9.56831 14.4168 11.0069 13.8532 12.1215 12.9184C12.4388 12.6522 12.4803 12.1791 12.2141 11.8617C11.9479 11.5444 11.4749 11.5029 11.1575 11.7691C10.303 12.4859 9.20281 12.9168 8 12.9168C5.51071 12.9168 3.4535 11.0669 3.12815 8.66683Z" fill="currentColor"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.4 KiB |
|
@ -1,7 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none">
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
d="M4.523 2.964a6.418 6.418 0 0 1 10.36 4.369h1.29c.26 0 .416.292.272.51l-2.006 3.011a.327.327 0 0 1-.544 0l-2.006-3.012a.327.327 0 0 1 .272-.509h1.21a4.918 4.918 0 0 0-7.918-3.192 3.684 3.684 0 0 1-.184.136l-.014.01-.004.003-.002.001h-.001v.001l-.415-.625.414.625a.75.75 0 0 1-.83-1.25l.003-.001.02-.014c.02-.014.048-.035.083-.063Zm-.895 5.703H4.84a.327.327 0 0 0 .272-.51L3.106 5.146a.327.327 0 0 0-.545 0L.555 8.157c-.144.218.011.51.273.51h1.29a6.418 6.418 0 0 0 10.503 4.251.75.75 0 0 0-.963-1.15 4.918 4.918 0 0 1-8.03-3.102Z"
|
||||
clip-rule="evenodd"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 703 B |
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
height="24"
|
||||
width="24">
|
||||
<metadata
|
||||
id="metadata14">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs12" />
|
||||
<path
|
||||
id="path2"
|
||||
d="M 12 2 C 6.47715 2 2 6.47715 2 12 C 2 17.5228 6.47715 22 12 22 C 17.5228 22 22 17.5228 22 12 C 22 6.47715 17.5228 2 12 2 z M 11.880859 5.5039062 C 12.720859 5.4439063 13.470547 6.0746875 13.560547 6.9296875 L 13.560547 7.1699219 L 13.080078 13.169922 C 13.035078 13.724922 12.570625 14.144531 12.015625 14.144531 L 11.925781 14.144531 C 11.400781 14.099531 10.996172 13.694922 10.951172 13.169922 L 10.470703 7.1699219 C 10.395703 6.3149219 11.025859 5.5639064 11.880859 5.5039062 z M 12 15.763672 C 12.729 15.763672 13.320312 16.354884 13.320312 17.083984 C 13.320313 17.812984 12.729 18.404297 12 18.404297 C 11.271 18.404297 10.679688 17.812984 10.679688 17.083984 C 10.679688 16.354884 11.271 15.763672 12 15.763672 z "
|
||||
style="fill:#ff5b55;fill-opacity:1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1,3 +0,0 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM6.9806 4.5101C6.9306 3.9401 7.3506 3.4401 7.9206 3.4001C8.4806 3.3601 8.9806 3.7801 9.0406 4.3501V4.5101L8.7206 8.5101C8.6906 8.8801 8.3806 9.1601 8.0106 9.1601H7.9506C7.6006 9.1301 7.3306 8.8601 7.3006 8.5101L6.9806 4.5101ZM8.88012 11.1202C8.88012 11.6062 8.48613 12.0002 8.00012 12.0002C7.51411 12.0002 7.12012 11.6062 7.12012 11.1202C7.12012 10.6342 7.51411 10.2402 8.00012 10.2402C8.48613 10.2402 8.88012 10.6342 8.88012 11.1202Z" fill="#8D99A5"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 713 B |
Before Width: | Height: | Size: 271 B |
|
@ -8,10 +8,10 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
import React, { ReactNode } from "react";
|
||||
import { Tooltip } from "@vector-im/compound-web";
|
||||
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import AccessibleButton from "../../../views/elements/AccessibleButton";
|
||||
import { Icon as EMailPromptIcon } from "../../../../../res/img/element-icons/email-prompt.svg";
|
||||
import { Icon as RetryIcon } from "../../../../../res/img/compound/retry-16px.svg";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { useTimeoutToggle } from "../../../../hooks/useTimeoutToggle";
|
||||
import { ErrorMessage } from "../../ErrorMessage";
|
||||
|
@ -60,7 +60,7 @@ export const CheckEmail: React.FC<CheckEmailProps> = ({
|
|||
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
|
||||
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
|
||||
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
|
||||
<RetryIcon className="mx_Icon mx_Icon_16" />
|
||||
<RestartIcon className="mx_Icon mx_Icon_16" />
|
||||
{_t("action|resend")}
|
||||
</AccessibleButton>
|
||||
</Tooltip>
|
||||
|
|
|
@ -8,10 +8,10 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
import React, { ReactNode } from "react";
|
||||
import { Tooltip } from "@vector-im/compound-web";
|
||||
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import AccessibleButton from "../../../views/elements/AccessibleButton";
|
||||
import { Icon as RetryIcon } from "../../../../../res/img/compound/retry-16px.svg";
|
||||
import { Icon as EmailPromptIcon } from "../../../../../res/img/element-icons/email-prompt.svg";
|
||||
import { useTimeoutToggle } from "../../../../hooks/useTimeoutToggle";
|
||||
import { ErrorMessage } from "../../ErrorMessage";
|
||||
|
@ -59,7 +59,7 @@ export const VerifyEmailModal: React.FC<Props> = ({
|
|||
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
|
||||
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
|
||||
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
|
||||
<RetryIcon className="mx_Icon mx_Icon_16" />
|
||||
<RestartIcon className="mx_Icon mx_Icon_16" />
|
||||
{_t("action|resend")}
|
||||
</AccessibleButton>
|
||||
</Tooltip>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { Room, EventType } from "matrix-js-sdk/src/matrix";
|
|||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
|
@ -34,7 +35,6 @@ import LazyRenderList from "../elements/LazyRenderList";
|
|||
import { useSettingValue } from "../../../hooks/useSettings";
|
||||
import { filterBoolean } from "../../../utils/arrays";
|
||||
import { NonEmptyArray } from "../../../@types/common";
|
||||
import WarningBadgeSvg from "../../../../res/img/element-icons/warning-badge.svg";
|
||||
|
||||
// These values match CSS
|
||||
const ROW_HEIGHT = 32 + 12;
|
||||
|
@ -229,7 +229,7 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
|
|||
if (error) {
|
||||
footer = (
|
||||
<>
|
||||
<img src={WarningBadgeSvg} height="24" width="24" alt="" />
|
||||
<ErrorIcon height="24px" width="24px" />
|
||||
|
||||
<span className="mx_AddExistingToSpaceDialog_error">
|
||||
<div className="mx_AddExistingToSpaceDialog_errorHeading">
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
WidgetApiFromWidgetAction,
|
||||
WidgetKind,
|
||||
} from "matrix-widget-api";
|
||||
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import { _t, getUserLanguage } from "../../../languageHandler";
|
||||
|
@ -33,7 +34,6 @@ import { arrayFastClone } from "../../../utils/arrays";
|
|||
import { ElementWidget } from "../../../stores/widgets/StopGapWidget";
|
||||
import { ELEMENT_CLIENT_ID } from "../../../identifiers";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import WarningBadgeSvg from "../../../../res/img/element-icons/warning-badge.svg";
|
||||
|
||||
interface IProps {
|
||||
widgetDefinition: IModalWidgetOpenRequestData;
|
||||
|
@ -186,7 +186,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
onFinished={this.props.onFinished}
|
||||
>
|
||||
<div className="mx_ModalWidgetDialog_warning">
|
||||
<img src={WarningBadgeSvg} height="16" width="16" alt="" />
|
||||
<ErrorIcon width="16px" height="16px" />
|
||||
{_t("widget|modal_data_warning", {
|
||||
widgetDomain: parsed.hostname,
|
||||
})}
|
||||
|
|
|
@ -8,9 +8,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
|||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { createRef, CSSProperties } from "react";
|
||||
import React, { createRef, CSSProperties, useRef, useState } from "react";
|
||||
import FocusLock from "react-focus-lock";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixEvent, parseErrorResponse } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import MemberAvatar from "../avatars/MemberAvatar";
|
||||
|
@ -30,6 +30,9 @@ import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
|||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||
import { presentableTextForFile } from "../../../utils/FileUtils";
|
||||
import AccessibleButton from "./AccessibleButton";
|
||||
import Modal from "../../../Modal";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import { FileDownloader } from "../../../utils/FileDownloader";
|
||||
|
||||
// Max scale to keep gaps around the image
|
||||
const MAX_SCALE = 0.95;
|
||||
|
@ -309,15 +312,6 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
this.setZoomAndRotation(cur + 90);
|
||||
};
|
||||
|
||||
private onDownloadClick = (): void => {
|
||||
const a = document.createElement("a");
|
||||
a.href = this.props.src;
|
||||
if (this.props.name) a.download = this.props.name;
|
||||
a.target = "_blank";
|
||||
a.rel = "noreferrer noopener";
|
||||
a.click();
|
||||
};
|
||||
|
||||
private onOpenContextMenu = (): void => {
|
||||
this.setState({
|
||||
contextMenuDisplayed: true,
|
||||
|
@ -555,11 +549,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
title={_t("lightbox|rotate_right")}
|
||||
onClick={this.onRotateClockwiseClick}
|
||||
/>
|
||||
<AccessibleButton
|
||||
className="mx_ImageView_button mx_ImageView_button_download"
|
||||
title={_t("action|download")}
|
||||
onClick={this.onDownloadClick}
|
||||
/>
|
||||
<DownloadButton url={this.props.src} fileName={this.props.name} />
|
||||
{contextMenuButton}
|
||||
<AccessibleButton
|
||||
className="mx_ImageView_button mx_ImageView_button_close"
|
||||
|
@ -591,3 +581,61 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
function DownloadButton({ url, fileName }: { url: string; fileName?: string }): JSX.Element {
|
||||
const downloader = useRef(new FileDownloader()).current;
|
||||
const [loading, setLoading] = useState(false);
|
||||
const blobRef = useRef<Blob>();
|
||||
|
||||
function showError(e: unknown): void {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("timeline|download_failed"),
|
||||
description: (
|
||||
<>
|
||||
<div>{_t("timeline|download_failed_description")}</div>
|
||||
<div>{e instanceof Error ? e.toString() : ""}</div>
|
||||
</>
|
||||
),
|
||||
});
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const onDownloadClick = async (): Promise<void> => {
|
||||
try {
|
||||
if (loading) return;
|
||||
setLoading(true);
|
||||
|
||||
if (blobRef.current) {
|
||||
// Cheat and trigger a download, again.
|
||||
return downloadBlob(blobRef.current);
|
||||
}
|
||||
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
throw parseErrorResponse(res, await res.text());
|
||||
}
|
||||
const blob = await res.blob();
|
||||
blobRef.current = blob;
|
||||
await downloadBlob(blob);
|
||||
} catch (e) {
|
||||
showError(e);
|
||||
}
|
||||
};
|
||||
|
||||
async function downloadBlob(blob: Blob): Promise<void> {
|
||||
await downloader.download({
|
||||
blob,
|
||||
name: fileName ?? _t("common|image"),
|
||||
});
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<AccessibleButton
|
||||
className="mx_ImageView_button mx_ImageView_button_download"
|
||||
title={loading ? _t("timeline|download_action_downloading") : _t("action|download")}
|
||||
onClick={onDownloadClick}
|
||||
disabled={loading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { Icon as WarningBadge } from "../../../../res/img/element-icons/warning-badge.svg";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { getLocationShareErrorMessage, LocationShareError } from "../../../utils/location";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
|
@ -29,7 +29,7 @@ export const MapError: React.FC<MapErrorProps> = ({ error, isMinimised, classNam
|
|||
className={classNames("mx_MapError", className, { mx_MapError_isMinimised: isMinimised })}
|
||||
onClick={onClick}
|
||||
>
|
||||
<WarningBadge className="mx_MapError_icon" />
|
||||
<ErrorIcon className="mx_MapError_icon" />
|
||||
<Heading className="mx_MapError_heading" size="3">
|
||||
{_t("location_sharing|failed_load_map")}
|
||||
</Heading>
|
||||
|
|
|
@ -27,11 +27,11 @@ import {
|
|||
OverflowHorizontalIcon,
|
||||
ReplyIcon,
|
||||
DeleteIcon,
|
||||
RestartIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { Icon as EditIcon } from "../../../../res/img/element-icons/room/message-bar/edit.svg";
|
||||
import { Icon as EmojiIcon } from "../../../../res/img/element-icons/room/message-bar/emoji.svg";
|
||||
import { Icon as ResendIcon } from "../../../../res/img/element-icons/retry.svg";
|
||||
import { Icon as ThreadIcon } from "../../../../res/img/element-icons/message/thread.svg";
|
||||
import { Icon as ExpandMessageIcon } from "../../../../res/img/element-icons/expand-message.svg";
|
||||
import { Icon as CollapseMessageIcon } from "../../../../res/img/element-icons/collapse-message.svg";
|
||||
|
@ -475,14 +475,14 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
|||
0,
|
||||
0,
|
||||
<RovingAccessibleButton
|
||||
className="mx_MessageActionBar_iconButton"
|
||||
className="mx_MessageActionBar_iconButton mx_MessageActionBar_retryButton"
|
||||
title={_t("action|retry")}
|
||||
onClick={this.onResendClick}
|
||||
onContextMenu={this.onResendClick}
|
||||
key="resend"
|
||||
placement="left"
|
||||
>
|
||||
<ResendIcon />
|
||||
<RestartIcon />
|
||||
</RovingAccessibleButton>,
|
||||
);
|
||||
|
||||
|
|
|
@ -1624,7 +1624,7 @@
|
|||
"download_f_droid": "Récupérez-le sur F-Droid",
|
||||
"download_google_play": "Récupérez-le sur Google Play",
|
||||
"enable_notifications": "Activer les notifications",
|
||||
"enable_notifications_action": "Activer les notifications",
|
||||
"enable_notifications_action": "Ouvrir les paramètres",
|
||||
"enable_notifications_description": "Ne ratez pas une réponse ou un message important",
|
||||
"explore_rooms": "Explorez les salons publics",
|
||||
"find_community_members": "Trouvez et invitez les membres de votre communauté",
|
||||
|
@ -1803,7 +1803,7 @@
|
|||
"restore_failed_error": "Impossible de restaurer la sauvegarde"
|
||||
},
|
||||
"right_panel": {
|
||||
"add_integrations": "Ajouter des widgets, passerelles et robots",
|
||||
"add_integrations": "Ajouter des extensions",
|
||||
"add_topic": "Ajouter un sujet",
|
||||
"files_button": "Fichiers",
|
||||
"pinned_messages": {
|
||||
|
@ -1823,7 +1823,7 @@
|
|||
"button": "Désépingler tous les messages"
|
||||
}
|
||||
},
|
||||
"pinned_messages_button": "Épinglé",
|
||||
"pinned_messages_button": "Messages épinglés",
|
||||
"poll": {
|
||||
"active_heading": "Sondages en cours",
|
||||
"empty_active": "Il n’y a aucun sondage en cours dans ce salon",
|
||||
|
@ -1848,7 +1848,7 @@
|
|||
"view_in_timeline": "Consulter la chronologie des sondages",
|
||||
"view_poll": "Voir le sondage"
|
||||
},
|
||||
"polls_button": "Historique des sondages",
|
||||
"polls_button": "Sondages",
|
||||
"room_summary_card": {
|
||||
"title": "Information du salon"
|
||||
},
|
||||
|
@ -3252,7 +3252,7 @@
|
|||
},
|
||||
"m.file": {
|
||||
"error_decrypting": "Erreur lors du déchiffrement de la pièce jointe",
|
||||
"error_invalid": "Fichier %(extra)s non valide"
|
||||
"error_invalid": "Fichier invalide"
|
||||
},
|
||||
"m.image": {
|
||||
"error": "Impossible d’afficher l’image à cause d’une erreur",
|
||||
|
@ -3988,7 +3988,7 @@
|
|||
"title": "Autoriser ce widget à vérifier votre identité"
|
||||
},
|
||||
"popout": "Détacher le widget",
|
||||
"set_room_layout": "Définir ma disposition de salon pour tout le monde",
|
||||
"set_room_layout": "Définir la mise en page pour tout le monde",
|
||||
"shared_data_avatar": "Votre URL d’image de profil",
|
||||
"shared_data_device_id": "Votre ID d’appareil",
|
||||
"shared_data_lang": "Votre langue",
|
||||
|
|
|
@ -127,12 +127,6 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
|||
this.allowedCapabilities.add(MatrixCapabilities.MSC4157SendDelayedEvent);
|
||||
this.allowedCapabilities.add(MatrixCapabilities.MSC4157UpdateDelayedEvent);
|
||||
|
||||
this.allowedCapabilities.add(
|
||||
WidgetEventCapability.forRoomEvent(EventDirection.Send, "org.matrix.rageshake_request").raw,
|
||||
);
|
||||
this.allowedCapabilities.add(
|
||||
WidgetEventCapability.forRoomEvent(EventDirection.Receive, "org.matrix.rageshake_request").raw,
|
||||
);
|
||||
this.allowedCapabilities.add(
|
||||
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomMember).raw,
|
||||
);
|
||||
|
@ -175,7 +169,13 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
|||
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomCreate).raw,
|
||||
);
|
||||
|
||||
const sendRecvRoomEvents = ["io.element.call.encryption_keys", EventType.Reaction, EventType.RoomRedaction];
|
||||
const sendRecvRoomEvents = [
|
||||
"io.element.call.encryption_keys",
|
||||
"org.matrix.rageshake_request",
|
||||
EventType.Reaction,
|
||||
EventType.RoomRedaction,
|
||||
"io.element.call.reaction",
|
||||
];
|
||||
for (const eventType of sendRecvRoomEvents) {
|
||||
this.allowedCapabilities.add(WidgetEventCapability.forRoomEvent(EventDirection.Send, eventType).raw);
|
||||
this.allowedCapabilities.add(WidgetEventCapability.forRoomEvent(EventDirection.Receive, eventType).raw);
|
||||
|
|
|
@ -7,13 +7,57 @@
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render } from "jest-matrix-react";
|
||||
import { mocked } from "jest-mock";
|
||||
import { render, fireEvent, waitFor } from "jest-matrix-react";
|
||||
import fetchMock from "fetch-mock-jest";
|
||||
|
||||
import ImageView from "../../../../../src/components/views/elements/ImageView";
|
||||
import { FileDownloader } from "../../../../../src/utils/FileDownloader";
|
||||
import Modal from "../../../../../src/Modal";
|
||||
import ErrorDialog from "../../../../../src/components/views/dialogs/ErrorDialog";
|
||||
|
||||
jest.mock("../../../../../src/utils/FileDownloader");
|
||||
|
||||
describe("<ImageView />", () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
it("renders correctly", () => {
|
||||
const { container } = render(<ImageView src="https://example.com/image.png" onFinished={jest.fn()} />);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should download on click", async () => {
|
||||
fetchMock.get("https://example.com/image.png", "TESTFILE");
|
||||
const { getByRole } = render(
|
||||
<ImageView src="https://example.com/image.png" name="filename.png" onFinished={jest.fn()} />,
|
||||
);
|
||||
fireEvent.click(getByRole("button", { name: "Download" }));
|
||||
await waitFor(() =>
|
||||
expect(mocked(FileDownloader).mock.instances[0].download).toHaveBeenCalledWith({
|
||||
blob: expect.anything(),
|
||||
name: "filename.png",
|
||||
}),
|
||||
);
|
||||
expect(fetchMock).toHaveFetched("https://example.com/image.png");
|
||||
});
|
||||
|
||||
it("should handle download errors", async () => {
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog");
|
||||
fetchMock.get("https://example.com/image.png", { status: 500 });
|
||||
const { getByRole } = render(
|
||||
<ImageView src="https://example.com/image.png" name="filename.png" onFinished={jest.fn()} />,
|
||||
);
|
||||
fireEvent.click(getByRole("button", { name: "Download" }));
|
||||
await waitFor(() =>
|
||||
expect(modalSpy).toHaveBeenCalledWith(
|
||||
ErrorDialog,
|
||||
expect.objectContaining({
|
||||
title: "Download failed",
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,9 +6,18 @@ exports[`<MapError /> applies class when isMinimised is truthy 1`] = `
|
|||
class="mx_MapError test mx_MapError_isMinimised"
|
||||
data-testid="map-rendering-error"
|
||||
>
|
||||
<div
|
||||
<svg
|
||||
class="mx_MapError_icon"
|
||||
/>
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 17a.97.97 0 0 0 .713-.288A.968.968 0 0 0 13 16a.968.968 0 0 0-.287-.713A.968.968 0 0 0 12 15a.968.968 0 0 0-.713.287A.968.968 0 0 0 11 16c0 .283.096.52.287.712.192.192.43.288.713.288Zm0-4c.283 0 .52-.096.713-.287A.968.968 0 0 0 13 12V8a.967.967 0 0 0-.287-.713A.968.968 0 0 0 12 7a.968.968 0 0 0-.713.287A.967.967 0 0 0 11 8v4c0 .283.096.52.287.713.192.191.43.287.713.287Zm0 9a9.738 9.738 0 0 1-3.9-.788 10.099 10.099 0 0 1-3.175-2.137c-.9-.9-1.612-1.958-2.137-3.175A9.738 9.738 0 0 1 2 12a9.74 9.74 0 0 1 .788-3.9 10.099 10.099 0 0 1 2.137-3.175c.9-.9 1.958-1.612 3.175-2.137A9.738 9.738 0 0 1 12 2a9.74 9.74 0 0 1 3.9.788 10.098 10.098 0 0 1 3.175 2.137c.9.9 1.613 1.958 2.137 3.175A9.738 9.738 0 0 1 22 12a9.738 9.738 0 0 1-.788 3.9 10.098 10.098 0 0 1-2.137 3.175c-.9.9-1.958 1.613-3.175 2.137A9.738 9.738 0 0 1 12 22Z"
|
||||
/>
|
||||
</svg>
|
||||
<h3
|
||||
class="mx_Heading_h3 mx_MapError_heading"
|
||||
>
|
||||
|
@ -36,9 +45,18 @@ exports[`<MapError /> renders correctly for MapStyleUrlNotConfigured 1`] = `
|
|||
class="mx_MapError test"
|
||||
data-testid="map-rendering-error"
|
||||
>
|
||||
<div
|
||||
<svg
|
||||
class="mx_MapError_icon"
|
||||
/>
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 17a.97.97 0 0 0 .713-.288A.968.968 0 0 0 13 16a.968.968 0 0 0-.287-.713A.968.968 0 0 0 12 15a.968.968 0 0 0-.713.287A.968.968 0 0 0 11 16c0 .283.096.52.287.712.192.192.43.288.713.288Zm0-4c.283 0 .52-.096.713-.287A.968.968 0 0 0 13 12V8a.967.967 0 0 0-.287-.713A.968.968 0 0 0 12 7a.968.968 0 0 0-.713.287A.967.967 0 0 0 11 8v4c0 .283.096.52.287.713.192.191.43.287.713.287Zm0 9a9.738 9.738 0 0 1-3.9-.788 10.099 10.099 0 0 1-3.175-2.137c-.9-.9-1.612-1.958-2.137-3.175A9.738 9.738 0 0 1 2 12a9.74 9.74 0 0 1 .788-3.9 10.099 10.099 0 0 1 2.137-3.175c.9-.9 1.958-1.612 3.175-2.137A9.738 9.738 0 0 1 12 2a9.74 9.74 0 0 1 3.9.788 10.098 10.098 0 0 1 3.175 2.137c.9.9 1.613 1.958 2.137 3.175A9.738 9.738 0 0 1 22 12a9.738 9.738 0 0 1-.788 3.9 10.098 10.098 0 0 1-2.137 3.175c-.9.9-1.958 1.613-3.175 2.137A9.738 9.738 0 0 1 12 22Z"
|
||||
/>
|
||||
</svg>
|
||||
<h3
|
||||
class="mx_Heading_h3 mx_MapError_heading"
|
||||
>
|
||||
|
@ -66,9 +84,18 @@ exports[`<MapError /> renders correctly for MapStyleUrlNotReachable 1`] = `
|
|||
class="mx_MapError test"
|
||||
data-testid="map-rendering-error"
|
||||
>
|
||||
<div
|
||||
<svg
|
||||
class="mx_MapError_icon"
|
||||
/>
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 17a.97.97 0 0 0 .713-.288A.968.968 0 0 0 13 16a.968.968 0 0 0-.287-.713A.968.968 0 0 0 12 15a.968.968 0 0 0-.713.287A.968.968 0 0 0 11 16c0 .283.096.52.287.712.192.192.43.288.713.288Zm0-4c.283 0 .52-.096.713-.287A.968.968 0 0 0 13 12V8a.967.967 0 0 0-.287-.713A.968.968 0 0 0 12 7a.968.968 0 0 0-.713.287A.967.967 0 0 0 11 8v4c0 .283.096.52.287.713.192.191.43.287.713.287Zm0 9a9.738 9.738 0 0 1-3.9-.788 10.099 10.099 0 0 1-3.175-2.137c-.9-.9-1.612-1.958-2.137-3.175A9.738 9.738 0 0 1 2 12a9.74 9.74 0 0 1 .788-3.9 10.099 10.099 0 0 1 2.137-3.175c.9-.9 1.958-1.612 3.175-2.137A9.738 9.738 0 0 1 12 2a9.74 9.74 0 0 1 3.9.788 10.098 10.098 0 0 1 3.175 2.137c.9.9 1.613 1.958 2.137 3.175A9.738 9.738 0 0 1 22 12a9.738 9.738 0 0 1-.788 3.9 10.098 10.098 0 0 1-2.137 3.175c-.9.9-1.958 1.613-3.175 2.137A9.738 9.738 0 0 1 12 22Z"
|
||||
/>
|
||||
</svg>
|
||||
<h3
|
||||
class="mx_Heading_h3 mx_MapError_heading"
|
||||
>
|
||||
|
|
|
@ -5,9 +5,18 @@ exports[`<MBeaconBody /> when map display is not configured renders maps unavail
|
|||
class="mx_MapError mx_MBeaconBody_mapError mx_MBeaconBody_mapErrorInteractive mx_MapError_isMinimised"
|
||||
data-testid="map-rendering-error"
|
||||
>
|
||||
<div
|
||||
<svg
|
||||
class="mx_MapError_icon"
|
||||
/>
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 17a.97.97 0 0 0 .713-.288A.968.968 0 0 0 13 16a.968.968 0 0 0-.287-.713A.968.968 0 0 0 12 15a.968.968 0 0 0-.713.287A.968.968 0 0 0 11 16c0 .283.096.52.287.712.192.192.43.288.713.288Zm0-4c.283 0 .52-.096.713-.287A.968.968 0 0 0 13 12V8a.967.967 0 0 0-.287-.713A.968.968 0 0 0 12 7a.968.968 0 0 0-.713.287A.967.967 0 0 0 11 8v4c0 .283.096.52.287.713.192.191.43.287.713.287Zm0 9a9.738 9.738 0 0 1-3.9-.788 10.099 10.099 0 0 1-3.175-2.137c-.9-.9-1.612-1.958-2.137-3.175A9.738 9.738 0 0 1 2 12a9.74 9.74 0 0 1 .788-3.9 10.099 10.099 0 0 1 2.137-3.175c.9-.9 1.958-1.612 3.175-2.137A9.738 9.738 0 0 1 12 2a9.74 9.74 0 0 1 3.9.788 10.098 10.098 0 0 1 3.175 2.137c.9.9 1.613 1.958 2.137 3.175A9.738 9.738 0 0 1 22 12a9.738 9.738 0 0 1-.788 3.9 10.098 10.098 0 0 1-2.137 3.175c-.9.9-1.958 1.613-3.175 2.137A9.738 9.738 0 0 1 12 22Z"
|
||||
/>
|
||||
</svg>
|
||||
<h3
|
||||
class="mx_Heading_h3 mx_MapError_heading"
|
||||
>
|
||||
|
|
Before Width: | Height: | Size: 460 B |
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="19px" height="19px" viewBox="0 0 19 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>ED5D3E59-2561-4AC1-9B43-82FBC51767FC</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="icon_context">
|
||||
<g>
|
||||
<path d="M9.5,19 C14.7467051,19 19,14.7467051 19,9.5 C19,4.25329488 14.7467051,0 9.5,0 C4.25329488,0 0,4.25329488 0,9.5 C0,14.7467051 4.25329488,19 9.5,19 Z" id="Oval-69" fill="#ECECEC"></path>
|
||||
<path d="M4.5,9.50063771 C4.5,9.13148623 4.59887838,8.85242947 4.7966381,8.66345907 C4.99439782,8.47448867 5.28224377,8.38000488 5.66018457,8.38000488 C6.0249414,8.38000488 6.3072941,8.47668596 6.50725115,8.67005103 C6.70720821,8.86341609 6.80718523,9.14027555 6.80718523,9.50063771 C6.80718523,9.84781589 6.70610956,10.1213794 6.50395517,10.3213365 C6.30180079,10.5212935 6.02054674,10.6212705 5.66018457,10.6212705 C5.29103309,10.6212705 5.00538444,10.5234908 4.80323006,10.3279284 C4.60107568,10.132366 4.5,9.85660521 4.5,9.50063771 L4.5,9.50063771 Z M8.3431114,9.50063771 C8.3431114,9.13148623 8.44198978,8.85242947 8.63974951,8.66345907 C8.83750923,8.47448867 9.12755247,8.38000488 9.50988794,8.38000488 C9.87464476,8.38000488 10.1569975,8.47668596 10.3569545,8.67005103 C10.5569116,8.86341609 10.6568886,9.14027555 10.6568886,9.50063771 C10.6568886,9.84781589 10.5558129,10.1213794 10.3536585,10.3213365 C10.1515042,10.5212935 9.8702501,10.6212705 9.50988794,10.6212705 C9.13634179,10.6212705 8.84849585,10.5234908 8.64634146,10.3279284 C8.44418708,10.132366 8.3431114,9.85660521 8.3431114,9.50063771 L8.3431114,9.50063771 Z M12.1928148,9.50063771 C12.1928148,9.13148623 12.2916931,8.85242947 12.4894529,8.66345907 C12.6872126,8.47448867 12.9750585,8.38000488 13.3529993,8.38000488 C13.7177562,8.38000488 14.0001089,8.47668596 14.2000659,8.67005103 C14.400023,8.86341609 14.5,9.14027555 14.5,9.50063771 C14.5,9.84781589 14.3989243,10.1213794 14.1967699,10.3213365 C13.9946156,10.5212935 13.7133615,10.6212705 13.3529993,10.6212705 C12.9838479,10.6212705 12.6981992,10.5234908 12.4960448,10.3279284 C12.2938904,10.132366 12.1928148,9.85660521 12.1928148,9.50063771 L12.1928148,9.50063771 Z" id="…" fill="#9B9B9B"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.5 KiB |