diff --git a/leaky-ships/package.json b/leaky-ships/package.json
index 6d0da24..ffbf40e 100644
--- a/leaky-ships/package.json
+++ b/leaky-ships/package.json
@@ -6,7 +6,8 @@
"build": "solid-start build",
"lint": "eslint --fix \"**/*.{ts,tsx,js,jsx}\"",
"push": "drizzle-kit push:pg",
- "test": "pnpm playwright test --ui"
+ "test": "pnpm playwright test --ui",
+ "typecheck": "tsc --noEmit --checkJs false --skipLibCheck"
},
"type": "module",
"dependencies": {
@@ -30,6 +31,7 @@
"drizzle-zod": "^0.5.0",
"http-status": "^1.6.2",
"nodemailer": "6.9.4",
+ "object-hash": "^3.0.0",
"postgres": "^3.3.5",
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
@@ -44,6 +46,7 @@
"@total-typescript/ts-reset": "^0.4.2",
"@types/node": "^20.5.0",
"@types/nodemailer": "^6.4.9",
+ "@types/object-hash": "^3.0.3",
"@types/web-bluetooth": "^0.0.17",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"autoprefixer": "^10.4.15",
diff --git a/leaky-ships/pnpm-lock.yaml b/leaky-ships/pnpm-lock.yaml
index e09250d..8097912 100644
--- a/leaky-ships/pnpm-lock.yaml
+++ b/leaky-ships/pnpm-lock.yaml
@@ -65,6 +65,9 @@ dependencies:
nodemailer:
specifier: 6.9.4
version: 6.9.4
+ object-hash:
+ specifier: ^3.0.0
+ version: 3.0.0
postgres:
specifier: ^3.3.5
version: 3.3.5
@@ -103,6 +106,9 @@ devDependencies:
'@types/nodemailer':
specifier: ^6.4.9
version: 6.4.9
+ '@types/object-hash':
+ specifier: ^3.0.3
+ version: 3.0.3
'@types/web-bluetooth':
specifier: ^0.0.17
version: 0.0.17
@@ -2075,6 +2081,10 @@ packages:
'@types/node': 18.17.5
dev: true
+ /@types/object-hash@3.0.3:
+ resolution: {integrity: sha512-Mb0SDIhjhBAz4/rDNU0cYcQR4lSJIwy+kFlm0whXLkx+o0pXwEszwyrWD6gXWumxVbAS6XZ9gXK82LR+Uk+cKQ==}
+ dev: true
+
/@types/resolve@1.20.2:
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
@@ -4257,7 +4267,6 @@ packages:
/object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
- dev: true
/object-inspect@1.12.3:
resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
diff --git a/leaky-ships/src/components/Gamefield/BorderTiles.tsx b/leaky-ships/src/components/Gamefield/BorderTiles.tsx
index e02348f..5a29274 100644
--- a/leaky-ships/src/components/Gamefield/BorderTiles.tsx
+++ b/leaky-ships/src/components/Gamefield/BorderTiles.tsx
@@ -1,7 +1,16 @@
import { For } from "solid-js"
-import { useGameProps } from "~/hooks/useGameProps"
-import useIndex from "~/hooks/useIndex"
-import useShips from "~/hooks/useShips"
+import {
+ gameState,
+ mode,
+ mouseCursor,
+ removeShip,
+ setMode,
+ setMouseCursor,
+ setShips,
+ setTarget,
+ targetPreview,
+} from "~/hooks/useGameProps"
+import { useSession } from "~/hooks/useSession"
import {
borderCN,
cornerCN,
@@ -23,40 +32,36 @@ type TilesType = {
}
function BorderTiles() {
- const { activeUser } = useIndex()
- const {
- payload,
- mode,
- targetPreview,
- mouseCursor,
- setTarget,
- setMouseCursor,
- } = useGameProps()
- const { ships, setShips, removeShip } = useShips()
+ const { selfIndex, activeUser, ships } = useSession()
const settingTarget = (isGameTile: boolean, x: number, y: number) => {
- if (payload?.game?.state === "running") {
- const list = targetList(targetPreview, mode)
+ if (gameState() === "running") {
+ const list = targetList(targetPreview(), mode())
if (
!isGameTile ||
- !list.filter(({ x, y }) => !isAlreadyHit(x, y, activeUser?.hits ?? []))
- .length
+ !list.filter(
+ ({ x, y }) => !isAlreadyHit(x, y, activeUser()?.hits() ?? []),
+ ).length
)
return
- if (!overlapsWithAnyBorder(targetPreview, mode))
+ if (!overlapsWithAnyBorder(targetPreview(), mode()))
setTarget({
show: true,
x,
y,
- orientation: targetPreview.orientation,
+ orientation: targetPreview().orientation,
})
} else if (
- payload?.game?.state === "starting" &&
- targetPreview.show &&
- !intersectingShip(ships(), shipProps(ships(), mode, targetPreview)).score
+ gameState() === "starting" &&
+ targetPreview().show &&
+ !intersectingShip(ships(), shipProps(ships(), mode(), targetPreview()))
+ .score
) {
setMouseCursor((e) => ({ ...e, shouldShow: false }))
- setShips([...ships(), shipProps(ships(), mode, targetPreview)])
+ setShips(
+ [...ships(), shipProps(ships(), mode(), targetPreview())],
+ selfIndex(),
+ )
}
}
@@ -89,11 +94,11 @@ function BorderTiles() {
class={props.className}
style={{ "--x": props.x, "--y": props.y }}
onClick={() => {
- if (payload?.game?.state === "running") {
+ if (gameState() === "running") {
settingTarget(props.isGameTile, props.x, props.y)
- } else if (payload?.game?.state === "starting") {
+ } else if (gameState() === "starting") {
const { index } = intersectingShip(ships(), {
- ...mouseCursor,
+ ...mouseCursor(),
size: 1,
variant: 0,
orientation: "h",
@@ -102,8 +107,8 @@ function BorderTiles() {
settingTarget(props.isGameTile, props.x, props.y)
else {
const ship = ships()[index]
- useGameProps.setState({ mode: ship.size - 2 })
- removeShip(ship)
+ setMode(ship.size - 2)
+ removeShip(ship, selfIndex())
setMouseCursor((e) => ({ ...e, shouldShow: true }))
}
}
@@ -114,13 +119,13 @@ function BorderTiles() {
y: props.y,
shouldShow:
props.isGameTile &&
- (payload?.game?.state === "starting"
+ (gameState() === "starting"
? intersectingShip(
ships(),
- shipProps(ships(), mode, {
+ shipProps(ships(), mode(), {
x: props.x,
y: props.y,
- orientation: targetPreview.orientation,
+ orientation: targetPreview().orientation,
}),
true,
).score < 2
diff --git a/leaky-ships/src/components/Gamefield/EventBar.tsx b/leaky-ships/src/components/Gamefield/EventBar.tsx
index e7faf0c..5717944 100644
--- a/leaky-ships/src/components/Gamefield/EventBar.tsx
+++ b/leaky-ships/src/components/Gamefield/EventBar.tsx
@@ -23,52 +23,36 @@ import {
} from "@fortawesome/pro-solid-svg-icons"
import { socket } from "~/lib/socket"
import { modes } from "~/lib/utils/helpers"
-import { GamePropsSchema } from "~/lib/zodSchemas"
// import { Icons, toast } from "react-toastify"
import { For, Show, createEffect } from "solid-js"
import { useNavigate } from "solid-start"
import { useDrawProps } from "~/hooks/useDrawProps"
-import { useGameProps } from "~/hooks/useGameProps"
-import useIndex from "~/hooks/useIndex"
-import useShips from "~/hooks/useShips"
-import { EventBarModes, GameSettings } from "../../interfaces/frontend"
+import {
+ allowChat,
+ allowMarkDraw,
+ allowSpecials,
+ allowSpectators,
+ gameState,
+ menu,
+ mode,
+ reset,
+ setGameSetting,
+ setIsReadyFor,
+ setMenu,
+ setMode,
+ setTarget,
+ setTargetPreview,
+ target,
+ users,
+} from "~/hooks/useGameProps"
+import { useSession } from "~/hooks/useSession"
+import { EventBarModes } from "../../interfaces/frontend"
import Item from "./Item"
-export function setGameSetting(
- payload: GameSettings,
- setSetting: (settings: GameSettings) => string | null,
- full: (payload: GamePropsSchema) => void,
-) {
- return () => {
- const hash = setSetting(payload)
- socket.emit("gameSetting", payload, (newHash) => {
- if (newHash === hash) return
- console.log("hash", hash, newHash)
- socket.emit("update", full)
- })
- }
-}
-
function EventBar(props: { clear: () => void }) {
const { shouldHide, color } = useDrawProps()
- const { selfIndex, isActiveIndex, selfUser } = useIndex()
- const { ships } = useShips()
- const navigate = useNavigate()
- const {
- payload,
- userStates,
- menu,
- mode,
- setSetting,
- full,
- target,
- setTarget,
- setTargetPreview,
- setIsReady,
- reset,
- } = useGameProps()
- const gameSetting = (payload: GameSettings) =>
- setGameSetting(payload, setSetting, full)
+ const { selfIndex, isActiveIndex, selfUser, ships } = useSession()
+ const navigator = useNavigate()
const items = (): EventBarModes => ({
main: [
@@ -76,36 +60,36 @@ function EventBar(props: { clear: () => void }) {
icon: "burger-menu",
text: "Menu",
callback: () => {
- useGameProps.setState({ menu: "menu" })
+ setMenu("menu")
},
},
- payload?.game?.state === "running"
+ gameState() === "running"
? {
icon: faSwords,
text: "Attack",
callback: () => {
- useGameProps.setState({ menu: "moves" })
+ setMenu("moves")
},
}
: {
icon: faShip,
text: "Ships",
callback: () => {
- useGameProps.setState({ menu: "moves" })
+ setMenu("moves")
},
},
{
icon: "pen",
text: "Draw",
callback: () => {
- useGameProps.setState({ menu: "draw" })
+ setMenu("draw")
},
},
{
icon: "gear",
text: "Settings",
callback: () => {
- useGameProps.setState({ menu: "settings" })
+ setMenu("settings")
},
},
],
@@ -115,47 +99,49 @@ function EventBar(props: { clear: () => void }) {
text: "Surrender",
iconColor: "darkred",
callback: () => {
- useGameProps.setState({ menu: "surrender" })
+ setMenu("surrender")
},
},
],
moves:
- payload?.game?.state === "running"
+ gameState() === "running"
? [
{
icon: "scope",
text: "Fire missile",
- enabled: mode === 0,
+ enabled: mode() === 0,
callback: () => {
- useGameProps.setState({ mode: 0 })
- setTarget((e) => ({ ...e, show: false }))
+ setMode(0)
+ setTarget((t) => ({ ...t, show: false }))
},
},
{
icon: "torpedo",
text: "Fire torpedo",
- enabled: mode === 1 || mode === 2,
+ enabled: mode() === 1 || mode() === 2,
amount:
2 -
- ((selfUser?.moves ?? []).filter(
- (e) => e.type === "htorpedo" || e.type === "vtorpedo",
- ).length ?? 0),
+ (selfUser()
+ ?.moves()
+ .filter((e) => e.type === "htorpedo" || e.type === "vtorpedo")
+ .length ?? 0),
callback: () => {
- useGameProps.setState({ mode: 1 })
- setTarget((e) => ({ ...e, show: false }))
+ setMode(1)
+ setTarget((t) => ({ ...t, show: false }))
},
},
{
icon: "radar",
text: "Radar scan",
- enabled: mode === 3,
+ enabled: mode() === 3,
amount:
1 -
- ((selfUser?.moves ?? []).filter((e) => e.type === "radar")
- .length ?? 0),
+ (selfUser()
+ ?.moves()
+ .filter((e) => e.type === "radar").length ?? 0),
callback: () => {
- useGameProps.setState({ mode: 3 })
- setTarget((e) => ({ ...e, show: false }))
+ setMode(3)
+ setTarget((t) => ({ ...t, show: false }))
},
},
]
@@ -166,7 +152,7 @@ function EventBar(props: { clear: () => void }) {
amount: 1 - ships().filter((e) => e.size === 2).length,
callback: () => {
if (1 - ships().filter((e) => e.size === 2).length === 0) return
- useGameProps.setState({ mode: 0 })
+ setMode(0)
},
},
{
@@ -175,7 +161,7 @@ function EventBar(props: { clear: () => void }) {
amount: 3 - ships().filter((e) => e.size === 3).length,
callback: () => {
if (3 - ships().filter((e) => e.size === 3).length === 0) return
- useGameProps.setState({ mode: 1 })
+ setMode(1)
},
},
{
@@ -184,7 +170,7 @@ function EventBar(props: { clear: () => void }) {
amount: 2 - ships().filter((e) => e.size === 4).length,
callback: () => {
if (2 - ships().filter((e) => e.size === 4).length === 0) return
- useGameProps.setState({ mode: 2 })
+ setMode(2)
},
},
{
@@ -213,31 +199,31 @@ function EventBar(props: { clear: () => void }) {
{
icon: faGlasses,
text: "Spectators",
- disabled: !payload?.game?.allowSpectators,
- callback: gameSetting({
- allowSpectators: !payload?.game?.allowSpectators,
+ disabled: !allowSpectators(),
+ callback: setGameSetting({
+ allowSpectators: !allowSpectators(),
}),
},
{
icon: faSparkles,
text: "Specials",
- disabled: !payload?.game?.allowSpecials,
- callback: gameSetting({
- allowSpecials: !payload?.game?.allowSpecials,
+ disabled: !allowSpecials(),
+ callback: setGameSetting({
+ allowSpecials: !allowSpecials(),
}),
},
{
icon: faComments,
text: "Chat",
- disabled: !payload?.game?.allowChat,
- callback: gameSetting({ allowChat: !payload?.game?.allowChat }),
+ disabled: !allowChat(),
+ callback: setGameSetting({ allowChat: !allowChat() }),
},
{
icon: faScribble,
text: "Mark/Draw",
- disabled: !payload?.game?.allowMarkDraw,
- callback: gameSetting({
- allowMarkDraw: !payload?.game?.allowMarkDraw,
+ disabled: !allowMarkDraw(),
+ callback: setGameSetting({
+ allowMarkDraw: !allowMarkDraw(),
}),
},
],
@@ -248,7 +234,7 @@ function EventBar(props: { clear: () => void }) {
iconColor: "green",
callback: async () => {
socket.emit("gameState", "aborted")
- await navigate("/")
+ await navigator("/")
reset()
},
},
@@ -257,7 +243,7 @@ function EventBar(props: { clear: () => void }) {
text: "No",
iconColor: "red",
callback: () => {
- useGameProps.setState({ menu: "main" })
+ setMenu("main")
},
},
],
@@ -265,22 +251,22 @@ function EventBar(props: { clear: () => void }) {
createEffect(() => {
if (
- menu !== "moves" ||
- payload?.game?.state !== "starting" ||
- mode < 0 ||
- items().moves[mode].amount
+ menu() !== "moves" ||
+ gameState() !== "starting" ||
+ mode() < 0 ||
+ items().moves[mode()].amount
)
return
const index = items().moves.findIndex((e) => e.amount)
- useGameProps.setState({ mode: index })
+ setMode(index)
})
createEffect(() => {
- useDrawProps.setState({ enable: menu === "draw" })
+ useDrawProps.setState({ enable: menu() === "draw" })
})
// createEffect(() => {
- // if (payload?.game?.state !== "running") return
+ // if (gameState() !== "running") return
// const toastId = "otherPlayer"
// if (isActiveIndex) toast.dismiss(toastId)
@@ -307,59 +293,51 @@ function EventBar(props: { clear: () => void }) {
return (
-
+
- {
- useGameProps.setState({ menu: "main" })
+ setMenu("main")
},
}}
/>
-
+
{(e, i) => (
-
+
)}
-
+
- = 0 && userStates[selfIndex].isReady()
- ? faLock
- : faCheck,
- text:
- selfIndex >= 0 && userStates[selfIndex].isReady()
- ? "unready"
- : "Done",
- disabled:
- payload?.game?.state === "starting" ? mode >= 0 : undefined,
- enabled:
- payload?.game?.state === "running" && mode >= 0 && target.show,
+ icon: selfUser()?.isReady() ? faLock : faCheck,
+ text: selfUser()?.isReady() ? "unready" : "Done",
+ disabled: gameState() === "starting" ? mode() >= 0 : undefined,
+ enabled: gameState() === "running" && mode() >= 0 && target().show,
callback: () => {
- if (selfIndex < 0) return
- switch (payload?.game?.state) {
+ const i = selfIndex()
+ if (i === -1) return
+ switch (gameState()) {
case "starting":
- const isReady = !userStates[selfIndex].isReady
- setIsReady({ isReady, i: selfIndex })
+ const isReady = !users[i].isReady()
+ setIsReadyFor({ isReady, i })
socket.emit("isReady", isReady)
break
case "running":
- const i = (selfUser?.moves ?? [])
- .map((e) => e.index)
- .reduce((prev, curr) => (curr > prev ? curr : prev), 0)
+ const moves = selfUser()?.moves()
+ const length = moves?.length
const props = {
- type: modes[mode].type,
- x: target.x,
- y: target.y,
- orientation: target.orientation,
- index: (selfUser?.moves ?? []).length ? i + 1 : 0,
+ type: modes[mode()].type,
+ x: target().x,
+ y: target().y,
+ orientation: target().orientation,
+ index: length ?? 0,
}
socket.emit("dispatchMove", props)
setTarget((t) => ({ ...t, show: false }))
diff --git a/leaky-ships/src/components/Gamefield/Gamefield.tsx b/leaky-ships/src/components/Gamefield/Gamefield.tsx
index a448886..ab29c0f 100644
--- a/leaky-ships/src/components/Gamefield/Gamefield.tsx
+++ b/leaky-ships/src/components/Gamefield/Gamefield.tsx
@@ -9,8 +9,20 @@ import HitElems from "~/components/Gamefield/HitElems"
import Targets from "~/components/Gamefield/Targets"
import { useDraw } from "~/hooks/useDraw"
import { useDrawProps } from "~/hooks/useDrawProps"
-import { useGameProps } from "~/hooks/useGameProps"
-import useIndex from "~/hooks/useIndex"
+import {
+ full,
+ gameId,
+ gameState,
+ mode,
+ mouseCursor,
+ reset,
+ setMode,
+ setMouseCursor,
+ setTargetPreview,
+ target,
+ users,
+} from "~/hooks/useGameProps"
+import { useSession } from "~/hooks/useSession"
import useSocket from "~/hooks/useSocket"
import { socket } from "~/lib/socket"
import { overlapsWithAnyBorder } from "~/lib/utils/helpers"
@@ -20,47 +32,35 @@ import Ships from "./Ships"
export const count = 12
function Gamefield() {
- const { selfUser } = useIndex()
- const navigate = useNavigate()
- const {
- userStates,
- mode,
- target,
- mouseCursor,
- setMouseCursor,
- payload,
- setTargetPreview,
- full,
- reset,
- } = useGameProps()
+ const { ships } = useSession()
+ const navigator = useNavigate()
const { isConnected } = useSocket()
-
const usingDraw = useDraw()
const { enable, color, shouldHide } = useDrawProps()
createEffect(() => {
if (
- payload?.game?.state !== "starting" ||
- userStates.reduce((prev, curr) => prev || !curr.isReady, false)
+ gameState() !== "starting" ||
+ !users[0].isReady() ||
+ !users[1].isReady()
)
return
- socket.emit("ships", selfUser?.ships ?? [])
+ socket.emit("ships", ships() ?? [])
socket.emit("gameState", "running")
})
createEffect(() => {
- if (payload?.game?.id || !isConnected) return
+ if (gameId() || !isConnected()) return
socket.emit("update", full)
})
createEffect(() => {
- if (mode < 0) return
- const { x, y, show } = target
- const { shouldShow, ...position } = mouseCursor
+ if (mode() < 0) return
+ const { x, y, show } = target()
+ const { shouldShow, ...position } = mouseCursor()
if (
!shouldShow ||
- (payload?.game?.state === "running" &&
- overlapsWithAnyBorder(position, mode))
+ (gameState() === "running" && overlapsWithAnyBorder(position, mode()))
)
setTargetPreview((t) => ({ ...t, show: false }))
else {
@@ -71,14 +71,14 @@ function Gamefield() {
}))
const handleKeyPress = (event: KeyboardEvent) => {
if (event.key !== "r") return
- if (payload?.game?.state === "starting") {
+ if (gameState() === "starting") {
setTargetPreview((t) => ({
...t,
orientation: t.orientation === "h" ? "v" : "h",
}))
}
- if (payload?.game?.state === "running" && (mode === 1 || mode === 2))
- useGameProps.setState({ mode: mode === 1 ? 2 : 1 })
+ if (gameState() === "running" && (mode() === 1 || mode() === 2))
+ setMode(mode() === 1 ? 2 : 1)
}
document.addEventListener("keydown", handleKeyPress)
return () => {
@@ -88,15 +88,15 @@ function Gamefield() {
})
createEffect(() => {
- if (payload?.game?.state !== "aborted") return
+ if (gameState() !== "aborted") return
// toast.info("Enemy gave up!")
- navigate("/")
+ navigator("/")
reset()
})
createEffect(() => {
- if (payload?.game?.id) return
- const timeout = setTimeout(() => navigate("/"), 5000)
+ if (gameId()) return
+ const timeout = setTimeout(() => navigator("/"), 5000)
return () => clearTimeout(timeout)
})
diff --git a/leaky-ships/src/components/Gamefield/HitElems.tsx b/leaky-ships/src/components/Gamefield/HitElems.tsx
index e7f5a30..eca91ce 100644
--- a/leaky-ships/src/components/Gamefield/HitElems.tsx
+++ b/leaky-ships/src/components/Gamefield/HitElems.tsx
@@ -1,16 +1,16 @@
import { faBurst, faXmark } from "@fortawesome/pro-solid-svg-icons"
import { For } from "solid-js"
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
-import useIndex from "~/hooks/useIndex"
+import { useSession } from "~/hooks/useSession"
import { Hit } from "../../interfaces/frontend"
function HitElems(props: { hits?: Hit[]; colorOverride?: string }) {
- const { activeUser } = useIndex()
+ const { activeUser } = useSession()
const hits = () => props?.hits
const colorOverride = () => props?.colorOverride
return (
-
+
{(props) => (
- {isColor() ? (
+
{/* */}
- ) : null}
+
-
{(props) => }
+
+ {(props) => }
)
}
diff --git a/leaky-ships/src/components/Gamefield/Targets.tsx b/leaky-ships/src/components/Gamefield/Targets.tsx
index 4c3550c..3dcf977 100644
--- a/leaky-ships/src/components/Gamefield/Targets.tsx
+++ b/leaky-ships/src/components/Gamefield/Targets.tsx
@@ -1,7 +1,6 @@
import { For, Match, Switch } from "solid-js"
-import { useGameProps } from "~/hooks/useGameProps"
-import useIndex from "~/hooks/useIndex"
-import useShips from "~/hooks/useShips"
+import { gameState, mode, target, targetPreview } from "~/hooks/useGameProps"
+import { useSession } from "~/hooks/useSession"
import {
composeTargetTiles,
intersectingShip,
@@ -12,29 +11,29 @@ import HitElems from "./HitElems"
import Ship from "./Ship"
function Targets() {
- const { activeUser } = useIndex()
- const { payload, target, targetPreview, mode } = useGameProps()
- const { ships } = useShips()
+ const { activeUser, ships } = useSession()
- const ship = shipProps(ships(), mode, targetPreview)
+ const ship = shipProps(ships(), mode(), targetPreview())
const { fields, borders, score } = intersectingShip(ships(), ship)
return (
-
-
+
+
{(props) => }
{(props) => }
= 0 && targetPreview.show
- }
+ when={gameState() === "starting" && mode() >= 0 && targetPreview().show}
>
void }) {
- const { payload, userStates, full, leave, reset } = useGameProps()
const { isConnected } = useSocket()
- const navigate = useNavigate()
- const session = useSession()
+ const navigator = useNavigate()
+ const { session } = useSession()
const [launchTime, setLaunchTime] = createSignal(3)
-
- const launching = () =>
- payload?.users.length === 2 &&
- !userStates.filter((user) => !user.isReady).length
+ const launching = () => users[0].isReady() && users[1].isReady()
createEffect(() => {
if (!launching() || launchTime() > 0) return
@@ -61,17 +64,13 @@ function LobbyFrame(props: { openSettings: () => void }) {
})
createEffect(() => {
- if (payload?.game?.id || !isConnected) return
+ if (gameId() || !isConnected()) return
socket.emit("update", full)
})
createEffect(() => {
- if (
- typeof payload?.game?.state !== "string" ||
- payload?.game?.state === "lobby"
- )
- return
- navigate("/gamefield")
+ if (gameState() === "unknown" || gameState() === "lobby") return
+ navigator("/gamefield")
})
return (
@@ -79,53 +78,50 @@ function LobbyFrame(props: { openSettings: () => void }) {
Chat
- {launching() ? (
-
- {launchTime() < 0
- ? "Game starts"
- : "Game is starting in " + launchTime()}
-
- ) : (
- <>
- {"Game-PIN: "}
- {isConnected() ? (
- {payload?.gamePin ?? "----"}
- ) : (
-
- )}
- >
- )}
+
+ {launchTime() < 0
+ ? "Game starts"
+ : "Game is starting in " + launchTime()}
+
+ }
+ >
+ {"Game-PIN: "}
+ }
+ >
+ {gamePin() ?? "----"}
+
+
Settings
- {isConnected() ? (
+
+ Warte auf Verbindung
+
+ }
+ >
<>
-
+
VS
- {payload?.users[1] ? (
-
+ {users[1].id() ? (
+
) : (
Warte auf Spieler 2
)}
>
- ) : (
-
- Warte auf Verbindung
-
- )}
+
{errorType &&
}
-
+
+
@@ -137,21 +144,19 @@ function Login() {
- {errorType ? (
- <>
-
-
- navigate("/")}
- class="mt-10 rounded-lg border-2 border-gray-400 bg-gray-500 bg-opacity-75 px-16 py-2 text-white shadow-inner drop-shadow-md backdrop-blur-md transition-colors duration-300 hover:border-blue-600"
- >
-
- Return
-
-
- >
- ) : null}
+
+
+
+ navigator("/")}
+ class="mt-10 rounded-lg border-2 border-gray-400 bg-gray-500 bg-opacity-75 px-16 py-2 text-white shadow-inner drop-shadow-md backdrop-blur-md transition-colors duration-300 hover:border-blue-600"
+ >
+
+ Return
+
+
+
)
diff --git a/leaky-ships/src/routes/signout.tsx b/leaky-ships/src/routes/signout.tsx
index a442cc2..157dbc0 100644
--- a/leaky-ships/src/routes/signout.tsx
+++ b/leaky-ships/src/routes/signout.tsx
@@ -1,15 +1,16 @@
import { signOut } from "@auth/solid-start/client"
+import { faLeftLong } from "@fortawesome/pro-solid-svg-icons"
import { createEffect } from "solid-js"
import { useNavigate } from "solid-start"
+import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
import { useSession } from "~/hooks/useSession"
function Logout() {
- const { state } = useSession()
-
+ const { session } = useSession()
const navigator = useNavigate()
createEffect(() => {
- if (state === "ready") navigator("/signin") // TODO
+ if (!session()) navigator("/signin")
})
return (
@@ -36,6 +37,17 @@ function Logout() {
Sign out
+
+
+ navigator("/")}
+ class="mt-10 rounded-lg border-2 border-gray-400 bg-gray-500 bg-opacity-75 px-16 py-2 text-white shadow-inner drop-shadow-md backdrop-blur-md transition-colors duration-300 hover:border-blue-600"
+ >
+
+ Return
+
+
diff --git a/leaky-ships/src/routes/start.tsx b/leaky-ships/src/routes/start.tsx
index 66a0eeb..a0a5745 100644
--- a/leaky-ships/src/routes/start.tsx
+++ b/leaky-ships/src/routes/start.tsx
@@ -10,7 +10,7 @@ import BurgerMenu from "~/components/BurgerMenu"
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
import Logo from "~/components/Logo"
import OptionButton from "~/components/OptionButton"
-import { useGameProps } from "~/hooks/useGameProps"
+import { full } from "~/hooks/useGameProps"
import { useSession } from "~/hooks/useSession"
export function isAuthenticated(res: Response) {
@@ -44,11 +44,11 @@ export function isAuthenticated(res: Response) {
// }
export default function Start() {
- const [otp] = createSignal("")
- const gameProps = useGameProps()
+ const [otp, setOtp] = createSignal("")
const location = useLocation()
- const navigate = useNavigate()
- const session = useSession()
+ const navigator = useNavigate()
+ const { session } = useSession()
+
const [searchParams] = useSearchParams()
const query = () => {
@@ -82,7 +82,8 @@ export default function Start() {
// hideProgressBar: true,
// closeButton: false,
// })
- const res = await gameRequestPromise.catch(() => {
+ const res = await gameRequestPromise.catch((err) => {
+ console.log(err)
// toast.update(toastId, {
// render: "Es ist ein Fehler aufgetreten bei der Anfrage 🤯",
// type: "error",
@@ -94,13 +95,13 @@ export default function Start() {
// })
})
if (!res) return
- gameProps.full(res)
+ full(res)
// toast.update(toastId, {
// render: "Weiterleitung",
// })
- navigate("/lobby")
+ navigator("/lobby")
// .then(() =>
// toast.update(toastId, {
// render: "Raum begetreten 👌",
@@ -141,19 +142,19 @@ export default function Start() {
class="-mt-2 h-14 w-20 self-start rounded-xl border-b-4 border-shield-gray bg-voidDark text-2xl text-grayish duration-100 active:border-b-0 active:border-t-4 sm:-mt-6 sm:w-40 sm:px-2 sm:text-5xl"
onClick={() =>
setTimeout(() => {
- navigate("/")
+ navigator("/")
}, 200)
}
>
- {!session.latest?.user?.id && (
+ {!session()?.user?.id && (
setTimeout(() => {
- navigate("/signin")
+ navigator("/signin")
}, 200)
}
>
@@ -166,12 +167,12 @@ export default function Start() {
text="Raum erstellen"
callback={gameFetch}
icon={faPlus}
- disabled={!session.latest}
+ disabled={!session()}
/>
- navigate(
+ navigator(
location.pathname.concat(
"?",
new URLSearchParams({ q: "join" }).toString(),
@@ -179,32 +180,30 @@ export default function Start() {
)
}
icon={faUserPlus}
- disabled={!session.latest}
- nodeWhen={query().join && !!session.latest}
+ disabled={!session()}
+ nodeWhen={query().join && !!session()}
node={
- <>
- {
- // -}
- // renderInput={(props) => }
- // />
- }
- >
+ setOtp(e.target.value)} />
+
+ // -}
+ // renderInput={(props) => }
+ // />
}
/>
- navigate(
+ navigator(
location.pathname +
"?" +
new URLSearchParams({