diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index f71e2b9f..ec719aed 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -10,6 +10,8 @@ shareFile, } from "$lib/download"; + import type { CobaltFileUrlType } from "$lib/types/api"; + import DialogContainer from "$components/dialog/DialogContainer.svelte"; import Meowbalt from "$components/misc/Meowbalt.svelte"; @@ -22,12 +24,14 @@ import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte"; import CopyIcon from "$components/misc/CopyIcon.svelte"; + export let id: string; export let dismissable = true; export let bodyText: string = ""; export let url: string = ""; export let file: File | undefined = undefined; + export let urlType: CobaltFileUrlType | undefined = undefined; let close: () => void; @@ -55,7 +59,7 @@ </div> <div class="action-buttons"> - {#if device.supports.directDownload} + {#if device.supports.directDownload && !(device.is.iOS && urlType === "redirect")} <VerticalActionButton id="save-download" fill diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index e8d24f0f..7dec3a36 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -88,6 +88,7 @@ return downloadFile({ url: response.url, + urlType: "redirect", }); } diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts index 78e465de..827b33b1 100644 --- a/web/src/lib/download.ts +++ b/web/src/lib/download.ts @@ -4,16 +4,31 @@ import settings from "$lib/state/settings"; import { device } from "$lib/device"; import { t } from "$lib/i18n/translations"; - import { createDialog } from "$lib/dialogs"; -import type { DialogInfo } from "$lib/types/dialog"; -const openSavingDialog = ({ url, file, body }: { url?: string, file?: File, body?: string }) => { +import type { DialogInfo } from "$lib/types/dialog"; +import type { CobaltFileUrlType } from "$lib/types/api"; + +type DownloadFileParams = { + url?: string, + file?: File, + urlType?: CobaltFileUrlType, +} + +type SavingDialogParams = { + url?: string, + file?: File, + body?: string, + urlType?: CobaltFileUrlType, +} + +const openSavingDialog = ({ url, file, body, urlType }: SavingDialogParams) => { const dialogData: DialogInfo = { type: "saving", id: "saving", file, url, + urlType, } if (body) dialogData.bodyText = body; @@ -60,13 +75,13 @@ export const copyURL = async (url: string) => { return await navigator?.clipboard?.writeText(url); } -export const downloadFile = ({ url, file }: { url?: string, file?: File }) => { +export const downloadFile = ({ url, file, urlType }: DownloadFileParams) => { if (!url && !file) throw new Error("attempted to download void"); const pref = get(settings).save.savingMethod; if (pref === "ask") { - return openSavingDialog({ url, file }); + return openSavingDialog({ url, file, urlType }); } /* @@ -85,6 +100,7 @@ export const downloadFile = ({ url, file }: { url?: string, file?: File }) => { url, file, body: get(t)("dialog.saving.timeout"), + urlType }); } @@ -100,7 +116,8 @@ export const downloadFile = ({ url, file }: { url?: string, file?: File }) => { if (url) { if (pref === "share" && device.supports.share) { return shareURL(url); - } else if (pref === "download" && device.supports.directDownload) { + } else if (pref === "download" && device.supports.directDownload + && !(device.is.iOS && urlType === "redirect")) { return openURL(url); } else if (pref === "copy" && !file) { return copyURL(url); @@ -108,5 +125,5 @@ export const downloadFile = ({ url, file }: { url?: string, file?: File }) => { } } catch { /* catch & ignore */ } - return openSavingDialog({ url, file }); + return openSavingDialog({ url, file, urlType }); } diff --git a/web/src/lib/types/api.ts b/web/src/lib/types/api.ts index e7e4307d..20161775 100644 --- a/web/src/lib/types/api.ts +++ b/web/src/lib/types/api.ts @@ -40,6 +40,8 @@ type CobaltTunnelResponse = { status: CobaltResponseType.Tunnel, } & CobaltPartialURLResponse; +export type CobaltFileUrlType = "redirect" | "tunnel"; + export type CobaltSession = { token: string, exp: number, @@ -65,6 +67,6 @@ export type CobaltSessionResponse = CobaltSession | CobaltErrorResponse; export type CobaltServerInfoResponse = CobaltServerInfo | CobaltErrorResponse; export type CobaltAPIResponse = CobaltErrorResponse - | CobaltPickerResponse - | CobaltRedirectResponse - | CobaltTunnelResponse; + | CobaltPickerResponse + | CobaltRedirectResponse + | CobaltTunnelResponse; diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index fa0df5fe..69e27b5d 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -1,3 +1,4 @@ +import type { CobaltFileUrlType } from "$lib/types/api"; import type { MeowbaltEmotions } from "$lib/types/meowbalt"; export type DialogButton = { @@ -43,6 +44,7 @@ type SavingDialog = Dialog & { bodyText?: string, url?: string, file?: File, + urlType?: CobaltFileUrlType, }; export type DialogInfo = SmallDialog | PickerDialog | SavingDialog;