rebase
This commit is contained in:
@@ -3,6 +3,7 @@ import { useParams, useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
import { useToastStore } from "@/stores/toastStore";
|
||||
import { toErrorMessage } from "@/lib/api";
|
||||
import { Button } from "@/components/ui/Button";
|
||||
import { Card } from "@/components/ui/Card";
|
||||
import { Spinner } from "@/components/ui/Spinner";
|
||||
@@ -20,6 +21,7 @@ export function PlayPage() {
|
||||
const world = useSessionStore((s) => s.world);
|
||||
const environment = useSessionStore((s) => s.environment);
|
||||
const nextActions = useSessionStore((s) => s.nextActions);
|
||||
const recentSteps = useSessionStore((s) => s.recentSteps);
|
||||
const loading = useSessionStore((s) => s.loading);
|
||||
const error = useSessionStore((s) => s.error);
|
||||
const submitting = useSessionStore((s) => s.submitting);
|
||||
@@ -31,15 +33,26 @@ export function PlayPage() {
|
||||
const reset = useSessionStore((s) => s.reset);
|
||||
|
||||
const [rollbackOpen, setRollbackOpen] = useState(false);
|
||||
const [redirected, setRedirected] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) return;
|
||||
void fetchState(id).catch(() => pushToast("error", t("play.load_failed")));
|
||||
void fetchState(id).catch((err) => pushToast("error", toErrorMessage(err, t("play.load_failed"))));
|
||||
return () => {
|
||||
reset();
|
||||
};
|
||||
}, [id, fetchState, reset, pushToast, t]);
|
||||
|
||||
// Redirect non-ready worlds to the edit page (once we have the world loaded).
|
||||
useEffect(() => {
|
||||
if (!id) return;
|
||||
if (world && world.status !== "ready" && !redirected) {
|
||||
pushToast("warning", t("play.not_ready"));
|
||||
setRedirected(true);
|
||||
navigate(`/worlds/${id}/edit`, { replace: true });
|
||||
}
|
||||
}, [id, world, redirected, navigate, pushToast, t]);
|
||||
|
||||
if (!id) return null;
|
||||
|
||||
if (loading && !world) {
|
||||
@@ -60,25 +73,27 @@ export function PlayPage() {
|
||||
);
|
||||
}
|
||||
if (!world) return null;
|
||||
if (world.status !== "ready") return null;
|
||||
|
||||
const player = environment?.player;
|
||||
const plotRails: PlotRail[] = Array.isArray(world.plot_rails) ? world.plot_rails : [];
|
||||
const noSteps = recentSteps.length === 0;
|
||||
|
||||
const handleSend = (action: string) => {
|
||||
void sendAction(id, action, "manual").catch((err) => {
|
||||
pushToast("error", err instanceof Error ? err.message : "Failed");
|
||||
pushToast("error", toErrorMessage(err, "Failed"));
|
||||
});
|
||||
};
|
||||
|
||||
const handleSuggested = (action: string) => {
|
||||
void sendAction(id, action, "suggested").catch((err) => {
|
||||
pushToast("error", err instanceof Error ? err.message : "Failed");
|
||||
pushToast("error", toErrorMessage(err, "Failed"));
|
||||
});
|
||||
};
|
||||
|
||||
const handleRetry = () => {
|
||||
void retry(id).catch((err) => {
|
||||
pushToast("error", err instanceof Error ? err.message : "Failed");
|
||||
pushToast("error", toErrorMessage(err, "Failed"));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -88,7 +103,7 @@ export function PlayPage() {
|
||||
await rollback(id);
|
||||
pushToast("success", t("play.rolled_back"));
|
||||
} catch (err) {
|
||||
pushToast("error", err instanceof Error ? err.message : "Failed");
|
||||
pushToast("error", toErrorMessage(err, "Failed"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -160,14 +175,23 @@ export function PlayPage() {
|
||||
|
||||
<Card>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Button size="sm" variant="secondary" onClick={handleRetry} disabled={submitting}>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={handleRetry}
|
||||
disabled={submitting || noSteps}
|
||||
className={noSteps ? "opacity-50 cursor-not-allowed" : ""}
|
||||
title={noSteps ? t("play.no_steps_to_retry") : undefined}
|
||||
>
|
||||
{t("play.retry_last")}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => setRollbackOpen(true)}
|
||||
disabled={submitting}
|
||||
disabled={submitting || noSteps}
|
||||
className={noSteps ? "opacity-50 cursor-not-allowed" : ""}
|
||||
title={noSteps ? t("play.no_steps_to_rollback") : undefined}
|
||||
>
|
||||
{t("play.rollback")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user