Fix local block file

This commit is contained in:
Will Scullin 2022-06-04 13:48:22 -07:00
parent 7a9c0aa9d0
commit 6bb0eb7fbe
No known key found for this signature in database
GPG Key ID: 26DCD1042C6638CD
5 changed files with 31 additions and 24 deletions

View File

@ -13,7 +13,7 @@ import { Screen } from './Screen';
import { Drives } from './Drives';
import { Slinky } from './Slinky';
import { ThunderClock } from './ThunderClock';
import { Ready } from './util/ready';
import { Ready } from './util/promises';
import styles from './css/Apple2.module.css';

View File

@ -1,5 +1,5 @@
import { h, Fragment } from 'preact';
import { useCallback, useRef, useState } from 'preact/hooks';
import { useCallback, useState } from 'preact/hooks';
import { DriveNumber, BLOCK_FORMATS } from '../formats/types';
import { ErrorModal } from './ErrorModal';
import { FileChooser } from './FileChooser';
@ -7,6 +7,7 @@ import { Modal, ModalContent, ModalFooter } from './Modal';
import { loadLocalBlockFile, getHashParts, setHashParts } from './util/files';
import SmartPort from 'js/cards/smartport';
import { useHash } from './hooks/useHash';
import { noAwait } from './util/promises';
import styles from './css/BlockFileModal.module.css';
@ -25,7 +26,7 @@ interface BlockFileModalProps {
}
export const BlockFileModal = ({ smartPort, number, onClose, isOpen } : BlockFileModalProps) => {
const inputRef = useRef<HTMLInputElement>(null);
const [handles, setHandles] = useState<FileSystemFileHandle[]>();
const [busy, setBusy] = useState<boolean>(false);
const [empty, setEmpty] = useState<boolean>(true);
const [error, setError] = useState<unknown>();
@ -33,13 +34,13 @@ export const BlockFileModal = ({ smartPort, number, onClose, isOpen } : BlockFil
const doCancel = useCallback(() => onClose(true), [onClose]);
const doOpen = useCallback(() => {
const doOpen = useCallback(async () => {
const hashParts = getHashParts(hash);
if (smartPort && inputRef.current && inputRef.current.files?.length === 1) {
if (smartPort && handles?.length === 1) {
hashParts[number] = '';
setBusy(true);
loadLocalBlockFile(smartPort, number, inputRef.current.files[0])
loadLocalBlockFile(smartPort, number, await handles[0].getFile())
.catch((error) => setError(error))
.finally(() => {
setBusy(false);
@ -48,13 +49,13 @@ export const BlockFileModal = ({ smartPort, number, onClose, isOpen } : BlockFil
}
setHashParts(hashParts);
}, [hash, smartPort, number, onClose]);
}, [handles, hash, smartPort, number, onClose]);
const onChange = useCallback((handles: FileSystemFileHandle[]) => {
setEmpty(handles.length === 0);
setHandles(handles);
}, []);
const onChange = useCallback(() => {
if (inputRef) {
setEmpty(!inputRef.current?.files?.length);
}
}, [ inputRef ]);
return (
<>
@ -66,7 +67,7 @@ export const BlockFileModal = ({ smartPort, number, onClose, isOpen } : BlockFil
</ModalContent>
<ModalFooter>
<button onClick={doCancel}>Cancel</button>
<button onClick={doOpen} disabled={busy || empty}>Open</button>
<button onClick={noAwait(doOpen)} disabled={busy || empty}>Open</button>
</ModalFooter>
</Modal>
<ErrorModal error={error} setError={setError} />

View File

@ -11,7 +11,7 @@ import { ProgressModal } from './ProgressModal';
import { loadHttpUnknownFile, getHashParts, loadJSON } from './util/files';
import { useHash } from './hooks/useHash';
import { DriveNumber } from 'js/formats/types';
import { Ready } from './util/ready';
import { Ready } from './util/promises';
import styles from './css/Drives.module.css';

View File

@ -10,3 +10,19 @@ export type NoAwait<F extends (...args: unknown[]) => Promise<unknown>> =
export function noAwait<F extends (...args: unknown[]) => Promise<unknown>>(f: F): NoAwait<F> {
return f as NoAwait<F>;
}
/**
* Utility class that allows a promise to be passed to a
* service to be resolved.
*/
export class Ready {
onReady: (value?: unknown) => void;
promise: Promise<unknown>;
constructor() {
this.promise = new Promise((resolve, _reject) => {
this.onReady = resolve;
}).catch(console.error);
}
}

View File

@ -1,10 +0,0 @@
export class Ready {
onReady: (value?: unknown) => void;
promise: Promise<unknown>;
constructor() {
this.promise = new Promise((resolve, _reject) => {
this.onReady = resolve;
}).catch(console.error);
}
}