mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
Implement FileSystemFileHandle
for file input (#124)
This removes the `FileSystemFileHandleLike` interface in preference to just implementing the correct interface. The advantage of the `FileSystemFileHandle` interface is that it can be passed to the worker directly to load the file.
This commit is contained in:
parent
3bbc77049d
commit
203d89b8d9
@ -12,17 +12,9 @@ const ACCEPT_EVERYTHING_TYPE: FilePickerAcceptType = {
|
||||
accept: { '*/*': [] },
|
||||
};
|
||||
|
||||
export interface FileSystemFileHandleLike {
|
||||
readonly name: string;
|
||||
readonly kind: string;
|
||||
readonly isWritable: boolean;
|
||||
getFile(): Promise<File>;
|
||||
createWritable: FileSystemFileHandle['createWritable'];
|
||||
}
|
||||
|
||||
export interface FileChooserProps {
|
||||
disabled?: boolean;
|
||||
onChange: (handles: Array<FileSystemFileHandleLike>) => void;
|
||||
onChange: (handles: Array<FileSystemFileHandle>) => void;
|
||||
accept?: FilePickerAcceptType[];
|
||||
control?: typeof controlDefault;
|
||||
}
|
||||
@ -170,7 +162,7 @@ export const FileChooser = ({
|
||||
}: FileChooserProps) => {
|
||||
|
||||
const onChangeForInput = useCallback((files: FileList) => {
|
||||
const handles: FileSystemFileHandleLike[] = [];
|
||||
const handles: FileSystemFileHandle[] = [];
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files.item(i);
|
||||
if (file === null) {
|
||||
@ -180,25 +172,19 @@ export const FileChooser = ({
|
||||
kind: 'file',
|
||||
name: file.name,
|
||||
getFile: () => Promise.resolve(file),
|
||||
isWritable: false,
|
||||
createWritable: (_options) => Promise.reject('File not writable.'),
|
||||
queryPermission: (descriptor) => Promise.resolve(descriptor === 'read' ? 'granted' : 'denied'),
|
||||
requestPermission: (descriptor) => Promise.resolve(descriptor === 'read' ? 'granted' : 'denied'),
|
||||
isSameEntry: (_unused) => Promise.resolve(false),
|
||||
isDirectory: false,
|
||||
isFile: true,
|
||||
});
|
||||
}
|
||||
onChange(handles);
|
||||
}, [onChange]);
|
||||
|
||||
const onChangeForPicker = useCallback((fileHandles: FileSystemFileHandle[]) => {
|
||||
const handles: FileSystemFileHandleLike[] = [];
|
||||
for (const fileHandle of fileHandles) {
|
||||
handles.push({
|
||||
kind: fileHandle.kind,
|
||||
name: fileHandle.name,
|
||||
getFile: () => fileHandle.getFile(),
|
||||
isWritable: true,
|
||||
createWritable: (options) => fileHandle.createWritable(options),
|
||||
});
|
||||
}
|
||||
onChange(handles);
|
||||
onChange(fileHandles);
|
||||
}, [onChange]);
|
||||
|
||||
return control === 'picker'
|
||||
|
@ -7,9 +7,9 @@ import DiskII from '../cards/disk2';
|
||||
import { ErrorModal } from './ErrorModal';
|
||||
|
||||
import index from 'json/disks/index.json';
|
||||
import { FileChooser, FilePickerAcceptType, FileSystemFileHandleLike } from './FileChooser';
|
||||
import { noAwait } from './util/promises';
|
||||
import { useHash } from './hooks/useHash';
|
||||
import { FileChooser, FilePickerAcceptType } from './FileChooser';
|
||||
|
||||
const DISK_TYPES: FilePickerAcceptType[] = [
|
||||
{
|
||||
@ -50,7 +50,7 @@ export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) =>
|
||||
const [busy, setBusy] = useState<boolean>(false);
|
||||
const [empty, setEmpty] = useState<boolean>(true);
|
||||
const [category, setCategory] = useState<string>();
|
||||
const [handles, setHandles] = useState<FileSystemFileHandleLike[]>();
|
||||
const [handles, setHandles] = useState<FileSystemFileHandle[]>();
|
||||
const [filename, setFilename] = useState<string>();
|
||||
const [error, setError] = useState<unknown>();
|
||||
const hash = useHash();
|
||||
@ -82,7 +82,7 @@ export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) =>
|
||||
setHashParts(hashParts);
|
||||
}, [disk2, filename, number, onClose, handles, hash]);
|
||||
|
||||
const onChange = useCallback((handles: FileSystemFileHandleLike[]) => {
|
||||
const onChange = useCallback((handles: FileSystemFileHandle[]) => {
|
||||
setEmpty(handles.length === 0);
|
||||
setHandles(handles);
|
||||
}, []);
|
||||
|
@ -69,9 +69,9 @@ describe('FileChooser', () => {
|
||||
const handle = handleList[0];
|
||||
expect(handle.kind).toBe('file');
|
||||
expect(handle.name).toBe(FAKE_FILE.name);
|
||||
expect(handle.isWritable).toBe(false);
|
||||
await expect(handle.getFile()).resolves.toBe(FAKE_FILE);
|
||||
await expect(handle.createWritable()).rejects.toEqual('File not writable.');
|
||||
await expect(handle.queryPermission({ mode: 'readwrite' })).resolves.toBe('denied');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -125,7 +125,6 @@ describe('FileChooser', () => {
|
||||
const handle = handleList[0];
|
||||
expect(handle.kind).toBe(FAKE_FILE_HANDLE.kind);
|
||||
expect(handle.name).toBe(FAKE_FILE_HANDLE.name);
|
||||
expect(handle.isWritable).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user