cooking with websockets

This commit is contained in:
2025-08-18 23:31:28 -04:00
parent 3f1635880a
commit 287c19fc0d
12 changed files with 205 additions and 81 deletions

View File

@@ -34,30 +34,33 @@ const Profile = () => {
);
};
const App = () => (
<Router
root={(props) => (
<>
<Suspense>{props.children}</Suspense>
<Profile />
const App = () => {
api.whoami.post();
return (
<Router
root={(props) => (
<>
<Suspense>{props.children}</Suspense>
<Profile />
{/* Version */}
<span class="fixed br m-2 font-mono text-xs">
{"v" + pkg.version}
</span>
</>
)}
>
<Route path="/" component={lazy(() => import("./routes/index"))} />
<Route
path="/:game"
component={lazy(() => import("./routes/[game]/index"))}
/>
<Route
path="/:game/:instance"
component={lazy(() => import("./routes/[game]/[instance]"))}
/>
</Router>
);
{/* Version */}
<span class="fixed br m-2 font-mono text-xs">
{"v" + pkg.version}
</span>
</>
)}
>
<Route path="/" component={lazy(() => import("./routes/index"))} />
<Route
path="/:game"
component={lazy(() => import("./routes/[game]/index"))}
/>
<Route
path="/:game/:instance"
component={lazy(() => import("./routes/[game]/[instance]"))}
/>
</Router>
);
};
api.whoami.post().then(() => render(App, document.getElementById("app")!));
render(App, document.getElementById("app")!);

View File

@@ -1,4 +1,12 @@
import { Accessor, createContext, createResource, Show } from "solid-js";
import {
Accessor,
createContext,
createResource,
createSignal,
For,
onCleanup,
Show,
} from "solid-js";
import {
GameState,
Action,
@@ -15,28 +23,36 @@ export const GameContext = createContext<{
}>();
export default (props: { instanceId: string }) => {
const [view, { mutate }] = createResource(() =>
api
.simple(props)
.get()
.then((res) => res.data as PlayerView)
);
const submitAction = (action: Action) =>
api
.simple(props)
.post({ action })
.then((res) => res.status == 200 && mutate(res.data as PlayerView));
const [view, setView] = createSignal<PlayerView>();
const [players, setPlayers] = createSignal<string[]>([]);
const ws = api.simple(props).subscribe();
onCleanup(() => ws.close());
ws.on("message", (evt) => {
if (evt.data.players) {
setPlayers(evt.data.players);
}
});
const submitAction = (action: Action) => api.simple(props).post({ action });
const Lobby = () => {
return (
<div class="fixed center">
<For each={players()}>{(player) => <p>{player}</p>}</For>
</div>
);
};
return (
<GameContext.Provider value={{ view, submitAction }}>
<Show when={view.latest != undefined}>
<Show when={view() != undefined} fallback={<Lobby />}>
<Pile
count={view.latest!.deckCount}
count={view()!.deckCount}
class="cursor-pointer fixed center"
onClick={() => submitAction({ type: "draw" })}
/>
<Hand class="fixed bc" hand={view.latest!.myHand} />
<Hand class="fixed bc" hand={view()!.myHand} />
</Show>
</GameContext.Provider>
);

View File

@@ -16,7 +16,7 @@ export default () => {
<div style={{ padding: "20px" }}>
<p class="text-[40px]">{param.game}</p>
<button
class="px-2 py-1.5 m-4 button rounded"
class="px-2 py-1.5 m-4 button"
onClick={() => api.simple.newGame.post().then(refetch)}
>
New Game

View File

@@ -29,7 +29,6 @@ a:visited {
background-color: white;
color: black;
box-shadow: 0px 5px 10px black;
border-radius: 10%;
transition: background-color 0.15s, color 0.15s, transform 0.15s;
}
.button:hover {