85 lines
2.2 KiB
JavaScript
85 lines
2.2 KiB
JavaScript
import {settings} from '@pixi/core';
|
|
import {json, useLoaderData} from "@remix-run/react";
|
|
import {useEffect, useState} from 'react';
|
|
import {Outlet, useParams} from 'react-router-dom';
|
|
|
|
import {
|
|
computeMissing,
|
|
fetchResources,
|
|
get,
|
|
readAsset,
|
|
set,
|
|
} from '@/util/resources.js';
|
|
|
|
import styles from './play.module.css';
|
|
|
|
settings.ADAPTER.fetch = async (path) => {
|
|
const resource = await readAsset(path);
|
|
return resource ? new Response(resource) : new Response(undefined, {status: 404});
|
|
};
|
|
|
|
export async function loader({request}) {
|
|
const {juggleSession} = await import('@/server/session.server.js');
|
|
const {loadManifest} = await import('@/util/resources.server.js');
|
|
await juggleSession(request);
|
|
return json({
|
|
manifest: await loadManifest(),
|
|
});
|
|
}
|
|
|
|
export default function Play() {
|
|
const {manifest} = useLoaderData();
|
|
const [Client, setClient] = useState();
|
|
const params = useParams();
|
|
const [type] = params['*'].split('/');
|
|
useEffect(() => {
|
|
const controller = new AbortController();
|
|
const {signal} = controller;
|
|
async function receiveResources() {
|
|
const current = await get();
|
|
const paths = await computeMissing(current, manifest);
|
|
if (paths.length > 0 && !signal.aborted) {
|
|
try {
|
|
const resources = await fetchResources(paths, {signal});
|
|
if (resources) {
|
|
for (const key in resources) {
|
|
current[key] = resources[key];
|
|
}
|
|
await set(current);
|
|
}
|
|
}
|
|
catch (e) {
|
|
if ((e instanceof DOMException) && 'AbortError' === e.name) {
|
|
return;
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
receiveResources();
|
|
return () => {
|
|
controller.abort();
|
|
};
|
|
}, [manifest]);
|
|
useEffect(() => {
|
|
async function loadClient() {
|
|
let Client;
|
|
switch (type) {
|
|
case 'local':
|
|
({default: Client} = await import('@/client/local.js'));
|
|
break;
|
|
case 'remote':
|
|
({default: Client} = await import('@/client/remote.js'));
|
|
break;
|
|
}
|
|
setClient(() => Client);
|
|
}
|
|
loadClient();
|
|
}, [type]);
|
|
return (
|
|
<div className={styles.play}>
|
|
<Outlet context={Client} />
|
|
</div>
|
|
);
|
|
}
|