Skip to content

Commit cb0d72f

Browse files
authored
Merge branch 'develop' into dbkr/stateafter
2 parents 931edd7 + 9a6be72 commit cb0d72f

File tree

32 files changed

+200
-135
lines changed

32 files changed

+200
-135
lines changed

playwright/plugins/homeserver/synapse/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { randB64Bytes } from "../../utils/rand";
2020
// Docker tag to use for synapse docker image.
2121
// We target a specific digest as every now and then a Synapse update will break our CI.
2222
// This digest is updated by the playwright-image-updates.yaml workflow periodically.
23-
const DOCKER_TAG = "develop@sha256:6c33604ee62f009f3b34454a3c3e85f7e3ff5de63e45011fcd79e0ddc54a4e51";
23+
const DOCKER_TAG = "develop@sha256:d1a89bd0fcdc2bf2900dac30696d53bb9e44da1231faacd5c2d3b9f539ce9586";
2424

2525
async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
2626
const templateDir = path.join(__dirname, "templates", opts.template);

playwright/plugins/homeserver/synapse/templates/default/homeserver.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ experimental_features:
102102
# messages > non-joined historical messages.
103103
# Can be removed after Synapse enables it by default
104104
msc4115_membership_on_events: true
105+
106+
enable_authenticated_media: true

res/css/structures/_RoomStatusBar.pcss

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Please see LICENSE files in the repository root for full details.
125125
padding-left: 34px; /* 28px from above, but +6px to account for the wider icon */
126126

127127
&::before {
128-
mask-image: url("$(res)/img/element-icons/retry.svg");
128+
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
129129
}
130130
}
131131
}

res/css/structures/_SpaceHierarchy.pcss

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Please see LICENSE files in the repository root for full details.
7777
height: 16px;
7878
width: 16px;
7979
left: 0;
80-
background-image: url("$(res)/img/element-icons/warning-badge.svg");
80+
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
8181
background-size: cover;
8282
background-repeat: no-repeat;
8383
}

res/css/views/context_menus/_MessageContextMenu.pcss

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Please see LICENSE files in the repository root for full details.
2929
}
3030

3131
.mx_MessageContextMenu_iconReport::before {
32-
mask-image: url("$(res)/img/element-icons/warning-badge.svg");
32+
mask-image: url("@vector-im/compound-design-tokens/icons/error.svg");
3333
}
3434

3535
.mx_MessageContextMenu_iconLink::before {
@@ -61,7 +61,7 @@ Please see LICENSE files in the repository root for full details.
6161
}
6262

6363
.mx_MessageContextMenu_iconResend::before {
64-
mask-image: url("$(res)/img/element-icons/retry.svg");
64+
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
6565
}
6666

6767
.mx_MessageContextMenu_iconSource::before {

res/css/views/dialogs/_AddExistingToSpaceDialog.pcss

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Please see LICENSE files in the repository root for full details.
125125
mask-repeat: no-repeat;
126126
mask-position: center;
127127
mask-size: contain;
128-
mask-image: url("$(res)/img/element-icons/retry.svg");
128+
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
129129
width: 18px;
130130
height: 18px;
131131
left: 0;

res/css/views/dialogs/security/_AccessSecretStorageDialog.pcss

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Please see LICENSE files in the repository root for full details.
2121

2222
&.mx_AccessSecretStorageDialog_resetBadge::before {
2323
/* The image isn't capable of masking, so we use a background instead. */
24-
background-image: url("$(res)/img/element-icons/warning-badge.svg");
24+
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
2525
background-size: 24px;
2626
background-color: transparent;
2727
}
@@ -120,7 +120,7 @@ Please see LICENSE files in the repository root for full details.
120120
width: 16px;
121121
left: 0;
122122
top: 2px; /* alignment */
123-
background-image: url("$(res)/img/element-icons/warning-badge.svg");
123+
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
124124
background-size: contain;
125125
}
126126

res/css/views/elements/_InfoTooltip.pcss

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ Please see LICENSE files in the repository root for full details.
2929
}
3030

3131
.mx_InfoTooltip_icon_warning::before {
32-
mask-image: url("$(res)/img/element-icons/warning.svg");
32+
mask-image: url("@vector-im/compound-design-tokens/icons/error.svg");
3333
}

res/css/views/messages/_MessageActionBar.pcss

+4
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ Please see LICENSE files in the repository root for full details.
108108
color: var(--cpd-color-icon-primary);
109109
}
110110

