Skip to content

Commit

Permalink
Flash: show error when not enough storage quota (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
incognitojam authored Feb 20, 2025
1 parent d96877f commit e7a00c2
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
11 changes: 9 additions & 2 deletions src/app/Flash.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ 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. Your browser may ' +
'be restricting the available space if you are in a private, incognito or guest session.',
},
}

if (isLinux) {
Expand Down Expand Up @@ -206,6 +210,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()
Expand All @@ -222,6 +227,8 @@ export default function Flash() {
if (progress >= 0) {
title += ` (${(progress * 100).toFixed(0)}%)`
}
} else if (error === Error.STORAGE_SPACE) {
title = message
} else {
title = status
}
Expand All @@ -237,8 +244,8 @@ export default function Flash() {
<div id="flash" className="relative flex flex-col gap-8 justify-center items-center h-full">
<div
className={`p-8 rounded-full ${bgColor}`}
style={{ cursor: step === Step.READY ? 'pointer' : 'default' }}
onClick={step === Step.READY ? handleStart : null}
style={{ cursor: canStart ? 'pointer' : 'default' }}
onClick={canStart ? handleStart : null}
>
<img
src={icon}
Expand Down
1 change: 1 addition & 0 deletions src/utils/manifest.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => ({
Expand Down
8 changes: 7 additions & 1 deletion src/utils/qdl.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const Error = {
FLASH_FAILED: 6,
ERASE_FAILED: 7,
REQUIREMENTS_NOT_MET: 8,
STORAGE_SPACE: 9,
}

/**
Expand Down Expand Up @@ -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)
}
}
}

Expand Down
18 changes: 11 additions & 7 deletions src/workers/image.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ async function readChunks(reader, total, { onChunk, onProgress = undefined }) {
}
}

const MIN_QUOTA_MB = 5250

/** @type {FileSystemDirectoryHandle} */
let root

Expand All @@ -48,15 +50,17 @@ let root

const imageWorker = {
async init() {
if (root) {
console.warn('[ImageWorker] Already initialized')
return
if (!root) {
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 })
console.info('[ImageWorker] Initialized')
const estimate = await navigator.storage.estimate()
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`
}
},

/**
Expand Down

0 comments on commit e7a00c2

Please sign in to comment.