From c7f36596e3097258c8b2930d5783b5171b97e367 Mon Sep 17 00:00:00 2001 From: Will Scullin Date: Sun, 24 Jul 2022 13:53:06 -0700 Subject: [PATCH] lazy load file index --- js/components/FileModal.tsx | 54 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/js/components/FileModal.tsx b/js/components/FileModal.tsx index 79e9468..e6cbe20 100644 --- a/js/components/FileModal.tsx +++ b/js/components/FileModal.tsx @@ -1,18 +1,19 @@ import { h, Fragment, JSX } from 'preact'; -import { useCallback, useState } from 'preact/hooks'; +import { useCallback, useEffect, useState } from 'preact/hooks'; import { DiskDescriptor, DriveNumber, NibbleFormat, NIBBLE_FORMATS } from '../formats/types'; import { Modal, ModalContent, ModalFooter } from './Modal'; import { loadLocalNibbleFile, loadJSON, getHashParts, setHashParts } from './util/files'; import DiskII from '../cards/disk2'; import { ErrorModal } from './ErrorModal'; -import index from 'json/disks/index.json'; -import { noAwait } from './util/promises'; +import { noAwait, spawn } from './util/promises'; import { useHash } from './hooks/useHash'; import { FileChooser, FilePickerAcceptType } from './FileChooser'; import styles from './css/FileModal.module.css'; +const indexJSON = import('json/disks/index.json'); + const DISK_TYPES: FilePickerAcceptType[] = [ { description: 'Disk Images', @@ -20,21 +21,6 @@ const DISK_TYPES: FilePickerAcceptType[] = [ } ]; -const categories = index.reduce>( - ( - acc: Record, - disk: DiskDescriptor - ) => { - const category = disk.category || 'Misc'; - acc[category] = [disk, ...(acc[category] || [])]; - - return acc; - }, - {} -); - -const categoryNames = Object.keys(categories).sort(); - export type NibbleFileCallback = ( name: string, fmt: NibbleFormat, @@ -48,6 +34,12 @@ interface FileModalProps { onClose: (closeBox?: boolean) => void; } +interface IndexEntry { + filename: string; + name: string; + category: string; +} + export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) => { const [busy, setBusy] = useState(false); const [empty, setEmpty] = useState(true); @@ -55,8 +47,16 @@ export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) => const [handles, setHandles] = useState(); const [filename, setFilename] = useState(); const [error, setError] = useState(); + const [index, setIndex] = useState(); const hash = useHash(); + useEffect(() => { + spawn(async () => { + const index = (await indexJSON).default; + setIndex(index); + }); + }, []); + const doCancel = useCallback(() => onClose(true), [onClose]); const doOpen = useCallback(async () => { @@ -102,6 +102,24 @@ export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) => }, [] ); + if (!index) { + return null; + } + + const categories = index.reduce>( + ( + acc: Record, + disk: DiskDescriptor + ) => { + const category = disk.category || 'Misc'; + acc[category] = [disk, ...(acc[category] || [])]; + + return acc; + }, + {} + ); + const categoryNames = Object.keys(categories).sort(); + const disks = category ? categories[category] : []; return (