diff --git a/src/hooks/useDownloadMedia.ts b/src/hooks/useDownloadMedia.ts
index 74328ac7ca6..eb0af954e02 100644
--- a/src/hooks/useDownloadMedia.ts
+++ b/src/hooks/useDownloadMedia.ts
@@ -59,15 +59,19 @@ export function useDownloadMedia(url: string, fileName?: string, mxEvent?: Matri
return downloadBlob(blobRef.current);
}
- const res = await fetch(url);
- if (!res.ok) {
- throw parseErrorResponse(res, await res.text());
+ // We must download via the mediaEventHelper if given as the file may need decryption.
+ if (mediaEventHelper) {
+ blobRef.current = await mediaEventHelper.sourceBlob.value;
+ } else {
+ const res = await fetch(url);
+ if (!res.ok) {
+ throw parseErrorResponse(res, await res.text());
+ }
+
+ blobRef.current = await res.blob();
}
- const blob = await res.blob();
- blobRef.current = blob;
-
- await downloadBlob(blob);
+ await downloadBlob(blobRef.current);
} catch (e) {
showError(e);
}
diff --git a/test/unit-tests/components/views/elements/ImageView-test.tsx b/test/unit-tests/components/views/elements/ImageView-test.tsx
index b0e9338f69a..6537a3948a2 100644
--- a/test/unit-tests/components/views/elements/ImageView-test.tsx
+++ b/test/unit-tests/components/views/elements/ImageView-test.tsx
@@ -10,11 +10,13 @@ import React from "react";
import { mocked } from "jest-mock";
import { render, fireEvent, waitFor } from "jest-matrix-react";
import fetchMock from "fetch-mock-jest";
+import { MatrixEvent } from "matrix-js-sdk/src/matrix";
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";
+import { stubClient } from "../../../../test-utils";
jest.mock("../../../../../src/utils/FileDownloader");
@@ -44,6 +46,39 @@ describe("", () => {
expect(fetchMock).toHaveFetched("https://example.com/image.png");
});
+ it("should use event as download source if given", async () => {
+ stubClient();
+
+ const event = new MatrixEvent({
+ event_id: "$eventId",
+ type: "m.image",
+ content: {
+ body: "fromEvent.png",
+ url: "mxc://test.dummy/fromEvent.png",
+ file_name: "filename.png",
+ },
+ origin_server_ts: new Date(2000, 0, 1, 0, 0, 0, 0).getTime(),
+ });
+
+ fetchMock.get("http://this.is.a.url/test.dummy/fromEvent.png", "TESTFILE");
+ const { getByRole } = render(
+ ,
+ );
+ fireEvent.click(getByRole("button", { name: "Download" }));
+ await waitFor(() =>
+ expect(mocked(FileDownloader).mock.instances[0].download).toHaveBeenCalledWith({
+ blob: expect.anything(),
+ name: "fromEvent.png",
+ }),
+ );
+ expect(fetchMock).toHaveFetched("http://this.is.a.url/test.dummy/fromEvent.png");
+ });
+
it("should start download on Ctrl+S", async () => {
fetchMock.get("https://example.com/image.png", "TESTFILE");