end to end!
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@games/client",
|
||||
"type": "module",
|
||||
"version": "0.0.3",
|
||||
"version": "0.0.4",
|
||||
"scripts": {
|
||||
"dev": "vite --port 3000",
|
||||
"build": "vite build"
|
||||
@@ -11,6 +11,7 @@
|
||||
"@solid-primitives/scheduled": "^1.5.2",
|
||||
"@solidjs/router": "^0.15.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"kefir": "^3.8.8",
|
||||
"kefir-bus": "^2.3.1",
|
||||
"object-hash": "^3.0.0",
|
||||
"solid-js": "^1.9.5"
|
||||
|
||||
@@ -13,4 +13,6 @@ const { api } = treaty<Api>(
|
||||
export default api;
|
||||
|
||||
export const fromWebsocket = <T>(ws: any) =>
|
||||
fromEvents<T, never>(ws, "message");
|
||||
fromEvents(ws, "message").map(
|
||||
(evt) => (evt as unknown as { data: T }).data
|
||||
);
|
||||
|
||||
@@ -1,25 +1,36 @@
|
||||
import { Accessor, createContext } from "solid-js";
|
||||
import { Accessor, createContext, useContext } from "solid-js";
|
||||
import {
|
||||
SimpleAction,
|
||||
SimplePlayerView,
|
||||
vSimpleGameState,
|
||||
} from "../../../server/src/games/simple";
|
||||
import Pile from "./Pile";
|
||||
import { TableContext } from "./Table";
|
||||
import Hand from "./Hand";
|
||||
|
||||
export const GameContext = createContext<{
|
||||
view: Accessor<SimplePlayerView | undefined>;
|
||||
submitAction: (action: SimpleAction) => Promise<any>;
|
||||
view: Accessor<SimplePlayerView>;
|
||||
submitAction: (action: SimpleAction) => any;
|
||||
}>();
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<>
|
||||
Game started!
|
||||
{/* <Pile
|
||||
count={view()!.deckCount}
|
||||
class="cursor-pointer fixed center"
|
||||
onClick={() => submitAction({ type: "draw" })}
|
||||
/>
|
||||
const table = useContext(TableContext)!;
|
||||
const view = table.view as Accessor<SimplePlayerView>;
|
||||
const submitAction = (action: SimpleAction) => table.sendWs({ action });
|
||||
|
||||
<Hand class="fixed bc" hand={view()!.myHand} /> */}
|
||||
</>
|
||||
return (
|
||||
<GameContext.Provider value={{ view, submitAction }}>
|
||||
<Pile
|
||||
count={view().deckCount}
|
||||
class="cursor-pointer fixed center"
|
||||
onClick={() => submitAction({ type: "draw" })}
|
||||
/>
|
||||
|
||||
<Hand
|
||||
class="fixed bc"
|
||||
hand={view().myHand}
|
||||
onClickCard={(card) => submitAction({ type: "discard", card })}
|
||||
/>
|
||||
</GameContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import { Component, For, useContext } from "solid-js";
|
||||
import Card from "./Card";
|
||||
import { Hand } from "../../../shared/cards";
|
||||
import type { Hand as THand, Card as TCard } from "../../../shared/cards";
|
||||
import { GameContext } from "./Game";
|
||||
import { produce } from "solid-js/store";
|
||||
import { Stylable } from "./toolbox";
|
||||
|
||||
export default ((props) => {
|
||||
const { submitAction, view } = useContext(GameContext)!;
|
||||
|
||||
return (
|
||||
<div class={"hand " + props.class} style={props.style}>
|
||||
<For each={props.hand}>
|
||||
{(card) => (
|
||||
{(card, i) => (
|
||||
<Card
|
||||
card={card}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => submitAction({ type: "discard", card })}
|
||||
onClick={() => props.onClickCard?.(card, i())}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
);
|
||||
}) satisfies Component<{ hand: Hand } & Stylable>;
|
||||
}) satisfies Component<
|
||||
{ hand: THand; onClickCard?: (card: TCard, i: number) => any } & Stylable
|
||||
>;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { playerColor, profile } from "../profile";
|
||||
import { Stylable } from "./toolbox";
|
||||
|
||||
export default (props: { playerKey: string } & Stylable) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
...props.style,
|
||||
"background-color": playerColor(props.playerKey),
|
||||
}}
|
||||
class={`${props.class} w-20 h-20 rounded-full flex justify-center items-center`}
|
||||
>
|
||||
<p style={{ "font-size": "1em" }}>
|
||||
{profile(props.playerKey)()?.name}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
Accessor,
|
||||
createContext,
|
||||
createEffect,
|
||||
createSignal,
|
||||
For,
|
||||
onCleanup,
|
||||
@@ -14,6 +15,8 @@ import Bus from "kefir-bus";
|
||||
import { createObservable, createObservableWithInit, WSEvent } from "../fn";
|
||||
import { EdenWS } from "@elysiajs/eden/treaty";
|
||||
import { TWsIn, TWsOut } from "../../../server/src/table";
|
||||
import Player from "./Player";
|
||||
import Game from "./Game";
|
||||
|
||||
export const TableContext = createContext<{
|
||||
players: Accessor<string[]>;
|
||||
@@ -27,18 +30,20 @@ export default (props: { tableKey: string }) => {
|
||||
onCleanup(() => ws.close());
|
||||
|
||||
const presenceEvents = wsEvents.filter((evt) => evt.players != null);
|
||||
|
||||
const gameEvents = wsEvents.filter((evt) => evt.view != null);
|
||||
|
||||
const players = createObservableWithInit<string[]>(
|
||||
presenceEvents.map((evt) => evt.players!),
|
||||
[]
|
||||
);
|
||||
|
||||
const view = createObservable(gameEvents.map((evt) => evt.view));
|
||||
|
||||
return (
|
||||
<TableContext.Provider
|
||||
value={{
|
||||
sendWs: ws.send,
|
||||
sendWs: (evt) => ws.send(evt),
|
||||
view,
|
||||
players,
|
||||
}}
|
||||
@@ -53,19 +58,14 @@ export default (props: { tableKey: string }) => {
|
||||
return 1 - y;
|
||||
};
|
||||
return (
|
||||
<div
|
||||
<Player
|
||||
playerKey={player}
|
||||
style={{
|
||||
transform: `translate(0, ${
|
||||
verticalOffset() * 150
|
||||
}vh)`,
|
||||
"background-color": playerColor(player),
|
||||
}}
|
||||
class="w-20 h-20 rounded-full flex justify-center items-center"
|
||||
>
|
||||
<p style={{ "font-size": "1em" }}>
|
||||
{profile(player)()?.name}
|
||||
</p>
|
||||
</div>
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
@@ -89,7 +89,7 @@ export default (props: { tableKey: string }) => {
|
||||
</Show>
|
||||
</div>
|
||||
<Show when={view() != null}>
|
||||
<div>Game started!</div>
|
||||
<Game />
|
||||
</Show>
|
||||
</TableContext.Provider>
|
||||
);
|
||||
|
||||
1
packages/client/src/global.d.ts
vendored
Normal file
1
packages/client/src/global.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="@solidjs/start/env" />
|
||||
Reference in New Issue
Block a user