From d245009c37922ea5bd109e48c5f41e87d2e97b39 Mon Sep 17 00:00:00 2001 From: aronmal Date: Sun, 10 Sep 2023 01:42:09 +0200 Subject: [PATCH] Fixid color picker and drawing functionality --- leaky-ships/package.json | 3 + leaky-ships/pnpm-lock.yaml | 25 ++++++++ .../src/components/Gamefield/EventBar.tsx | 8 ++- .../src/components/Gamefield/Gamefield.tsx | 19 +----- leaky-ships/src/components/Gamefield/Item.tsx | 47 ++++++--------- .../src/hooks/{useDraw.ts => useDraw.tsx} | 58 +++++++++++++------ leaky-ships/src/hooks/useDrawProps.ts | 41 ++++++++----- leaky-ships/src/hooks/useGameProps.ts | 8 --- leaky-ships/src/hooks/useSocket.ts | 7 ++- leaky-ships/src/styles/App.scss | 8 ++- 10 files changed, 132 insertions(+), 92 deletions(-) rename leaky-ships/src/hooks/{useDraw.ts => useDraw.tsx} (75%) diff --git a/leaky-ships/package.json b/leaky-ships/package.json index 067db5a..579e677 100644 --- a/leaky-ships/package.json +++ b/leaky-ships/package.json @@ -31,13 +31,16 @@ "drizzle-zod": "^0.5.1", "http-status": "^1.7.0", "json-stable-stringify": "^1.0.2", + "lodash-es": "^4.17.21", "nodemailer": "^6.9.5", "object-hash": "^3.0.0", "postgres": "^3.3.5", "socket.io": "^4.7.2", "socket.io-client": "^4.7.2", + "solid-color": "^0.0.4", "solid-js": "^1.7.11", "solid-start": "^0.3.5", + "tinycolor2": "^1.6.0", "unique-names-generator": "^4.7.1", "zod": "3.21.1" }, diff --git a/leaky-ships/pnpm-lock.yaml b/leaky-ships/pnpm-lock.yaml index f531c4d..d9b527c 100644 --- a/leaky-ships/pnpm-lock.yaml +++ b/leaky-ships/pnpm-lock.yaml @@ -69,6 +69,9 @@ dependencies: json-stable-stringify: specifier: ^1.0.2 version: 1.0.2 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 nodemailer: specifier: ^6.9.5 version: 6.9.5 @@ -84,12 +87,18 @@ dependencies: socket.io-client: specifier: ^4.7.2 version: 4.7.2 + solid-color: + specifier: ^0.0.4 + version: 0.0.4(solid-js@1.7.11) solid-js: specifier: ^1.7.11 version: 1.7.11 solid-start: specifier: ^0.3.5 version: 0.3.5(@solidjs/meta@0.28.6)(@solidjs/router@0.8.3)(solid-js@1.7.11)(solid-start-node@0.3.5)(vite@4.4.9) + tinycolor2: + specifier: ^1.6.0 + version: 1.6.0 unique-names-generator: specifier: ^4.7.1 version: 4.7.1 @@ -4088,6 +4097,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + /lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -5021,6 +5034,14 @@ packages: - utf-8-validate dev: false + /solid-color@0.0.4(solid-js@1.7.11): + resolution: {integrity: sha512-hFZ0E0v6OYiuxc73txwlN8NB1KoeEU3mw5rwBfk3eJ8Kr/yY7h4G7X/QZ1xhnmOeVmam8lHk8iTujee8BeWSOw==} + peerDependencies: + solid-js: '>=1.0.0' + dependencies: + solid-js: 1.7.11 + dev: false + /solid-js@1.7.11: resolution: {integrity: sha512-JkuvsHt8jqy7USsy9xJtT18aF9r2pFO+GB8JQ2XGTvtF49rGTObB46iebD25sE3qVNvIbwglXOXdALnJq9IHtQ==} dependencies: @@ -5316,6 +5337,10 @@ packages: next-tick: 1.1.0 dev: true + /tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + dev: false + /titleize@3.0.0: resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} engines: {node: '>=12'} diff --git a/leaky-ships/src/components/Gamefield/EventBar.tsx b/leaky-ships/src/components/Gamefield/EventBar.tsx index 377d323..e9436b5 100644 --- a/leaky-ships/src/components/Gamefield/EventBar.tsx +++ b/leaky-ships/src/components/Gamefield/EventBar.tsx @@ -26,7 +26,12 @@ import { modes } from "~/lib/utils/helpers" // import { Icons, toast } from "react-toastify" import { For, Show, createEffect } from "solid-js" import { useNavigate } from "solid-start" -import { useDrawProps } from "~/hooks/useDrawProps" +import { + color, + setEnable, + setShouldHide, + shouldHide, +} from "~/hooks/useDrawProps" import { gameProps, reset, @@ -43,7 +48,6 @@ import { EventBarModes } from "../../interfaces/frontend" import Item from "./Item" function EventBar(props: { clear: () => void }) { - const { shouldHide, setShouldHide, setEnable, color } = useDrawProps const { selfIndex, selfIsActiveIndex, selfUser, ships } = useSession() const navigator = useNavigate() diff --git a/leaky-ships/src/components/Gamefield/Gamefield.tsx b/leaky-ships/src/components/Gamefield/Gamefield.tsx index fefb352..4557023 100644 --- a/leaky-ships/src/components/Gamefield/Gamefield.tsx +++ b/leaky-ships/src/components/Gamefield/Gamefield.tsx @@ -7,8 +7,7 @@ import BorderTiles from "~/components/Gamefield/BorderTiles" import EventBar from "~/components/Gamefield/EventBar" import HitElems from "~/components/Gamefield/HitElems" import Targets from "~/components/Gamefield/Targets" -import { useDraw } from "~/hooks/useDraw" -import { useDrawProps } from "~/hooks/useDrawProps" +import { DrawingCanvas, clearDrawing } from "~/hooks/useDraw" import { full, gameProps, @@ -33,8 +32,6 @@ function Gamefield() { const { ships } = useSession() const navigator = useNavigate() const { isConnected } = useSocket() - const usingDraw = useDraw() - const { enable, color, shouldHide } = useDrawProps createEffect(() => { if ( @@ -119,19 +116,9 @@ function Gamefield() { - + - + ) } diff --git a/leaky-ships/src/components/Gamefield/Item.tsx b/leaky-ships/src/components/Gamefield/Item.tsx index c26daf2..99a1a94 100644 --- a/leaky-ships/src/components/Gamefield/Item.tsx +++ b/leaky-ships/src/components/Gamefield/Item.tsx @@ -1,47 +1,31 @@ -import { Show, createEffect, createSignal, onCleanup } from "solid-js" -import { FontAwesomeIcon } from "~/components/FontAwesomeIcon" -// import { useDrawProps } from "~/hooks/useDrawProps" -// import { HexColorPicker } from "react-colorful" import classNames from "classnames" +import { BlockPicker } from "solid-color" +import { Show, createSignal } from "solid-js" +import { FontAwesomeIcon } from "~/components/FontAwesomeIcon" +import { color, colors, setColor } from "~/hooks/useDrawProps" import { ItemProps } from "../../interfaces/frontend" function Item(props: ItemProps) { const isColor = () => props.text === "Color" - // const { color, setColor } = useDrawProps() const [active, setActive] = createSignal(false) let cpRef: HTMLDivElement - createEffect(() => { - const inActive = (e: MouseEvent) => { - if (cpRef && !cpRef.contains(e.target as Node)) setActive(false) - } - - // Add event listeners - if (!isColor()) return - setTimeout(() => window.addEventListener("click", inActive), 200) - - // Remove event listeners - onCleanup(() => { - window.removeEventListener("click", inActive) - }) - }) - return ( -
- isColor() ? setActive(true) : props.callback && props.callback() - } - > +
- {/* */} + setColor(e.hex)} + colors={colors} + triangle="hide" + />
-
{ + isColor() ? setActive((e) => !e) : props.callback && props.callback() + }} > {typeof props.icon === "string" ? ( )} -
+ {props.text}
) diff --git a/leaky-ships/src/hooks/useDraw.ts b/leaky-ships/src/hooks/useDraw.tsx similarity index 75% rename from leaky-ships/src/hooks/useDraw.ts rename to leaky-ships/src/hooks/useDraw.tsx index bde1e0b..d83c456 100644 --- a/leaky-ships/src/hooks/useDraw.ts +++ b/leaky-ships/src/hooks/useDraw.tsx @@ -1,7 +1,9 @@ import { createEffect, createSignal, onCleanup } from "solid-js" import { socket } from "~/lib/socket" import { Draw, DrawLineProps, PlayerEvent, Point } from "../interfaces/frontend" -import { useDrawProps } from "./useDrawProps" +import { color, enable, shouldHide } from "./useDrawProps" + +let canvasRef: HTMLCanvasElement function drawLine({ prevPoint, currentPoint, ctx, color }: Draw) { const { x: currX, y: currY } = currentPoint @@ -22,38 +24,41 @@ function drawLine({ prevPoint, currentPoint, ctx, color }: Draw) { ctx.fill() } -export const useDraw = () => { +function clear() { + const canvas = canvasRef + if (!canvas) return + + const ctx = canvas.getContext("2d") + if (!ctx) return + + ctx.clearRect(0, 0, canvas.width, canvas.height) +} + +export function DrawingCanvas() { const [mouseDown, setMouseDown] = createSignal(false) - let canvasRef: HTMLCanvasElement let prevPoint: null | Point - const { color } = useDrawProps - const onMouseDown = () => setMouseDown(true) - const clear = () => { - const canvas = canvasRef - if (!canvas) return - - const ctx = canvas.getContext("2d") - if (!ctx) return - - ctx.clearRect(0, 0, canvas.width, canvas.height) - } - createEffect(() => { const canvas = canvasRef if (!canvas) return const handler = (e: MouseEvent) => { - if (!mouseDown) return + if (!mouseDown()) return const currentPoint = computePointInCanvas(e) const ctx = canvasRef?.getContext("2d") if (!ctx || !currentPoint) return - drawLine({ ctx, currentPoint, prevPoint: prevPoint, color: color() }) + const props = { + currentPoint, + prevPoint: prevPoint, + color: color(), + } + socket.emit("draw-line", props) + drawLine({ ctx, ...props }) prevPoint = currentPoint } @@ -121,5 +126,22 @@ export const useDraw = () => { }) }) - return { canvasRef: canvasRef!, onMouseDown, clear } + return ( + + ) +} + +export function clearDrawing() { + clear() + socket.emit("canvas-clear") } diff --git a/leaky-ships/src/hooks/useDrawProps.ts b/leaky-ships/src/hooks/useDrawProps.ts index 35a9070..ba89601 100644 --- a/leaky-ships/src/hooks/useDrawProps.ts +++ b/leaky-ships/src/hooks/useDrawProps.ts @@ -1,19 +1,30 @@ import { createSignal } from "solid-js" -const [enable, setEnable] = createSignal(false) -const [shouldHide, setShouldHide] = createSignal(false) -const [color, setColor] = createSignal("#b32aa9") +export const colors = [ + "#ff4400", + "#fea800", + "#ffd635", + "#00a367", + "#7eed55", + "#2351a6", + "#3590ea", + "#52e9f3", + "#811e9f", + "#b34abf", + "#fe99a9", + "#9c6926", + // "#ffffff", + "#d3d7d8", + "#898d90", + "#000000", +] -export const useDrawProps = { - enable, - setEnable, - shouldHide, - setShouldHide, - color, - setColor, - reset: () => { - setEnable(false) - setShouldHide(false) - setColor("#b32aa9") - }, +export const [enable, setEnable] = createSignal(false) +export const [shouldHide, setShouldHide] = createSignal(false) +export const [color, setColor] = createSignal("#b32aa9") + +export function reset() { + setEnable(false) + setShouldHide(false) + setColor("#b32aa9") } diff --git a/leaky-ships/src/hooks/useGameProps.ts b/leaky-ships/src/hooks/useGameProps.ts index 0f4eb40..80897d8 100644 --- a/leaky-ships/src/hooks/useGameProps.ts +++ b/leaky-ships/src/hooks/useGameProps.ts @@ -129,14 +129,6 @@ export function setPlayer(newUsers: Players): string | null { setUsers(0, newUsers) setUsers(1, newUsers) const body = getPayloadwithChecksum(getPayloadFromProps()) - if (!body.hash) { - console.log("Something is wrong... ") - // toast.warn("Something is wrong... ", { - // toastId: "st_wrong", - // theme: "colored", - // }) - return null - } hash = body.hash setGameProps("hash", hash) return hash diff --git a/leaky-ships/src/hooks/useSocket.ts b/leaky-ships/src/hooks/useSocket.ts index 534d7cc..c3b0e5c 100644 --- a/leaky-ships/src/hooks/useSocket.ts +++ b/leaky-ships/src/hooks/useSocket.ts @@ -2,6 +2,8 @@ import status from "http-status" // import { toast } from "react-toastify" import { createEffect, createSignal, onCleanup } from "solid-js" import { useNavigate } from "solid-start" +import { getPayloadFromProps } from "~/lib/getPayloadFromProps" +import { getPayloadwithChecksum } from "~/lib/getPayloadwithChecksum" import { socket } from "~/lib/socket" import { GamePropsSchema, GameState } from "~/lib/zodSchemas" import { isAuthenticated } from "~/routes/start" @@ -70,8 +72,11 @@ function useSocket() { let message: string if (type !== "disconnect") { const { hash } = event + const hashAlreadyMatches = + hash === getPayloadwithChecksum(getPayloadFromProps()).hash + if (hashAlreadyMatches) return const newHash = setPlayer(event.users) - if (newHash && newHash !== hash) { + if (newHash !== hash) { console.log("hash", hash, newHash) socket.emit("update", (body) => { console.log("Update is needed after", type) diff --git a/leaky-ships/src/styles/App.scss b/leaky-ships/src/styles/App.scss index 361639c..c1f8701 100644 --- a/leaky-ships/src/styles/App.scss +++ b/leaky-ships/src/styles/App.scss @@ -395,12 +395,12 @@ body { width: 128px; position: relative; - .react-colorful-wrapper { + .color-picker-wrapper { pointer-events: none; opacity: 0; transition: 0.2s; position: absolute; - top: -225px; + bottom: 105%; left: 50%; transform: translateX(-50%); z-index: 1; @@ -454,6 +454,10 @@ body { color: black; font-size: 0.75em; font-weight: bold; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } } }