import type { TWsIn, TWsOut } from "@games/server/src/table"; import { fromPromise, Stream } from "kefir"; import { Accessor, createContext, createEffect, createSignal, For, onCleanup, Show, } from "solid-js"; import api, { fromWebsocket } from "~/api"; import { createObservable, createObservableWithInit, cx } from "~/fn"; import { me, mePromise } from "~/profile"; import Game from "./Game"; import Player from "./Player"; export const TableContext = createContext<{ view: Accessor; sendWs: (msg: TWsIn) => void; wsEvents: Stream; }>(); export default (props: { tableKey: string }) => { const wsPromise = new Promise< ReturnType["subscribe"]> >((res) => { const ws = api.ws(props).subscribe(); ws.on("open", () => res(ws)); ws.on("error", () => res(ws)); }); const sendWs = (msg: TWsIn) => wsPromise.then((ws) => ws.send(msg)); const wsEvents = fromPromise(wsPromise).flatMap((ws) => fromWebsocket(ws) ); onCleanup(() => wsPromise.then((ws) => ws.close())); const presenceEvents = wsEvents.filter((evt) => evt.players != null); const gameEvents = wsEvents.filter((evt) => evt.view !== undefined); const players = createObservableWithInit( presenceEvents.map((evt) => evt.players!), [] ); const [ready, setReady] = createSignal(false); mePromise.then( (me) => me && wsEvents .filter((evt) => evt.playersReady !== undefined) .map((evt) => evt.playersReady?.[me] ?? false) .onValue(setReady) ); createEffect(() => sendWs({ ready: ready() })); const view = createObservable(gameEvents.map((evt) => evt.view)); return (
p != me())}> {(player, i) => { const verticalOffset = () => { const N = players().length - 1; const x = Math.abs((2 * i() + 1) / (N * 2) - 0.5); const y = Math.sqrt(1 - x * x); return 1 - y; }; return ( ); }}
); };