forked from phenom/healer-man
Release Healer Man 0.1.7
This commit is contained in:
1 parent
b12fb84859
commit
eca6b5db9b
99 files changed
+1931
-150
No files matched your search
+38
-2
@@ -1,5 +1,7 @@
|
||||
import { lazy, Suspense, useEffect } from "react";
|
||||
import { lazy, Suspense, useEffect, useMemo, useState, type ReactNode } from "react";
|
||||
import { BASE_CLASS_IDS, classById } from "./app/characterCatalog";
|
||||
import { useShellStore } from "./app/shellStore";
|
||||
import { preloadAbilityCatalogsForClasses } from "./game/abilityCatalog";
|
||||
import { useManastormAdminStore } from "./game/manastormAdminStore";
|
||||
import { useAuthoritativeDualScreenSync, useForcedThorDisplays } from "./platform/useThorDualScreen";
|
||||
import { LoginScreen } from "./ui/LoginScreen";
|
||||
@@ -18,6 +20,39 @@ function ShellTransition() {
|
||||
return <div className="world-transition"><span>HM</span><strong>Opening expedition</strong><small>Preparing the next screen...</small></div>;
|
||||
}
|
||||
|
||||
function RuntimeCatalogGate({ children }: { readonly children: ReactNode }) {
|
||||
const character = useShellStore((state) => (
|
||||
state.characters.find((candidate) => candidate.id === state.selectedCharacterId) ?? null
|
||||
));
|
||||
const classIds = useMemo(() => {
|
||||
if (!character) return [];
|
||||
const definition = classById(character.classId);
|
||||
if (definition.mode === "conquest") return [...BASE_CLASS_IDS, character.classId];
|
||||
return [character.classId, ...(character.secondaryClassId ? [character.secondaryClassId] : [])];
|
||||
}, [character]);
|
||||
const requestKey = classIds.join(":");
|
||||
const [loadedKey, setLoadedKey] = useState("");
|
||||
const [failedKey, setFailedKey] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
if (!requestKey) return;
|
||||
let active = true;
|
||||
setFailedKey("");
|
||||
void preloadAbilityCatalogsForClasses(classIds).then(() => {
|
||||
if (active) setLoadedKey(requestKey);
|
||||
}).catch(() => {
|
||||
if (active) setFailedKey(requestKey);
|
||||
});
|
||||
return () => { active = false; };
|
||||
}, [classIds, requestKey]);
|
||||
|
||||
if (!requestKey || loadedKey === requestKey) return children;
|
||||
if (failedKey === requestKey) {
|
||||
return <div className="world-transition"><span>!</span><strong>Catalog unavailable</strong><small>Reload the app to retry loading combat data.</small></div>;
|
||||
}
|
||||
return <ShellTransition />;
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
useForcedThorDisplays();
|
||||
useAuthoritativeDualScreenSync();
|
||||
@@ -39,5 +74,6 @@ export default function App() {
|
||||
else if (phase === "manastorms") screen = <Suspense fallback={<ShellTransition />}><ManastormSelectScreen /></Suspense>;
|
||||
else if (phase === "gm-admin") screen = <Suspense fallback={<ShellTransition />}><GmAdminScreen /></Suspense>;
|
||||
else if (phase === "game") screen = <Suspense fallback={<ShellTransition />}><GameRuntime /></Suspense>;
|
||||
return <><OnlineGroupCoordinator />{screen}</>;
|
||||
const requiresRuntimeCatalog = !["login", "characters", "create-character"].includes(phase);
|
||||
return <><OnlineGroupCoordinator />{requiresRuntimeCatalog ? <RuntimeCatalogGate>{screen}</RuntimeCatalogGate> : screen}</>;
|
||||
}
|
||||
Reference in new issue
Block a user