bugs bashed

This commit is contained in:
2025-09-08 22:45:42 -04:00
parent 41bd1fce38
commit fb3f567a5b
10 changed files with 55 additions and 64 deletions

View File

@@ -6,11 +6,9 @@ import { Stylable } from "./toolbox";
export default (props: { playerKey: string } & Stylable) => {
const table = useContext(TableContext);
onMount(() => console.log("Player mounted"));
return (
<div
ref={(e) => table?.setPlayers(props.playerKey, "ref", e)}
ref={(e) => table?.setPlayers(props.playerKey, { ref: e })}
style={{
...props.style,
"background-color": playerColor(props.playerKey),

View File

@@ -52,36 +52,40 @@ export default (props: { tableKey: string }) => {
// #region inbound table properties
const [players, setPlayers] = createStore<PlayerStore>({});
const playerKeys = () => Object.keys(players);
wsEvents
.thru(extractProperty("playersPresent"))
.onValue((P) =>
P.filter((p) => !(p in players)).forEach((p) =>
setPlayers(p, { name: "", ready: false })
setPlayers(
Object.fromEntries(
P.map((p) => [
p,
p in players ? players[p] : { name: "", ready: false },
])
)
)
);
wsEvents
.thru(extractProperty("playerNames"))
.onValue((P) =>
Object.entries(P).map(([player, name]) =>
setPlayers(player, "name", name)
)
);
wsEvents.thru(extractProperty("playerNames")).onValue((P) =>
Object.entries(P)
.filter(([player]) => player in players)
.map(([player, name]) => setPlayers(player, "name", name))
);
wsEvents
.thru(extractProperty("playersReady"))
.onValue((P) =>
Object.entries(P).map(([player, ready]) =>
setPlayers(player, "ready", ready)
)
);
wsEvents.thru(extractProperty("playersReady")).onValue((P) =>
Object.entries(P)
.filter(([player]) => player in players)
.map(([player, ready]) => setPlayers(player, "ready", ready))
);
// #endregion
// #region inbound game properties
const [gameConfig, setGameConfig] = createSynced({
ws: wsEvents.thru(extractProperty("gameConfig")) as Property<any, any>,
ws: wsEvents.thru(extractProperty("gameConfig")) as Property<
{ game: string; players: string[] },
any
>,
sendWs: (gameConfig) => sendWs({ gameConfig }),
});
const view = wsEvents.thru(extractProperty("view")).thru(createObservable);
@@ -94,6 +98,7 @@ export default (props: { tableKey: string }) => {
ws.on("open", () => {
wsEvents.plug(fromWebsocket<TWsOut>(ws));
// TODO: these need to be in a tracking scope to be disposed
createEffect(() => sendWs({ ready: ready() }));
createEffect(() => sendWs({ name: name() }));
});
@@ -103,7 +108,7 @@ export default (props: { tableKey: string }) => {
const GamePicker = () => {
return (
<div class="absolute tc mt-8 flex gap-4">
<select>
<select value={gameConfig()?.game}>
<For each={Object.entries(games)}>
{([gameId]) => <option value={gameId}>{gameId}</option>}
</For>
@@ -133,10 +138,10 @@ export default (props: { tableKey: string }) => {
>
{/* Player avatars around the table */}
<div class="flex justify-around p-t-14">
<For each={playerKeys().filter((p) => p != me())}>
<For each={gameConfig()?.players.filter((p) => p != me())}>
{(player, i) => {
const verticalOffset = () => {
const N = playerKeys().length - 1;
const N = gameConfig()!.players.length - 1;
const x = Math.abs((2 * i() + 1) / (N * 2) - 0.5);
const y = Math.sqrt(1 - x * x);
return 1 - y;

View File

@@ -15,8 +15,6 @@ export default () => {
const table = useContext(TableContext)!;
const view = table.view as Accessor<SimplePlayerView>;
createEffect(() => console.log(table.gameConfig()));
const Configuration = () => (
<Show when={view() == null}>
<Portal mount={table.tableRef}>
@@ -52,7 +50,7 @@ export default () => {
onChange={(evt) =>
table.setGameConfig({
...table.gameConfig(),
"cards to win": evt.target.value,
"cards to win": Number.parseInt(evt.target.value),
})
}
/>

View File

@@ -2,6 +2,7 @@ import { createLatest } from "@solid-primitives/memo";
import { Observable, Property, Stream } from "kefir";
import { Accessor, createEffect, createSignal } from "solid-js";
import { createStore } from "solid-js/store";
import type { ExtractPropertyType, UnionKeys } from "@games/shared/types";
declare global {
interface Array<T> {
@@ -48,13 +49,6 @@ export const createObservableStore =
return store;
};
type UnionKeys<T> = T extends any ? keyof T : never;
type ExtractPropertyType<T, P extends string | number | symbol> = T extends {
[K in P]: any;
}
? T[P]
: never;
export const extractProperty =
<T extends object, P extends UnionKeys<T>>(property: P) =>
(obs: Observable<T, any>): Property<ExtractPropertyType<T, P>, any> =>