From 7a75752e461a04b1365d5cb6de5220a516a68733 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 20 Feb 2025 23:26:04 +0000 Subject: [PATCH 1/6] Flash: show error when not enough storage quota --- src/app/Flash.jsx | 5 +++++ src/utils/qdl.js | 8 +++++++- src/workers/image.worker.js | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/app/Flash.jsx b/src/app/Flash.jsx index 33e66bc..0fac9c5 100644 --- a/src/app/Flash.jsx +++ b/src/app/Flash.jsx @@ -105,6 +105,9 @@ const errors = { description: 'Your system does not meet the requirements to flash your device. Make sure to use a browser which ' + 'supports WebUSB and is up to date.', }, + [Error.STORAGE_SPACE]: { + description: 'Your system does not have enough space available to download the system image.', + }, } if (isLinux) { @@ -222,6 +225,8 @@ export default function Flash() { if (progress >= 0) { title += ` (${(progress * 100).toFixed(0)}%)` } + } else if (error === Error.STORAGE_SPACE) { + title = message } else { title = status } diff --git a/src/utils/qdl.js b/src/utils/qdl.js index a151f67..509bd4b 100644 --- a/src/utils/qdl.js +++ b/src/utils/qdl.js @@ -25,6 +25,7 @@ export const Error = { FLASH_FAILED: 6, ERASE_FAILED: 7, REQUIREMENTS_NOT_MET: 8, + STORAGE_SPACE: 9, } /** @@ -170,7 +171,12 @@ export class QdlManager { this.setStep(Step.READY) } catch (err) { console.error('[QDL] Initialization error', err) - this.setError(Error.UNKNOWN) + if (err.startsWith('Not enough storage')) { + this.setError(Error.STORAGE_SPACE) + this.setMessage(err) + } else { + this.setError(Error.UNKNOWN) + } } } diff --git a/src/workers/image.worker.js b/src/workers/image.worker.js index a9b1d82..55ec2dd 100644 --- a/src/workers/image.worker.js +++ b/src/workers/image.worker.js @@ -39,6 +39,8 @@ async function readChunks(reader, total, { onChunk, onProgress = undefined }) { } } +const MIN_QUOTA_MB = 6000 + /** @type {FileSystemDirectoryHandle} */ let root @@ -56,6 +58,13 @@ const imageWorker = { // TODO: check storage quota and report error if insufficient root = await navigator.storage.getDirectory() await root.remove({ recursive: true }) + + const estimate = await navigator.storage.estimate() + const quotaMB = (estimate.quota || 0) / 1024 / 1024 + if (quotaMB < MIN_QUOTA_MB) { + throw `Not enough storage: ${quotaMB.toFixed(0)}MB free, need ${MIN_QUOTA_MB.toFixed(0)}MB` + } + console.info('[ImageWorker] Initialized') }, From 94024e6934ee94a1630f1f72b30bdc7b72ec7dcd Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 20 Feb 2025 23:28:03 +0000 Subject: [PATCH 2/6] bugfix --- src/app/Flash.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/Flash.jsx b/src/app/Flash.jsx index 0fac9c5..e400679 100644 --- a/src/app/Flash.jsx +++ b/src/app/Flash.jsx @@ -209,6 +209,7 @@ export default function Flash() { // Handle user clicking the start button const handleStart = () => qdlManager.current?.start() + const canStart = step === Step.READY && !error // Handle retry on error const handleRetry = () => window.location.reload() @@ -242,8 +243,8 @@ export default function Flash() {
Date: Thu, 20 Feb 2025 23:28:28 +0000 Subject: [PATCH 3/6] mock --- src/utils/manifest.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/manifest.test.js b/src/utils/manifest.test.js index 8fc87de..617bea3 100644 --- a/src/utils/manifest.test.js +++ b/src/utils/manifest.test.js @@ -7,6 +7,7 @@ import { getManifest } from './manifest' globalThis.navigator = { storage: { + estimate: vi.fn().mockImplementation(() => ({ quota: 10 * (1024 ** 3) })), getDirectory: () => ({ getFileHandle: () => ({ createWritable: vi.fn().mockImplementation(() => ({ From 6b24638ff4bfc456ce0cd26727ed224d46f5ab01 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 20 Feb 2025 23:30:51 +0000 Subject: [PATCH 4/6] incognito warning --- src/app/Flash.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/Flash.jsx b/src/app/Flash.jsx index e400679..b667443 100644 --- a/src/app/Flash.jsx +++ b/src/app/Flash.jsx @@ -106,7 +106,8 @@ const errors = { 'supports WebUSB and is up to date.', }, [Error.STORAGE_SPACE]: { - description: 'Your system does not have enough space available to download the system image.', + description: 'Your system does not have enough space available to download the system image. Your browser may ' + + 'be restricting the available space if you are in a private, incognito or guest session.', }, } From ec529c938015022d47c934c8681e699b22123f77 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 20 Feb 2025 23:46:19 +0000 Subject: [PATCH 5/6] reduce quota --- src/app/Flash.jsx | 2 +- src/workers/image.worker.js | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/app/Flash.jsx b/src/app/Flash.jsx index b667443..05d191d 100644 --- a/src/app/Flash.jsx +++ b/src/app/Flash.jsx @@ -107,7 +107,7 @@ const errors = { }, [Error.STORAGE_SPACE]: { description: 'Your system does not have enough space available to download the system image. Your browser may ' + - 'be restricting the available space if you are in a private, incognito or guest session.', + 'be restricting the available space if you are in a private, incognito or guest session.', }, } diff --git a/src/workers/image.worker.js b/src/workers/image.worker.js index 55ec2dd..e2947de 100644 --- a/src/workers/image.worker.js +++ b/src/workers/image.worker.js @@ -39,7 +39,7 @@ async function readChunks(reader, total, { onChunk, onProgress = undefined }) { } } -const MIN_QUOTA_MB = 6000 +const MIN_QUOTA_MB = 5250 /** @type {FileSystemDirectoryHandle} */ let root @@ -50,22 +50,18 @@ let root const imageWorker = { async init() { - if (root) { - console.warn('[ImageWorker] Already initialized') - return + if (!root) { + // TODO: check storage quota and report error if insufficient + root = await navigator.storage.getDirectory() + await root.remove({ recursive: true }) + console.info('[ImageWorker] Initialized') } - // TODO: check storage quota and report error if insufficient - root = await navigator.storage.getDirectory() - await root.remove({ recursive: true }) - const estimate = await navigator.storage.estimate() - const quotaMB = (estimate.quota || 0) / 1024 / 1024 + const quotaMB = (estimate.quota || 0) / (1024 ** 2) if (quotaMB < MIN_QUOTA_MB) { throw `Not enough storage: ${quotaMB.toFixed(0)}MB free, need ${MIN_QUOTA_MB.toFixed(0)}MB` } - - console.info('[ImageWorker] Initialized') }, /** From 5cfacf425e5e82dea6b020b66b221f7d9a2d9020 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 20 Feb 2025 23:47:08 +0000 Subject: [PATCH 6/6] rm TODO --- src/workers/image.worker.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/workers/image.worker.js b/src/workers/image.worker.js index e2947de..bfb4df1 100644 --- a/src/workers/image.worker.js +++ b/src/workers/image.worker.js @@ -51,7 +51,6 @@ let root const imageWorker = { async init() { if (!root) { - // TODO: check storage quota and report error if insufficient root = await navigator.storage.getDirectory() await root.remove({ recursive: true }) console.info('[ImageWorker] Initialized')