web: prevent openURL action on ios devices if url is redirect

This commit is contained in:
wukko 2024-09-23 15:06:57 +06:00
parent 12f7ee874e
commit ba93492c8d
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
5 changed files with 37 additions and 11 deletions

View file

@ -10,6 +10,8 @@
shareFile, shareFile,
} from "$lib/download"; } from "$lib/download";
import type { CobaltFileUrlType } from "$lib/types/api";
import DialogContainer from "$components/dialog/DialogContainer.svelte"; import DialogContainer from "$components/dialog/DialogContainer.svelte";
import Meowbalt from "$components/misc/Meowbalt.svelte"; import Meowbalt from "$components/misc/Meowbalt.svelte";
@ -22,12 +24,14 @@
import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte"; import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte";
import CopyIcon from "$components/misc/CopyIcon.svelte"; import CopyIcon from "$components/misc/CopyIcon.svelte";
export let id: string; export let id: string;
export let dismissable = true; export let dismissable = true;
export let bodyText: string = ""; export let bodyText: string = "";
export let url: string = ""; export let url: string = "";
export let file: File | undefined = undefined; export let file: File | undefined = undefined;
export let urlType: CobaltFileUrlType | undefined = undefined;
let close: () => void; let close: () => void;
@ -55,7 +59,7 @@
</div> </div>
<div class="action-buttons"> <div class="action-buttons">
{#if device.supports.directDownload} {#if device.supports.directDownload && !(device.is.iOS && urlType === "redirect")}
<VerticalActionButton <VerticalActionButton
id="save-download" id="save-download"
fill fill

View file

@ -88,6 +88,7 @@
return downloadFile({ return downloadFile({
url: response.url, url: response.url,
urlType: "redirect",
}); });
} }

View file

@ -4,16 +4,31 @@ import settings from "$lib/state/settings";
import { device } from "$lib/device"; import { device } from "$lib/device";
import { t } from "$lib/i18n/translations"; import { t } from "$lib/i18n/translations";
import { createDialog } from "$lib/dialogs"; 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 = { const dialogData: DialogInfo = {
type: "saving", type: "saving",
id: "saving", id: "saving",
file, file,
url, url,
urlType,
} }
if (body) dialogData.bodyText = body; if (body) dialogData.bodyText = body;
@ -60,13 +75,13 @@ export const copyURL = async (url: string) => {
return await navigator?.clipboard?.writeText(url); 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"); if (!url && !file) throw new Error("attempted to download void");
const pref = get(settings).save.savingMethod; const pref = get(settings).save.savingMethod;
if (pref === "ask") { 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, url,
file, file,
body: get(t)("dialog.saving.timeout"), body: get(t)("dialog.saving.timeout"),
urlType
}); });
} }
@ -100,7 +116,8 @@ export const downloadFile = ({ url, file }: { url?: string, file?: File }) => {
if (url) { if (url) {
if (pref === "share" && device.supports.share) { if (pref === "share" && device.supports.share) {
return shareURL(url); 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); return openURL(url);
} else if (pref === "copy" && !file) { } else if (pref === "copy" && !file) {
return copyURL(url); return copyURL(url);
@ -108,5 +125,5 @@ export const downloadFile = ({ url, file }: { url?: string, file?: File }) => {
} }
} catch { /* catch & ignore */ } } catch { /* catch & ignore */ }
return openSavingDialog({ url, file }); return openSavingDialog({ url, file, urlType });
} }

View file

@ -40,6 +40,8 @@ type CobaltTunnelResponse = {
status: CobaltResponseType.Tunnel, status: CobaltResponseType.Tunnel,
} & CobaltPartialURLResponse; } & CobaltPartialURLResponse;
export type CobaltFileUrlType = "redirect" | "tunnel";
export type CobaltSession = { export type CobaltSession = {
token: string, token: string,
exp: number, exp: number,
@ -65,6 +67,6 @@ export type CobaltSessionResponse = CobaltSession | CobaltErrorResponse;
export type CobaltServerInfoResponse = CobaltServerInfo | CobaltErrorResponse; export type CobaltServerInfoResponse = CobaltServerInfo | CobaltErrorResponse;
export type CobaltAPIResponse = CobaltErrorResponse export type CobaltAPIResponse = CobaltErrorResponse
| CobaltPickerResponse | CobaltPickerResponse
| CobaltRedirectResponse | CobaltRedirectResponse
| CobaltTunnelResponse; | CobaltTunnelResponse;

View file

@ -1,3 +1,4 @@
import type { CobaltFileUrlType } from "$lib/types/api";
import type { MeowbaltEmotions } from "$lib/types/meowbalt"; import type { MeowbaltEmotions } from "$lib/types/meowbalt";
export type DialogButton = { export type DialogButton = {
@ -43,6 +44,7 @@ type SavingDialog = Dialog & {
bodyText?: string, bodyText?: string,
url?: string, url?: string,
file?: File, file?: File,
urlType?: CobaltFileUrlType,
}; };
export type DialogInfo = SmallDialog | PickerDialog | SavingDialog; export type DialogInfo = SmallDialog | PickerDialog | SavingDialog;