From 57a065abd1f3e8bfe79aca282b9a40bf784a7fb2 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Mon, 13 Feb 2023 14:59:00 -0600 Subject: [PATCH] Add typescript checking --- .dir-locals.el | 2 +- .eslintrc.cjs | 31 +++++++++ .eslintrc.yml | 17 ----- package-lock.json | 137 ++++---------------------------------- package.json | 6 +- src/Contestant.tsx | 5 -- src/DrawPad.tsx | 20 +++--- src/main.tsx | 2 +- src/socket.ts | 13 ++-- src/store/displaySlice.ts | 2 +- 10 files changed, 69 insertions(+), 166 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.yml diff --git a/.dir-locals.el b/.dir-locals.el index d354f5d..517f77e 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -2,5 +2,5 @@ ;;; For more information see (info "(emacs) Directory Variables") ((js-mode . ((js-indent-level . 2))) - (web-mode . ((mode . prettier) + (web-mode . ((mode . prettier-js) (indent-tabs-mode . nil)))) diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..018f7fb --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,31 @@ +module.exports = { + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react/jsx-runtime", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking" + ], + "overrides": [], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "project": "./tsconfig.json", + "tsconfigRootDir": __dirname, + }, + "plugins": [ + "react", + "@typescript-eslint" + ], + "rules": {}, + "settings": { + "react": { + "version": "detect", + }, + }, +} diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 746f164..0000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,17 +0,0 @@ -env: - browser: true - es2021: true -extends: - - eslint:recommended - - plugin:react/recommended - - plugin:react/jsx-runtime - - plugin:@typescript-eslint/recommended -overrides: [] -parser: '@typescript-eslint/parser' -parserOptions: - ecmaVersion: latest - sourceType: module -plugins: - - react - - '@typescript-eslint' -rules: {} diff --git a/package-lock.json b/package-lock.json index 8c5d010..21791b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,18 +10,17 @@ "dependencies": { "@reduxjs/toolkit": "^1.9.2", "bootstrap": "^5.2.3", - "konva": "^8.4.2", "lodash": "^4.17.21", "react": "^18.2.0", "react-bootstrap": "^2.7.0", "react-dom": "^18.2.0", - "react-konva": "^18.2.3", "react-redux": "^8.0.5", "react-router": "^6.7.0", "react-router-dom": "^6.7.0", "socket.io-client": "^4.5.4" }, "devDependencies": { + "@types/lodash": "^4.14.191", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", "@typescript-eslint/eslint-plugin": "^5.49.0", @@ -1045,6 +1044,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true + }, "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -1077,14 +1082,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-reconciler": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.2.tgz", - "integrity": "sha512-8tu6lHzEgYPlfDf/J6GOQdIc+gs+S2yAqlby3zTsB3SP2svlqTYe5fwZNtZyfactP74ShooP2vvi1BOp9ZemWw==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -3046,17 +3043,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/its-fine": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.0.8.tgz", - "integrity": "sha512-MagTA9/J6kN3aEQsQu6by3nyrttCm0whCOYo4SfiNzOfYgcr1cb29mJ3zgluaJboaWOL/lHzJeMXi/QGSCfX1Q==", - "dependencies": { - "@types/react-reconciler": "^0.28.0" - }, - "peerDependencies": { - "react": ">=18.0" - } - }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -3133,25 +3119,6 @@ "node": ">=4.0" } }, - "node_modules/konva": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/konva/-/konva-8.4.2.tgz", - "integrity": "sha512-4VQcrgj/PI8ydJjtLcTuinHBE8o0WGX0YoRwbiN5mpYQiC52aOzJ0XbpKNDJdRvORQphK5LP+jeM0hQJEYIuUA==", - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/lavrton" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/konva" - }, - { - "type": "github", - "url": "https://github.com/sponsors/lavrton" - } - ] - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3681,55 +3648,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/react-konva": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.3.tgz", - "integrity": "sha512-OPxjBTgaEGU9pt/VJSVM7QNXYHEZ5CkulX+4fTTvbaH+Wh+vMLbXmH3yjWw4kT/5Qi6t0UQKHPPmirCv8/9sdg==", - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/lavrton" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/konva" - }, - { - "type": "github", - "url": "https://github.com/sponsors/lavrton" - } - ], - "dependencies": { - "its-fine": "^1.0.6", - "react-reconciler": "~0.29.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "konva": "^8.0.1 || ^7.2.5", - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, - "node_modules/react-reconciler": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", - "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, "node_modules/react-redux": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", @@ -5201,6 +5124,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true + }, "@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -5233,14 +5162,6 @@ "@types/react": "*" } }, - "@types/react-reconciler": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.2.tgz", - "integrity": "sha512-8tu6lHzEgYPlfDf/J6GOQdIc+gs+S2yAqlby3zTsB3SP2svlqTYe5fwZNtZyfactP74ShooP2vvi1BOp9ZemWw==", - "requires": { - "@types/react": "*" - } - }, "@types/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -6643,14 +6564,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "its-fine": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.0.8.tgz", - "integrity": "sha512-MagTA9/J6kN3aEQsQu6by3nyrttCm0whCOYo4SfiNzOfYgcr1cb29mJ3zgluaJboaWOL/lHzJeMXi/QGSCfX1Q==", - "requires": { - "@types/react-reconciler": "^0.28.0" - } - }, "js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -6705,11 +6618,6 @@ "object.assign": "^4.1.3" } }, - "konva": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/konva/-/konva-8.4.2.tgz", - "integrity": "sha512-4VQcrgj/PI8ydJjtLcTuinHBE8o0WGX0YoRwbiN5mpYQiC52aOzJ0XbpKNDJdRvORQphK5LP+jeM0hQJEYIuUA==" - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7079,30 +6987,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "react-konva": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.3.tgz", - "integrity": "sha512-OPxjBTgaEGU9pt/VJSVM7QNXYHEZ5CkulX+4fTTvbaH+Wh+vMLbXmH3yjWw4kT/5Qi6t0UQKHPPmirCv8/9sdg==", - "requires": { - "its-fine": "^1.0.6", - "react-reconciler": "~0.29.0", - "scheduler": "^0.23.0" - } - }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, - "react-reconciler": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", - "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - } - }, "react-redux": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", diff --git a/package.json b/package.json index aa081b7..158cdd8 100644 --- a/package.json +++ b/package.json @@ -7,23 +7,23 @@ "start": "vite --host", "build": "tsc && vite build", "preview": "vite preview", - "pretty": "prettier -w src" + "pretty": "prettier -w src", + "lint": "eslint src" }, "dependencies": { "@reduxjs/toolkit": "^1.9.2", "bootstrap": "^5.2.3", - "konva": "^8.4.2", "lodash": "^4.17.21", "react": "^18.2.0", "react-bootstrap": "^2.7.0", "react-dom": "^18.2.0", - "react-konva": "^18.2.3", "react-redux": "^8.0.5", "react-router": "^6.7.0", "react-router-dom": "^6.7.0", "socket.io-client": "^4.5.4" }, "devDependencies": { + "@types/lodash": "^4.14.191", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", "@typescript-eslint/eslint-plugin": "^5.49.0", diff --git a/src/Contestant.tsx b/src/Contestant.tsx index f8f6f4e..0f58314 100644 --- a/src/Contestant.tsx +++ b/src/Contestant.tsx @@ -15,11 +15,6 @@ const Contestant = () => { useEffect(() => { socket.emit("contestant-join", { room, signature }); }, []); - useEffect(() => { - if (parent.current) { - setWidth(parent.current.getBoundingClientRect().width); - } - }, [parent]); const handleBuzz = debounce( () => { diff --git a/src/DrawPad.tsx b/src/DrawPad.tsx index 1b32c9f..fa3191f 100644 --- a/src/DrawPad.tsx +++ b/src/DrawPad.tsx @@ -1,20 +1,22 @@ import { useRef, useState, useEffect } from "react"; +import type { PointerEvent } from "react"; type Props = { - height: number, - lines: number[][], - onUpdateImage?: (path: number[]) => unknown, - readonly?: boolean, + height: number; + lines: number[][]; + onUpdateImage?: (path: number[]) => unknown; + readonly?: boolean; }; -const cursorPos = (e) => { - const rect = e.target.getBoundingClientRect(); +const cursorPos = (e: PointerEvent) => { + const target = e.target as HTMLCanvasElement; + const rect: DOMRect = target.getBoundingClientRect(); return [e.clientX - rect.left, e.clientY - rect.top]; }; const DrawPad = ({ height, lines, onUpdateImage, readonly = false }: Props) => { - const parent = useRef(); - const canvas = useRef(); + const parent = useRef(); + const canvas = useRef(); const [width, setWidth] = useState(0); const [down, setDown] = useState(false); const [path, setPath] = useState([]); @@ -51,7 +53,7 @@ const DrawPad = ({ height, lines, onUpdateImage, readonly = false }: Props) => { setDown(true); }; - const drawLine = (e) => { + const drawLine = (e: PointerEvent) => { if (!down) return; const [x, y] = cursorPos(e); setPath([...path, x, y]); diff --git a/src/main.tsx b/src/main.tsx index 6236e11..5841dd9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; -import { setup } from './socket'; +import { setup } from "./socket"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/src/socket.ts b/src/socket.ts index 870b203..eebb3dc 100644 --- a/src/socket.ts +++ b/src/socket.ts @@ -11,15 +11,18 @@ export const setup = () => { console.log("Connected to socket"); }); - socket.on("set-code", ({ code }) => { + socket.on("set-code", ({ code }: { code: string }) => { store.dispatch(setRoomCode(code)); }); - socket.on("contestant-joined", (data) => { - store.dispatch(addContestant(data)); - }); + socket.on( + "contestant-joined", + (data: { sid: string; signature: number[][] }) => { + store.dispatch(addContestant(data)); + } + ); - socket.on("categories", (data) => + socket.on("categories", (data: string[]) => data.forEach((category) => store.dispatch(addCategory(category))) ); }; diff --git a/src/store/displaySlice.ts b/src/store/displaySlice.ts index ced7299..7f54fac 100644 --- a/src/store/displaySlice.ts +++ b/src/store/displaySlice.ts @@ -5,7 +5,7 @@ interface DisplayState { contestants: Record; } -interface Contestant { +export interface Contestant { signature: number[][]; score: number; active: boolean;