cooking with sqlite
This commit is contained in:
2
Makefile
2
Makefile
@@ -10,4 +10,4 @@ build:
|
||||
|
||||
|
||||
start:
|
||||
sudo docker run -p $(PORT):3000 -t games
|
||||
sudo docker run -p $(PORT):3000 -p 5555:5555 -t games
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../sources/Card_back_01.svg
|
||||
@@ -1 +0,0 @@
|
||||
../sources/Vector-Cards-Version-3.2/FACES (BORDERED)/STANDARD BORDERED/Single Cards (One Per FIle)/
|
||||
@@ -3,10 +3,11 @@
|
||||
"type": "module",
|
||||
"version": "0.0.2",
|
||||
"scripts": {
|
||||
"dev": "concurrently 'vinxi dev' 'pnpm dlx prisma studio --browser none'",
|
||||
"dev": "concurrently 'vinxi dev' 'pnpm run dbstudio'",
|
||||
"build": "vinxi build",
|
||||
"start": "vinxi start",
|
||||
"sync_db": "concurrently 'pnpm dlx prisma generate' 'pnpm dlx prisma migrate dev'"
|
||||
"start": "concurrently 'vinxi start' 'pnpm run dbstudio'",
|
||||
"dbstudio": "pnpm dlx prisma studio --browser none",
|
||||
"dbsync": "concurrently 'pnpm dlx prisma generate' 'pnpm dlx prisma migrate dev'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "6.13.0",
|
||||
|
||||
1
public/views/back.svg
Symbolic link
1
public/views/back.svg
Symbolic link
@@ -0,0 +1 @@
|
||||
../../assets/sources/Card_back_01.svg
|
||||
1
public/views/cards
Symbolic link
1
public/views/cards
Symbolic link
@@ -0,0 +1 @@
|
||||
../../assets/sources/Vector-Cards-Version-3.2/FACES (BORDERED)/STANDARD BORDERED/Single Cards (One Per FIle)/
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, createResource, JSX, Suspense } from "solid-js";
|
||||
import { Card } from "../types/cards";
|
||||
import { Card, newDeck } from "../types/cards";
|
||||
import { Clickable, Stylable } from "./toolbox";
|
||||
|
||||
const cardToSvgFilename = (card: Card) => {
|
||||
@@ -17,17 +17,6 @@ const cardToSvgFilename = (card: Card) => {
|
||||
};
|
||||
|
||||
export default ((props) => {
|
||||
const [svgPath] = createResource(() =>
|
||||
props.face == "down"
|
||||
? // @ts-ignore
|
||||
import("~/../assets/views/back.svg")
|
||||
: import(
|
||||
`~/../assets/views/cards/${cardToSvgFilename(
|
||||
props.card
|
||||
)}.svg`
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<Suspense>
|
||||
<img
|
||||
@@ -39,7 +28,11 @@ export default ((props) => {
|
||||
...props.style,
|
||||
}}
|
||||
width="100px"
|
||||
src={svgPath()?.default}
|
||||
src={
|
||||
props.face == "down"
|
||||
? "/views/back.svg"
|
||||
: `/views/cards/${cardToSvgFilename(props.card)}.svg`
|
||||
}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
@@ -1,42 +1,54 @@
|
||||
import { createContext, JSX } from "solid-js";
|
||||
import {
|
||||
Accessor,
|
||||
createContext,
|
||||
createResource,
|
||||
JSX,
|
||||
Show,
|
||||
Suspense,
|
||||
} from "solid-js";
|
||||
import Card from "./Card";
|
||||
import Hand from "./Hand";
|
||||
import Pile from "./Pile";
|
||||
import { GameState, newDeck, shuffle, Hand as THand } from "../types/cards";
|
||||
import { createStore, produce, SetStoreFunction, Store } from "solid-js/store";
|
||||
import { getGameState, updateGameState } from "../db/Instances";
|
||||
|
||||
export const GameContext = createContext<{
|
||||
gameState: Store<GameState>;
|
||||
setGameState: SetStoreFunction<GameState>;
|
||||
gameState: Accessor<GameState | undefined>;
|
||||
setGameState: (state: GameState) => Promise<any>;
|
||||
}>();
|
||||
|
||||
export default (props: { initialState: GameState }) => {
|
||||
const [gameState, setGameState] = createStore<GameState>(
|
||||
props.initialState
|
||||
export default (props: { instanceId: number }) => {
|
||||
const [gameState, { refetch }] = createResource(() =>
|
||||
getGameState(props.instanceId)
|
||||
);
|
||||
const setGameState = (state: GameState) =>
|
||||
updateGameState(props.instanceId, state).then(refetch);
|
||||
|
||||
return (
|
||||
<GameContext.Provider value={{ gameState, setGameState }}>
|
||||
<div
|
||||
onClick={() => {}}
|
||||
class="full column center"
|
||||
style={{ "row-gap": "20px", "font-size": "32px" }}
|
||||
>
|
||||
<div class="full center">
|
||||
<Pile
|
||||
pile={gameState.deck}
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() =>
|
||||
setGameState(
|
||||
produce((state) => {
|
||||
state.hand.push(state.deck.pop()!);
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Show when={gameState() != undefined}>
|
||||
<div
|
||||
onClick={() => {}}
|
||||
class="full column center"
|
||||
style={{ "row-gap": "20px", "font-size": "32px" }}
|
||||
>
|
||||
<div class="full center">
|
||||
<Pile
|
||||
pile={gameState()!.deck}
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => {
|
||||
const [drawn, ...rest] = gameState()!.deck;
|
||||
setGameState({
|
||||
deck: rest,
|
||||
hand: [drawn, ...gameState()!.hand],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Hand hand={gameState()!.hand} />
|
||||
</div>
|
||||
<Hand hand={gameState.hand} />
|
||||
</div>
|
||||
</Show>
|
||||
</GameContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import { GameContext } from "./Game";
|
||||
import { produce } from "solid-js/store";
|
||||
|
||||
export default ((props) => {
|
||||
const { setGameState } = useContext(GameContext)!;
|
||||
const { setGameState, gameState } = useContext(GameContext)!;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -33,20 +33,16 @@ export default ((props) => {
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() =>
|
||||
setGameState(
|
||||
produce((state) => {
|
||||
const index = state.hand.indexOf(card);
|
||||
console.log(index);
|
||||
state.deck.push(
|
||||
state.hand.splice(
|
||||
props.hand.indexOf(card),
|
||||
1
|
||||
)[0]!
|
||||
);
|
||||
})
|
||||
)
|
||||
}
|
||||
onClick={() => {
|
||||
const index = gameState()!.hand.indexOf(card);
|
||||
setGameState({
|
||||
deck: [card, ...gameState()!.deck],
|
||||
hand: [
|
||||
...gameState()!.hand.slice(0, index),
|
||||
...gameState()!.hand.slice(index + 1),
|
||||
],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
"use server";
|
||||
|
||||
import { GameState, newDeck, shuffle } from "../types/cards";
|
||||
import { prisma } from "./db";
|
||||
|
||||
export const queryInstances = async (gameName: string) =>
|
||||
await prisma.instance.findMany({ where: { game: { name: gameName } } });
|
||||
prisma.instance.findMany({ where: { game: { name: gameName } } });
|
||||
|
||||
export const createInstance = (gameName: string) =>
|
||||
prisma.instance.create({
|
||||
data: {
|
||||
gameState: { deck: shuffle(newDeck()), hand: [] } as GameState,
|
||||
game: { connect: { name: gameName } },
|
||||
},
|
||||
});
|
||||
|
||||
export const getGameState = (instanceId: number) =>
|
||||
prisma.instance
|
||||
.findUnique({ where: { id: instanceId } })
|
||||
.then((i) => i?.gameState as GameState | undefined);
|
||||
|
||||
export const updateGameState = async (
|
||||
instanceId: number,
|
||||
gameState: GameState
|
||||
) => prisma.instance.update({ where: { id: instanceId }, data: { gameState } });
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
import { useParams } from "@solidjs/router";
|
||||
import { A, useParams } from "@solidjs/router";
|
||||
|
||||
import { createEffect, createResource, Show, Suspense } from "solid-js";
|
||||
import Game from "../../components/Game";
|
||||
import { aql } from "arangojs";
|
||||
import { getGameState } from "../../db/Instances";
|
||||
|
||||
export default () => {
|
||||
const params = useParams();
|
||||
|
||||
const [instance] = createResource(async () => {
|
||||
return null;
|
||||
});
|
||||
const params = useParams<{ game: string; instance: string }>();
|
||||
|
||||
return (
|
||||
<Show when={instance() != null}>
|
||||
<Game state={instance()!} />
|
||||
</Show>
|
||||
<>
|
||||
<Game instanceId={Number.parseInt(params.instance)} />
|
||||
<A
|
||||
href={`/${params.game}`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
padding: "10px",
|
||||
top: "0",
|
||||
left: "0",
|
||||
margin: "20px",
|
||||
"background-color": "white",
|
||||
"border-radius": "8px",
|
||||
border: "2px solid black",
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</A>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,26 +5,31 @@ import * as Instance from "../../db/Instances";
|
||||
|
||||
export default () => {
|
||||
const params = useParams<{ game: string }>();
|
||||
createEffect(() => {
|
||||
console.log(">>", params.game);
|
||||
});
|
||||
const [instances] = createResource(
|
||||
|
||||
const [instances, { refetch }] = createResource(
|
||||
() => params.game,
|
||||
() => Instance.queryInstances(params.game)
|
||||
);
|
||||
|
||||
createEffect(() => console.log(instances()));
|
||||
|
||||
return (
|
||||
<Suspense>
|
||||
<div style={{ padding: "20px" }}>
|
||||
<h1 style={{ margin: 0 }}>{params.game}</h1>
|
||||
<button
|
||||
onClick={() =>
|
||||
Instance.createInstance(params.game).then(refetch)
|
||||
}
|
||||
>
|
||||
New Game
|
||||
</button>
|
||||
<ul>
|
||||
<For each={instances() ?? []}>
|
||||
{(instance) => (
|
||||
<A href={`/${params.game}/${instance._id}`}>
|
||||
{instance._id}
|
||||
</A>
|
||||
<li>
|
||||
<A href={`/${params.game}/${instance.id}`}>
|
||||
{instance.id}
|
||||
</A>
|
||||
</li>
|
||||
)}
|
||||
</For>
|
||||
</ul>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import { createResource, For } from "solid-js";
|
||||
import * as Games from "../db/games";
|
||||
import * as Games from "../db/Games";
|
||||
|
||||
export default () => {
|
||||
const [games] = createResource(() => Games.queryAll());
|
||||
|
||||
Reference in New Issue
Block a user