111+
&.mx_MessageActionBar_retryButton {
112+
--MessageActionBar-icon-size: 16px;
113+
}
114+
111115
&.mx_MessageActionBar_downloadButton {
112116
--MessageActionBar-icon-size: 14px;
113117

res/css/views/rooms/_EntityTile.pcss

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ Please see LICENSE files in the repository root for full details.
3131
position: absolute;
3232
top: calc(50% - 8px); /* center */
3333
right: -8px;
34-
mask: url("$(res)/img/member_chevron.png");
34+
mask: url("@vector-im/compound-design-tokens/icons/chevron-right.svg");
3535
mask-repeat: no-repeat;
36+
mask-position: center;
3637
width: 16px;
3738
height: 16px;
3839
background-color: $header-panel-text-primary-color;

res/css/views/rooms/_ThreadSummary.pcss

+4-4
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ Please see LICENSE files in the repository root for full details.
5353
content: "";
5454
position: absolute;
5555
top: 50%;
56-
right: $spacing-12;
56+
right: var(--cpd-space-1x);
5757
transform: translateY(-50%);
58-
width: 12px;
59-
height: 12px;
60-
mask-image: url("$(res)/img/compound/chevron-right-12px.svg");
58+
width: 24px;
59+
height: 24px;
60+
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-right.svg");
6161
mask-position: center;
6262
mask-size: contain;
6363
mask-repeat: no-repeat;

res/img/compound/chevron-right-12px.svg

-10
This file was deleted.

res/img/compound/retry-16px.svg

-3
This file was deleted.

res/img/element-icons/retry.svg

-7
This file was deleted.

res/img/element-icons/warning-badge.svg

-32
This file was deleted.

res/img/element-icons/warning.svg

-3
This file was deleted.

res/img/member_chevron.png

-271 Bytes
Binary file not shown.

src/components/structures/auth/forgot-password/CheckEmail.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ Please see LICENSE files in the repository root for full details.
88

99
import React, { ReactNode } from "react";
1010
import { Tooltip } from "@vector-im/compound-web";
11+
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
1112

1213
import AccessibleButton from "../../../views/elements/AccessibleButton";
1314
import { Icon as EMailPromptIcon } from "../../../../../res/img/element-icons/email-prompt.svg";
14-
import { Icon as RetryIcon } from "../../../../../res/img/compound/retry-16px.svg";
1515
import { _t } from "../../../../languageHandler";
1616
import { useTimeoutToggle } from "../../../../hooks/useTimeoutToggle";
1717
import { ErrorMessage } from "../../ErrorMessage";
@@ -60,7 +60,7 @@ export const CheckEmail: React.FC<CheckEmailProps> = ({
6060
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
6161
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
6262
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
63-
<RetryIcon className="mx_Icon mx_Icon_16" />
63+
<RestartIcon className="mx_Icon mx_Icon_16" />
6464
{_t("action|resend")}
6565
</AccessibleButton>
6666
</Tooltip>

src/components/structures/auth/forgot-password/VerifyEmailModal.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ Please see LICENSE files in the repository root for full details.
88

99
import React, { ReactNode } from "react";
1010
import { Tooltip } from "@vector-im/compound-web";
11+
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
1112

1213
import { _t } from "../../../../languageHandler";
1314
import AccessibleButton from "../../../views/elements/AccessibleButton";
14-
import { Icon as RetryIcon } from "../../../../../res/img/compound/retry-16px.svg";
1515
import { Icon as EmailPromptIcon } from "../../../../../res/img/element-icons/email-prompt.svg";
1616
import { useTimeoutToggle } from "../../../../hooks/useTimeoutToggle";
1717
import { ErrorMessage } from "../../ErrorMessage";
@@ -59,7 +59,7 @@ export const VerifyEmailModal: React.FC<Props> = ({
5959
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
6060
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
6161
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
62-
<RetryIcon className="mx_Icon mx_Icon_16" />
62+
<RestartIcon className="mx_Icon mx_Icon_16" />
6363
{_t("action|resend")}
6464
</AccessibleButton>
6565
</Tooltip>

src/components/views/dialogs/AddExistingToSpaceDialog.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Room, EventType } from "matrix-js-sdk/src/matrix";
1212
import { KnownMembership } from "matrix-js-sdk/src/types";
1313
import { sleep } from "matrix-js-sdk/src/utils";
1414
import { logger } from "matrix-js-sdk/src/logger";
15+
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
1516

1617
import { _t, _td, TranslationKey } from "../../../languageHandler";
1718
import BaseDialog from "./BaseDialog";
@@ -34,7 +35,6 @@ import LazyRenderList from "../elements/LazyRenderList";
3435
import { useSettingValue } from "../../../hooks/useSettings";
3536
import { filterBoolean } from "../../../utils/arrays";
3637
import { NonEmptyArray } from "../../../@types/common";
37-
import WarningBadgeSvg from "../../../../res/img/element-icons/warning-badge.svg";
3838

3939
// These values match CSS
4040
const ROW_HEIGHT = 32 + 12;
@@ -229,7 +229,7 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
229229
if (error) {
230230
footer = (
231231
<>
232-
<img src={WarningBadgeSvg} height="24" width="24" alt="" />
232+
<ErrorIcon height="24px" width="24px" />
233233

234234
<span className="mx_AddExistingToSpaceDialog_error">
235235
<div className="mx_AddExistingToSpaceDialog_errorHeading">

src/components/views/dialogs/ModalWidgetDialog.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
WidgetApiFromWidgetAction,
2323
WidgetKind,
2424
} from "matrix-widget-api";
25+
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
2526

2627
import BaseDialog from "./BaseDialog";
2728
import { _t, getUserLanguage } from "../../../languageHandler";
@@ -33,7 +34,6 @@ import { arrayFastClone } from "../../../utils/arrays";
3334
import { ElementWidget } from "../../../stores/widgets/StopGapWidget";
3435
import { ELEMENT_CLIENT_ID } from "../../../identifiers";
3536
import SettingsStore from "../../../settings/SettingsStore";
36-
import WarningBadgeSvg from "../../../../res/img/element-icons/warning-badge.svg";
3737

3838
interface IProps {
3939
widgetDefinition: IModalWidgetOpenRequestData;
@@ -186,7 +186,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
186186
onFinished={this.props.onFinished}
187187
>
188188
<div className="mx_ModalWidgetDialog_warning">
189-
<img src={WarningBadgeSvg} height="16" width="16" alt="" />
189+
<ErrorIcon width="16px" height="16px" />
190190
{_t("widget|modal_data_warning", {
191191
widgetDomain: parsed.hostname,
192192
})}

src/components/views/elements/ImageView.tsx

+64-16
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
88
Please see LICENSE files in the repository root for full details.
99
*/
1010

11-
import React, { createRef, CSSProperties } from "react";
11+
import React, { createRef, CSSProperties, useRef, useState } from "react";
1212
import FocusLock from "react-focus-lock";
13-
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
13+
import { MatrixEvent, parseErrorResponse } from "matrix-js-sdk/src/matrix";
1414

1515
import { _t } from "../../../languageHandler";
1616
import MemberAvatar from "../avatars/MemberAvatar";
@@ -30,6 +30,9 @@ import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
3030
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
3131
import { presentableTextForFile } from "../../../utils/FileUtils";
3232
import AccessibleButton from "./AccessibleButton";
33+
import Modal from "../../../Modal";
34+
import ErrorDialog from "../dialogs/ErrorDialog";
35+
import { FileDownloader } from "../../../utils/FileDownloader";
3336

3437
// Max scale to keep gaps around the image
3538
const MAX_SCALE = 0.95;
@@ -309,15 +312,6 @@ export default class ImageView extends React.Component<IProps, IState> {
309312
this.setZoomAndRotation(cur + 90);
310313
};
311314

312-
private onDownloadClick = (): void => {
313-
const a = document.createElement("a");
314-
a.href = this.props.src;
315-
if (this.props.name) a.download = this.props.name;
316-
a.target = "_blank";
317-
a.rel = "noreferrer noopener";
318-
a.click();
319-
};
320-
321315
private onOpenContextMenu = (): void => {
322316
this.setState({
323317
contextMenuDisplayed: true,
@@ -555,11 +549,7 @@ export default class ImageView extends React.Component<IProps, IState> {
555549
title={_t("lightbox|rotate_right")}
556550
onClick={this.onRotateClockwiseClick}
557551
/>
558-
<AccessibleButton
559-
className="mx_ImageView_button mx_ImageView_button_download"
560-
title={_t("action|download")}
561-
onClick={this.onDownloadClick}
562-
/>
552+
<DownloadButton url={this.props.src} fileName={this.props.name} />
563553
{contextMenuButton}
564554
<AccessibleButton
565555
className="mx_ImageView_button mx_ImageView_button_close"
@@ -591,3 +581,61 @@ export default class ImageView extends React.Component<IProps, IState> {
591581
);
592582
}
593583
}
584+
585+
function DownloadButton({ url, fileName }: { url: string; fileName?: string }): JSX.Element {
586+
const downloader = useRef(new FileDownloader()).current;
587+
const [loading, setLoading] = useState(false);
588+
const blobRef = useRef<Blob>();
589+
590+
function showError(e: unknown): void {
591+
Modal.createDialog(ErrorDialog, {
592+
title: _t("timeline|download_failed"),
593+
description: (
594+
<>
595+
<div>{_t("timeline|download_failed_description")}</div>
596+
<div>{e instanceof Error ? e.toString() : ""}</div>
597+
</>
598+
),
599+
});
600+
setLoading(false);
601+
}
602+
603+
const onDownloadClick = async (): Promise<void> => {
604+
try {
605+
if (loading) return;
606+
setLoading(true);
607+
608+
if (blobRef.current) {
609+
// Cheat and trigger a download, again.
610+
return downloadBlob(blobRef.current);
611+
}
612+
613+
const res = await fetch(url);
614+
if (!res.ok) {
615+
throw parseErrorResponse(res, await res.text());
616+
}
617+
const blob = await res.blob();
618+
blobRef.current = blob;
619+
await downloadBlob(blob);
620+
} catch (e) {
621+
showError(e);
622+
}
623+
};
624+
625+
async function downloadBlob(blob: Blob): Promise<void> {
626+
await downloader.download({
627+
blob,
628+
name: fileName ?? _t("common|image"),
629+
});
630+
setLoading(false);
631+
}
632+
633+
return (
634+
<AccessibleButton
635+
className="mx_ImageView_button mx_ImageView_button_download"
636+
title={loading ? _t("timeline|download_action_downloading") : _t("action|download")}
637+
onClick={onDownloadClick}
638+
disabled={loading}
639+
/>
640+
);
641+
}

0 commit comments

Comments
 (0)