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