aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/downloads.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/downloads.js29
1 files changed, 24 insertions, 5 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
index 9c6ced1..a71f289 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
@@ -133,11 +133,11 @@ export async function freeName(name, exists) {
}
/**
- * Where this download should be written.
+ * Where this download should be written, if a folder has been granted.
*
- * Returns a writable stream, or null meaning "there is nowhere to stream to —
- * collect it and hand the browser a blob". The caller opens the picker itself
- * in "ask" mode, because that one has to happen inside the click.
+ * Returns `{writable, name, open}` or null. Null does not mean failure: it
+ * means there is no granted folder, and the caller decides between handing the
+ * browser a blob and asking for a Save As.
*/
export async function openTarget(filename) {
if (!SUPPORTED || getMode() === 'ask') return null;
@@ -155,5 +155,24 @@ export async function openTarget(filename) {
};
const name = await freeName(filename, exists);
const handle = await dir.getFileHandle(name, { create: true });
- return { writable: await handle.createWritable(), name };
+ return {
+ writable: await handle.createWritable(),
+ name,
+ // Reading it back is the only way a page can "open" a file it wrote: hand
+ // the bytes to a tab and let the browser decide what to do with them. No
+ // web page can start a desktop application, or show a file manager.
+ open: async () => {
+ const file = await handle.getFile();
+ const url = URL.createObjectURL(file);
+ window.open(url, '_blank', 'noopener');
+ setTimeout(() => URL.revokeObjectURL(url), 60000);
+ },
+ };
}
+
+/**
+ * Below this, a download with no granted folder is collected in memory and
+ * handed to the browser, which saves it without asking. Above it that would
+ * mean holding gigabytes in a tab, so it is worth one Save As dialog instead.
+ */
+export const BLOB_LIMIT = 512 * 1024 * 1024;