import { useEffect, useCallback, useState } from "react"; import type { NextPage } from "next"; import Head from "next/head"; import "mapbox-gl/dist/mapbox-gl.css"; import Map from "../components/Map"; import { useAppDispatch } from "../lib/hooks"; import { isPlugin, isPluginPath, parsePluginFiles } from "../lib/plugins"; import { setPluginsTxtAndApplyLoadOrder } from "../slices/pluginsTxt"; import { WorkerPool, WorkerPoolContext } from "../lib/WorkerPool"; const Home: NextPage = () => { const [workerPool, setWorkerPool] = useState(null); const dispatch = useAppDispatch(); const createWorkerPool = useCallback(async () => { setWorkerPool( await new WorkerPool().init(window.navigator.hardwareConcurrency) ); }, []); useEffect(() => { return () => { if (workerPool) { workerPool.terminateAll(); } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [dispatch]); useEffect(() => { createWorkerPool(); }, [createWorkerPool]); return ( <> Modmapper
{ evt.preventDefault(); }} onDrop={async (evt) => { evt.preventDefault(); if (evt.dataTransfer.items && evt.dataTransfer.items.length > 0) { const item = evt.dataTransfer.items[0]; if (item.kind === "file") { // Gotta love all these competing web file system standards... if ( ( item as DataTransferItem & { getAsFileSystemHandle?: () => Promise; } ).getAsFileSystemHandle ) { const entry = await ( item as DataTransferItem & { getAsFileSystemHandle: () => Promise; } ).getAsFileSystemHandle(); if (entry.kind === "file") { const file = await ( entry as FileSystemFileHandle ).getFile(); dispatch(setPluginsTxtAndApplyLoadOrder(await file.text())); return; } else if (entry.kind === "directory") { const plugins: { getFile: () => Promise }[] = []; const values = ( entry as FileSystemDirectoryHandle & { values: any } ).values(); // I'm scared of yield and generators so I'm just going to do a lame while loop while (true) { const next = await values.next(); if (next.done) { break; } if ( next.value.kind == "file" && isPluginPath(next.value.name) ) { plugins.push(next.value); } } const pluginFiles = await Promise.all( plugins.map(async (plugin) => plugin.getFile()) ); if (workerPool) { parsePluginFiles(pluginFiles, workerPool); } else { alert("Workers not loaded yet"); } } } else if ( ( item as DataTransferItem & { webkitGetAsEntry?: FileSystemEntry | null; } ).webkitGetAsEntry ) { const entry = item.webkitGetAsEntry(); if (entry?.isFile) { (entry as FileSystemFileEntry).file(async (file) => { dispatch( setPluginsTxtAndApplyLoadOrder(await file.text()) ); }); } else if (entry?.isDirectory) { const reader = ( entry as FileSystemDirectoryEntry ).createReader(); const plugins = await new Promise( (resolve, reject) => { const plugins: FileSystemFileEntry[] = []; reader.readEntries((entries) => { entries.forEach((entry) => { if (entry?.isFile && isPluginPath(entry.name)) { plugins.push(entry as FileSystemFileEntry); } }); resolve(plugins); }, reject); } ); const pluginFiles = await Promise.all( plugins.map( (plugin) => new Promise((resolve, reject) => plugin.file((file) => resolve(file), reject) ) ) ); if (workerPool) { parsePluginFiles(pluginFiles, workerPool); } else { alert("Workers not loaded yet"); } } } else { const file = item.getAsFile(); if (file) { dispatch(setPluginsTxtAndApplyLoadOrder(await file.text())); } } } else if (item.kind === "string") { item.getAsString((str) => { dispatch(setPluginsTxtAndApplyLoadOrder(str)); }); } } }} >
); }; export default Home;