From 5c780a2d2e37757e2e74329399c4df85578234a0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 18:59:58 +0600 Subject: [PATCH] web: added saving method preference, made downloading resilient --- web/i18n/en/settings.json | 9 +++-- web/src/components/dialog/SavingDialog.svelte | 4 +- web/src/lib/device.ts | 15 ++++--- web/src/lib/download.ts | 39 ++++++++++--------- web/src/lib/settings/defaults.ts | 2 +- web/src/lib/settings/migrate.ts | 2 - web/src/lib/types/settings.ts | 3 +- web/src/routes/settings/download/+page.svelte | 25 +++++++----- 8 files changed, 56 insertions(+), 43 deletions(-) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 0127627b..69555ab3 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -72,9 +72,12 @@ "metadata.disable.title": "disable file metadata", "metadata.disable.description": "title, artist, and other info will not be added to the file.", - "saving.method": "saving method", - "saving.ask.title": "ask how to save", - "saving.ask.description": "offer several ways to save the file instead of opening it in a new tab.", + "saving.title": "saving method", + "saving.ask": "ask", + "saving.download": "download", + "saving.share": "share", + "saving.copy": "copy", + "saving.description": "preferred way of saving the file or link from cobalt. if preferred method is unavailable or something goes wrong, cobalt will ask you what to do next.", "accessibility": "accessibility", "accessibility.transparency.title": "reduce visual transparency", diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index 34c84b84..5e1832ab 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -34,7 +34,7 @@
- {#if !(app.is.installed && device.is.iOS)} + {#if device.supports.directDownload} {/if} - {#if navigator.share !== undefined} + {#if device.supports.share} { /* if new tab got blocked by user agent, show a saving dialog */ if (!open) { - openSavingDialog(url); + return openSavingDialog(url); } } export const shareURL = async (url: string) => { - try { - return await navigator?.share({ url }); - } catch { - return false; - } + return await navigator?.share({ url }); } export const copyURL = async (url: string) => { - try { - return await navigator?.clipboard.writeText(url); - } catch { - return false; - } + return await navigator?.clipboard?.writeText(url); } export const downloadFile = (url: string) => { - const savingPreference = get(settings).save.downloadPopup; + const pref = get(settings).save.savingMethod; /* user actions (such as invoke share, open new tab) have expiration. @@ -49,11 +41,20 @@ export const downloadFile = (url: string) => { invoke an action without the user agent interrupting it. if not, we show a saving dialog for user to re-invoke that action. */ - if (savingPreference || !navigator.userActivation.isActive) { - openSavingDialog(url); - } else if (device.is.iOS && app.is.installed) { - return shareURL(url); - } else { - return openURL(url); + + if (pref === "ask" || !navigator.userActivation.isActive) { + return openSavingDialog(url); } + + try { + if (pref === "share" && device.supports.share) { + return shareURL(url); + } else if (pref === "download" && device.supports.directDownload) { + return openURL(url); + } else if (pref === "copy") { + return copyURL(url); + } + } catch {} + + return openSavingDialog(url); } diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index 528d2cad..58f46fec 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -18,8 +18,8 @@ const defaultSettings: CobaltSettings = { audioFormat: "mp3", disableMetadata: false, downloadMode: "auto", - downloadPopup: false, filenameStyle: "classic", + savingMethod: "download", tiktokH265: false, tiktokFullAudio: false, twitterGif: false, diff --git a/web/src/lib/settings/migrate.ts b/web/src/lib/settings/migrate.ts index 81feb99f..769ab360 100644 --- a/web/src/lib/settings/migrate.ts +++ b/web/src/lib/settings/migrate.ts @@ -10,7 +10,6 @@ const oldSwitcherValues = { const oldCheckboxes = [ 'audioMode', - 'downloadPopup', 'fullTikTokAudio', 'muteAudio', 'reduceTransparency', @@ -101,7 +100,6 @@ export const migrateOldSettings = () => { filenameStyle: getLiteral('filenamePattern'), tiktokFullAudio: getBool('fullTikTokAudio'), tiktokH265: getBool('tiktokH265'), - downloadPopup: getBool('downloadPopup'), disableMetadata: getBool('disableMetadata'), twitterGif: getBool('twitterGif'), youtubeDubBrowserLang: getBool('ytDub'), diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index 5965bf49..ff4c66b7 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -7,6 +7,7 @@ export const downloadModeOptions = ["auto", "audio", "mute"] as const; export const filenameStyleOptions = ["classic", "basic", "pretty", "nerdy"] as const; export const videoQualityOptions = ["max", "2160", "1440", "1080", "720", "480", "360", "240", "144"] as const; export const youtubeVideoCodecOptions = ["h264", "av1", "vp9"] as const; +export const savingMethodOptions = ["ask", "download", "share", "copy"] as const; type CobaltSettingsAppearance = { theme: typeof themeOptions[number], @@ -28,8 +29,8 @@ type CobaltSettingsSave = { audioFormat: typeof audioFormatOptions[number], disableMetadata: boolean, downloadMode: typeof downloadModeOptions[number], - downloadPopup: boolean, filenameStyle: typeof filenameStyleOptions[number], + savingMethod: typeof savingMethodOptions[number], tiktokH265: boolean, tiktokFullAudio: boolean, twitterGif: boolean, diff --git a/web/src/routes/settings/download/+page.svelte b/web/src/routes/settings/download/+page.svelte index 6e6ea6f0..5c5985b2 100644 --- a/web/src/routes/settings/download/+page.svelte +++ b/web/src/routes/settings/download/+page.svelte @@ -1,7 +1,7 @@