Release Healer Man 0.1.43
This commit is contained in:
1 parent
c7e8163790
commit
ccc01396cd
86 files changed
+2951
-198
No files matched your search
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useShellStore } from "../app/shellStore";
|
||||
import { BOSS_TESTING_STATUSES, BOSS_TESTING_STATUS_LABELS, useBossTestingReviews, type BossTestingStatus } from "../app/bossTestingReviews";
|
||||
import { bossTestIsDefeated } from "../game/BossTestingBridge";
|
||||
import { useGameStore } from "../game/store";
|
||||
import { useMenuController, type MenuAction } from "../input/useMenuController";
|
||||
import { ControllerButton } from "./ControllerButton";
|
||||
import "./bossTesting.css";
|
||||
|
||||
export function BossTestingReviewPanel() {
|
||||
const boss = useGameStore((state) => state.bossTest);
|
||||
const session = useShellStore((state) => state.session);
|
||||
const review = useBossTestingReviews((state) => boss ? state.reviews[boss.key] : undefined);
|
||||
const save = useBossTestingReviews((state) => state.save);
|
||||
const refresh = useBossTestingReviews((state) => state.refresh);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [message, setMessage] = useState("");
|
||||
const busy = useRef(false);
|
||||
const mark = async (status: BossTestingStatus) => {
|
||||
if (!boss || busy.current) return;
|
||||
busy.current = true; setSaving(true); setMessage("");
|
||||
const synced = await save(boss, status, session);
|
||||
setMessage(synced ? `Marked ${BOSS_TESTING_STATUS_LABELS[status].toLowerCase()}.` : "Saved on this device. This label will sync when you reconnect or reopen Boss Testing.");
|
||||
busy.current = false; setSaving(false);
|
||||
};
|
||||
useEffect(() => {
|
||||
void refresh(session);
|
||||
const reconnect = () => void refresh(session);
|
||||
window.addEventListener("online", reconnect);
|
||||
return () => window.removeEventListener("online", reconnect);
|
||||
}, [refresh, session]);
|
||||
const defeated = bossTestIsDefeated();
|
||||
const back = () => { if (!busy.current) useGameStore.getState().openOverlay("pause"); };
|
||||
const retry = () => useGameStore.getState().resetAtEntrance();
|
||||
const leave = () => useShellStore.getState().returnToMainMenu();
|
||||
const actions: MenuAction[] = [
|
||||
...BOSS_TESTING_STATUSES.map((status) => ({ id: `boss-review-${status}`, run: () => void mark(status), enabled: !saving })),
|
||||
{ id: "boss-review-report", run: () => useGameStore.getState().openOverlay("report-issue"), enabled: !saving },
|
||||
{ id: "boss-review-retry", run: retry, enabled: !saving },
|
||||
{ id: "boss-review-leave", run: leave, enabled: !saving },
|
||||
{ id: "boss-review-back", run: back, enabled: !saving },
|
||||
];
|
||||
const controller = useMenuController(actions, { initialId: "boss-review-needs-testing", onBack: back });
|
||||
if (!boss) return null;
|
||||
const button = (controlId: string, label: string, run: () => void, pressed?: boolean) =>
|
||||
<ControllerButton controlId={controlId} selectedId={controller.selectedId} select={controller.select}
|
||||
type="button" className="button" onClick={run} disabled={saving} aria-pressed={pressed}>{label}</ControllerButton>;
|
||||
return <div className="modal-backdrop" role="presentation">
|
||||
<section className="pause-menu boss-testing-review" role="dialog" aria-modal="true" aria-labelledby="boss-review-title">
|
||||
<p className="eyebrow">{defeated ? "Boss defeated" : "Boss Testing paused"}</p><h2 id="boss-review-title">{boss.name}</h2>
|
||||
<p>Current readiness: <strong>{BOSS_TESTING_STATUS_LABELS[review?.status ?? "needs-testing"]}</strong></p>
|
||||
<div className="boss-testing-actions" aria-label="Boss readiness">{BOSS_TESTING_STATUSES.map((status) =>
|
||||
<span key={status}>{button(`boss-review-${status}`, `Mark ${BOSS_TESTING_STATUS_LABELS[status].toLowerCase()}`, () => void mark(status), review?.status === status)}</span>
|
||||
)}</div>
|
||||
{message && <p role="status">{message}</p>}
|
||||
<div className="pause-menu__actions">
|
||||
{button("boss-review-report", "Submit a boss report", () => useGameStore.getState().openOverlay("report-issue"))}
|
||||
{button("boss-review-retry", "Fight this boss again", retry)}
|
||||
{button("boss-review-leave", "Return to main menu", leave)}
|
||||
{button("boss-review-back", "Back to pause menu", back)}
|
||||
</div>
|
||||
</section>
|
||||
</div>;
|
||||
}
|
||||
Reference in new issue
Block a user