From 82091db1547ba00999057f6dde36b535d6c5d2ca Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 13:32:21 +0600 Subject: [PATCH] web/download: open saving dialog if user action expired --- web/src/lib/download.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts index 74f65606..34d1a3ad 100644 --- a/web/src/lib/download.ts +++ b/web/src/lib/download.ts @@ -5,6 +5,13 @@ import settings from "$lib/state/settings"; import { createDialog } from "$lib/dialogs"; +export const openSavingDialog = (url: string) => + createDialog({ + type: "saving", + id: "saving", + url + }) + export const openURL = (url: string) => { return window.open(url, "_blank"); } @@ -27,12 +34,18 @@ export const copyURL = async (url: string) => { export const downloadFile = (url: string) => { const savingPreference = get(settings).save.downloadPopup; - if (savingPreference) { - createDialog({ - type: "saving", - id: "saving", - url - }) + + /* + user actions (such as invoke share, open new tab) have expiration. + in webkit, for example, that timeout is 5 seconds. + https://github.com/WebKit/WebKit/blob/b838f8bb3573bd5906bc5f02fcc8cb274b3c9b8a/Source/WebCore/page/LocalDOMWindow.cpp#L167 + + navigator.userActivation.isActive makes sure that we're still able to + 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 {