From 715b66bc9b60eb49b6305aed971cc3c1fce77336 Mon Sep 17 00:00:00 2001 From: Francisco De La Hoz <39561227+franciscodelahoz@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:44:54 -0500 Subject: [PATCH] feat: implement file picker for loading ROM files and update UI for better user interaction --- src/html/index.html | 2 +- src/scripts/ui/controls/emulator.ts | 97 +++++++++++++++++++++++------ src/styles/style.css | 32 ++-------- 3 files changed, 84 insertions(+), 47 deletions(-) diff --git a/src/html/index.html b/src/html/index.html index 3f0e484..4aa3f52 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -22,7 +22,7 @@
- +
Click to Load ROM File
diff --git a/src/scripts/ui/controls/emulator.ts b/src/scripts/ui/controls/emulator.ts index ee7e835..b3803f2 100644 --- a/src/scripts/ui/controls/emulator.ts +++ b/src/scripts/ui/controls/emulator.ts @@ -1,17 +1,89 @@ import { Chip8Emulator } from '../../emulator/emulator'; -const input = document.getElementById('file') as HTMLInputElement | null; +const input = document.getElementById('file') as HTMLElement | null; const resetRomBtn = document.getElementById('reset-rom-btn') as HTMLElement | null; +async function getFileFromHandle(fileHandle: File | FileSystemFileHandle): Promise { + if (fileHandle instanceof FileSystemFileHandle) { + return await fileHandle.getFile(); + } else { + return fileHandle; + } +} + +async function handleFileInput(files: FileList | FileSystemFileHandle[], emulatorInstance: Chip8Emulator) { + let fileData = await getFileFromHandle(files[0]); + + try { + const arrayBuffer = await fileData.arrayBuffer(); + const romData = new Uint8Array(arrayBuffer); + + emulatorInstance.loadRomFromData(romData); + + } catch(error) { + return alert(`Error loading the ROM file.`); + } +} + +function setNowPlayingRomName(romName: string) { + if (!input) return; + input.innerText = `Loaded ROM: ${romName}`; +} + +async function handleFilePickerEvent(emulatorInstance: Chip8Emulator) { + const filePickerOptions: OpenFilePickerOptions = { + types: [ + { + description: 'Chip-8 ROM files', + accept: { + 'application/octet-stream': ['.ch8', '.sc8', '.xo8'], + }, + }, + ], + multiple: false, + }; + + const fileHandle = await window.showOpenFilePicker(filePickerOptions); + await handleFileInput(fileHandle, emulatorInstance); + + setNowPlayingRomName(fileHandle[0].name); +} + +async function handleFilePickerEventFallback(emulatorInstance: Chip8Emulator) { + const fileInput = document.createElement('input'); + + fileInput.type = 'file'; + fileInput.accept = '.ch8,.sc8,.xo8'; + fileInput.style.display = 'none'; + + fileInput.addEventListener('change', async (event) => { + const target = event.target as HTMLInputElement; + + if (target.files && target.files.length > 0) { + await handleFileInput(target.files, emulatorInstance); + setNowPlayingRomName(target.files[0].name); + } + }); + + document.body.appendChild(fileInput); + fileInput.click(); + document.body.removeChild(fileInput); +} + function initializeRomFileInputEventHandlers(emulatorInstance: Chip8Emulator) { if (!input) return; - input.addEventListener('change', async (event) => { + input.addEventListener('click', async () => { try { - await emulatorInstance.startEmulation(event as GenericEvent); - input.blur(); + if ('showOpenFilePicker' in window) { + await handleFilePickerEvent(emulatorInstance); + } else { + await handleFilePickerEventFallback(emulatorInstance); + } } catch(error) { - console.error(error); + if ((error as Error)?.name !== 'AbortError') { + return alert(`Error loading the ROM file.`); + } } }); } @@ -28,21 +100,6 @@ function initializeResetRomButtonEventHandlers(emulatorInstance: Chip8Emulator) }); } -async function handleFileInput(files: Array, emulatorInstance: Chip8Emulator) { - const fileHandle = files[0]; - - try { - const fileData = await fileHandle.getFile(); - const arrayBuffer = await fileData.arrayBuffer(); - - const romData = new Uint8Array(arrayBuffer); - emulatorInstance.loadRomFromData(romData); - - } catch(error) { - return alert(`Error loading the ROM file.`); - } -} - function registerFileHandlerLoadRom(emulatorInstance: Chip8Emulator) { window.launchQueue?.setConsumer(async (launchParams) => { if (launchParams.files.length) { diff --git a/src/styles/style.css b/src/styles/style.css index f3fcf8a..b5c12e1 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -82,16 +82,16 @@ body { width: 100%; } -.rom-controller input { - content: 'Upload rom file'; - border: 2px solid #34ff66; - padding: 5px; - border-radius: 5px; +#file { user-select: none; cursor: pointer; - flex-grow: 10; font-family: Verdana; font-size: 0.83rem; + flex-grow: 9; + border: 2px solid #34ff66; + padding: 5px; + border-radius: 5px; + text-overflow: ellipsis; } .default-button { @@ -161,26 +161,6 @@ body { height: 1.9rem; } -input[type="file"]::-webkit-file-upload-button { - display: none; -} - -input[type="file"]::-moz-file-upload-button { - display: none; -} - -input[type="file"]::-ms-file-upload-button { - display: none; -} - -input[type="file"]::-o-file-upload-button { - display: none; -} - -input[type="file"]::file-upload-button { - display: none; -} - .keyboard-container { padding: 0.6rem; }