no db
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
"dependencies": {
|
||||
"@elysiajs/eden": "^1.3.2",
|
||||
"@solid-primitives/scheduled": "^1.5.2",
|
||||
"@solid-primitives/storage": "^4.3.3",
|
||||
"@solidjs/router": "^0.15.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"kefir": "^3.8.8",
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import { makePersisted } from "@solid-primitives/storage";
|
||||
import { Route, Router } from "@solidjs/router";
|
||||
import { createResource, lazy, Suspense } from "solid-js";
|
||||
import pkg from "^/package.json";
|
||||
import { createSignal, lazy, Suspense } from "solid-js";
|
||||
import { render } from "solid-js/web";
|
||||
import "virtual:uno.css";
|
||||
import pkg from "^/package.json";
|
||||
import "./style.css";
|
||||
import api from "./api";
|
||||
import { mePromise } from "./profile";
|
||||
import { name, setName } from "./profile";
|
||||
|
||||
const Profile = () => {
|
||||
let dialogRef!: HTMLDialogElement;
|
||||
const [profile] = createResource(() =>
|
||||
mePromise.then(() => api.profile.get())
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -24,10 +21,10 @@ const Profile = () => {
|
||||
<div class="fixed tr bg-emerald-100 m-2 p-4 rounded-xl border-2 shadow-md shadow-black">
|
||||
Name:{" "}
|
||||
<input
|
||||
value={profile()?.data?.name ?? ""}
|
||||
value={name()}
|
||||
onChange={(e) => {
|
||||
dialogRef.close();
|
||||
void api.setName.post({ name: e.target.value });
|
||||
setName(e.target.value);
|
||||
}}
|
||||
class="bg-emerald-200 border-1.5 rounded-full px-4"
|
||||
/>
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {
|
||||
SimplePlayerView,
|
||||
SimpleResult,
|
||||
} from "@games/shared/games/simple";
|
||||
import { me, profile } from "~/profile";
|
||||
import { me } from "~/profile";
|
||||
import Hand from "./Hand";
|
||||
import Pile from "./Pile";
|
||||
import { TableContext } from "./Table";
|
||||
@@ -39,7 +39,7 @@ export default () => {
|
||||
<span class="font-bold">
|
||||
{view().playerTurn == me()
|
||||
? "your"
|
||||
: profile(view().playerTurn)()?.name + "'s"}
|
||||
: table.playerNames[view().playerTurn] + "'s"}
|
||||
</span>{" "}
|
||||
turn
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSignal, useContext } from "solid-js";
|
||||
import { playerColor, profile } from "~/profile";
|
||||
import { playerColor } from "~/profile";
|
||||
import { TableContext } from "./Table";
|
||||
import { Stylable } from "./toolbox";
|
||||
import { createObservable, createObservableWithInit } from "~/fn";
|
||||
@@ -31,7 +31,7 @@ export default (props: { playerKey: string } & Stylable) => {
|
||||
class={`${props.class} w-20 h-20 rounded-full flex justify-center items-center`}
|
||||
>
|
||||
<p style={{ "font-size": "1em" }}>
|
||||
{profile(props.playerKey)()?.name}
|
||||
{table?.playerNames[props.playerKey]}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -10,16 +10,24 @@ import {
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import api, { fromWebsocket } from "~/api";
|
||||
import { createObservable, createObservableWithInit, cx } from "~/fn";
|
||||
import { me, mePromise, profile } from "~/profile";
|
||||
import {
|
||||
createObservable,
|
||||
createObservableStore,
|
||||
createObservableWithInit,
|
||||
cx,
|
||||
} from "~/fn";
|
||||
import { me, mePromise } from "~/profile";
|
||||
import Game from "./Game";
|
||||
import Player from "./Player";
|
||||
import games from "@games/shared/games/index";
|
||||
import { createStore, Store } from "solid-js/store";
|
||||
import { name } from "~/profile";
|
||||
|
||||
export const TableContext = createContext<{
|
||||
view: Accessor<any>;
|
||||
sendWs: (msg: TWsIn) => void;
|
||||
wsEvents: Stream<TWsOut, any>;
|
||||
playerNames: Store<{ [key: string]: string }>;
|
||||
}>();
|
||||
|
||||
export default (props: { tableKey: string }) => {
|
||||
@@ -37,7 +45,9 @@ export default (props: { tableKey: string }) => {
|
||||
);
|
||||
onCleanup(() => wsPromise.then((ws) => ws.close()));
|
||||
|
||||
const presenceEvents = wsEvents.filter((evt) => evt.playersPresent != null);
|
||||
const presenceEvents = wsEvents.filter(
|
||||
(evt) => evt.playersPresent !== undefined
|
||||
);
|
||||
const gameEvents = wsEvents.filter((evt) => evt.view !== undefined);
|
||||
const resultEvents = wsEvents.filter((evt) => evt.results !== undefined);
|
||||
|
||||
@@ -45,6 +55,13 @@ export default (props: { tableKey: string }) => {
|
||||
presenceEvents.map((evt) => evt.playersPresent!),
|
||||
[]
|
||||
);
|
||||
const playerNames = createObservableStore(
|
||||
wsEvents
|
||||
.filter((evt) => evt.playerNames != null)
|
||||
.map(({ playerNames }) => playerNames!)
|
||||
.toProperty(),
|
||||
{}
|
||||
);
|
||||
|
||||
const [ready, setReady] = createSignal(false);
|
||||
mePromise.then(
|
||||
@@ -57,8 +74,9 @@ export default (props: { tableKey: string }) => {
|
||||
);
|
||||
|
||||
createEffect(() => sendWs({ ready: ready() }));
|
||||
createEffect(() => sendWs({ name: name() }));
|
||||
const view = createObservable(gameEvents.map((evt) => evt.view));
|
||||
const results = createObservable(
|
||||
const results = createObservable<string>(
|
||||
merge([
|
||||
gameEvents
|
||||
.filter((evt) => "view" in evt && evt.view == null)
|
||||
@@ -73,6 +91,7 @@ export default (props: { tableKey: string }) => {
|
||||
sendWs,
|
||||
wsEvents,
|
||||
view,
|
||||
playerNames,
|
||||
}}
|
||||
>
|
||||
<div class="flex justify-around p-t-14">
|
||||
@@ -138,7 +157,7 @@ export default (props: { tableKey: string }) => {
|
||||
</Show>
|
||||
<Show when={results() != null}>
|
||||
<span class="bg-[var(--light)] text-[var(--dark)] rounded-[24px] border-2 border-[var(--dark)] absolute center p-4 shadow-lg text-[4em] text-center">
|
||||
{profile(results())()?.name} won!
|
||||
{playerNames[results()!]} won!
|
||||
</span>
|
||||
</Show>
|
||||
</TableContext.Provider>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Observable } from "kefir";
|
||||
import { Accessor, createSignal } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
@@ -37,3 +38,12 @@ export const createObservableWithInit = <T>(
|
||||
};
|
||||
|
||||
export const cx = (...classes: string[]) => classes.join(" ");
|
||||
|
||||
export const createObservableStore = <T extends object = {}>(
|
||||
obs: Observable<T, any>,
|
||||
init: T
|
||||
) => {
|
||||
const [store, setStore] = createStore<T>(init);
|
||||
obs.onValue((val) => setStore(val));
|
||||
return store;
|
||||
};
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
import { createResource, Resource } from "solid-js";
|
||||
import { createEffect, createResource, createSignal, Resource } from "solid-js";
|
||||
import { ApiType } from "./fn";
|
||||
import api from "./api";
|
||||
import hash from "object-hash";
|
||||
import { makePersisted } from "@solid-primitives/storage";
|
||||
|
||||
export const mePromise = api.whoami.post().then((r) => r.data);
|
||||
export const [me] = createResource(() => mePromise);
|
||||
|
||||
const playerProfiles: {
|
||||
[humanKey: string]: Resource<ApiType<typeof api.profile.get>>;
|
||||
} = {};
|
||||
|
||||
export const profile = (humanKey: string) => {
|
||||
if (!(humanKey in playerProfiles)) {
|
||||
playerProfiles[humanKey] = createResource(() =>
|
||||
api.profile
|
||||
.get({ query: { otherHumanKey: humanKey } })
|
||||
.then((r) => r.data)
|
||||
)[0];
|
||||
}
|
||||
|
||||
return playerProfiles[humanKey];
|
||||
};
|
||||
createEffect(() => console.log(me()));
|
||||
|
||||
export const playerColor = (humanKey: string) =>
|
||||
"#" + hash(humanKey).substring(0, 6);
|
||||
|
||||
export const [name, setName] = makePersisted(createSignal("__name__"), {
|
||||
name: "name",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user