cooking with kefir

This commit is contained in:
2025-08-20 21:56:23 -04:00
parent 265aad4522
commit 35a5af154f
9 changed files with 245 additions and 188 deletions

View File

@@ -52,12 +52,8 @@ const App = () => {
>
<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]"))}
path="/:tableKey"
component={lazy(() => import("./routes/[table]"))}
/>
</Router>
);

View File

@@ -9,6 +9,7 @@ import {
Resource,
ResourceReturn,
Show,
untrack,
} from "solid-js";
import {
GameState,
@@ -28,35 +29,38 @@ export const GameContext = createContext<{
}>();
const [playerProfiles, setPlayerProfiles] = createStore<
Record<
string,
ReturnType<typeof createResource<ApiType<typeof api.profile.get>>>[0]
>
Record<string, Resource<ApiType<typeof api.profile.get>>>
>({});
export default (props: { instanceId: string }) => {
export default (props: { tableKey: string }) => {
const [view, setView] = createSignal<PlayerView>();
const [players, setPlayers] = createSignal<string[]>([]);
createEffect(() => {
players().forEach((player) => {
if (!playerProfiles[player]) {
if (!untrack(() => playerProfiles[player])) {
const [playerProfile] = createResource(() =>
api.profile
.get({ query: { otherHumanKey: player } })
.then((r) => r.data)
);
setPlayerProfiles(player, playerProfile);
setPlayerProfiles((prev) => ({
...prev,
[player]: playerProfile,
}));
}
});
});
const ws = api.simple(props).subscribe();
const ws = api(props).subscribe;
onCleanup(() => ws.close());
ws.on("message", (evt) => {
if (evt.data.players) {
setPlayers(evt.data.players);
}
if (evt.data.view) {
setView(evt.data.view);
}
});
const submitAction = (action: Action) => api.simple(props).post({ action });
@@ -66,7 +70,11 @@ export default (props: { instanceId: string }) => {
<div class="fixed tc mt-20 flex flex-col items-center">
<button class="button p-1 m-10">Start Game!</button>
<For each={players()}>
{(player) => <p>{playerProfiles[player]?.()?.name}</p>}
{(player) => (
<p style={{ "font-size": "2em" }}>
{playerProfiles[player]?.()?.name}
</p>
)}
</For>
</div>
);

View File

@@ -0,0 +1,90 @@
import {
Accessor,
createContext,
createEffect,
createResource,
createSignal,
For,
onCleanup,
Resource,
ResourceReturn,
Show,
untrack,
} from "solid-js";
import {
GameState,
Action,
vGameState,
PlayerView,
} from "../../../server/src/games/simple";
import api from "../api";
import Hand from "./Hand";
import Pile from "./Pile";
import { ApiType } from "../fn";
import { createStore } from "solid-js/store";
import Game from "./Game";
const [playerProfiles, setPlayerProfiles] = createStore<
Record<string, Resource<ApiType<typeof api.profile.get>>>
>({});
export const TableContext = createContext<{
players: Accessor<string[]>;
view: Accessor<PlayerView | undefined>;
// submitAction: (action: Action) => Promise<any>;
}>();
export default (props: { tableKey: string }) => {
const [players, setPlayers] = createSignal<string[]>([]);
const [view, setView] = createSignal<PlayerView>();
const ws = api(props).subscribe();
onCleanup(() => ws.close());
ws.on("message", (evt) => {
if (evt.data.players) {
setPlayers(evt.data.players);
}
if (evt.data.view) {
setView(evt.data.view);
}
});
createEffect(() => {
players().forEach((player) => {
if (!untrack(() => playerProfiles[player])) {
const [playerProfile] = createResource(() =>
api.profile
.get({ query: { otherHumanKey: player } })
.then((r) => r.data)
);
setPlayerProfiles((prev) => ({
...prev,
[player]: playerProfile,
}));
}
});
});
const Lobby = () => {
return (
<div class="fixed tc mt-20 flex flex-col items-center">
<button class="button p-1 m-10">Start Game!</button>
<For each={players()}>
{(player) => (
<p style={{ "font-size": "2em" }}>
{playerProfiles[player]?.()?.name}
</p>
)}
</For>
</div>
);
};
return (
<TableContext.Provider value={{ view, players }}>
<Show when={view() != null} fallback={<Lobby />}>
<Game tableKey={props.tableKey} />
</Show>
</TableContext.Provider>
);
};

View File

@@ -0,0 +1,16 @@
import { A, useParams } from "@solidjs/router";
import Table from "../components/Table";
export default () => {
const { tableKey } = useParams();
return (
<>
<Table tableKey={tableKey} />
<A href={"/"} class="fixed tl m-4 px-2 py-1.5 button">
Back
</A>
</>
);
};