diff --git a/.eslintrc.js b/.eslintrc.js index 7788059e..89b58447 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -25,6 +25,11 @@ module.exports = { files: [ "src/**/*.{ts,tsx}", ], + extends: [ + "plugin:matrix-org/typescript", + "plugin:matrix-org/react", + "prettier", + ], }, ], settings: { diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index ef155587..60e67039 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,9 +1,9 @@ -name: Lint and format +name: Lint, format & type check on: pull_request: {} jobs: prettier: - name: Lint and format + name: Lint, format & type check runs-on: ubuntu-latest steps: - name: Checkout code @@ -17,4 +17,6 @@ jobs: - name: Prettier run: "yarn run prettier:check" - name: ESLint - run: "yarn run lint" + run: "yarn run lint:js" + - name: Type check + run: "yarn run lint:types" diff --git a/package.json b/package.json index 3ac338e7..36540516 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "build-storybook": "build-storybook", "prettier:check": "prettier -c src", "prettier:format": "prettier -w src", - "lint": "eslint --max-warnings 2 src" + "lint:js": "eslint --max-warnings 2 src", + "lint:types": "tsc" }, "dependencies": { "@juggle/resize-observer": "^3.3.1", @@ -34,7 +35,7 @@ "color-hash": "^2.0.1", "events": "^3.3.0", "lodash-move": "^1.1.1", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#robertlong/group-call", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#acef1d7dd0b915368730efabee94deb42b2e4058", "mermaid": "^8.13.8", "normalize.css": "^8.0.1", "pako": "^2.0.4", @@ -51,10 +52,16 @@ }, "devDependencies": { "@babel/core": "^7.16.5", + "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz", "@storybook/react": "^6.5.0-alpha.5", + "@types/request": "^2.48.8", + "@typescript-eslint/eslint-plugin": "^5.22.0", + "@typescript-eslint/parser": "^5.22.0", "babel-loader": "^8.2.3", "eslint": "^8.14.0", + "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-matrix-org": "^0.4.0", "eslint-plugin-react": "^7.29.4", @@ -62,6 +69,7 @@ "prettier": "^2.6.2", "sass": "^1.42.1", "storybook-builder-vite": "^0.1.12", + "typescript": "^4.6.4", "vite": "^2.4.2", "vite-plugin-html-template": "^1.1.0", "vite-plugin-svgr": "^0.4.0" diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts new file mode 100644 index 00000000..7b9c1d9d --- /dev/null +++ b/src/@types/global.d.ts @@ -0,0 +1,17 @@ +/* +Copyright 2022 Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import "matrix-js-sdk/src/@types/global"; diff --git a/src/@types/modules.d.ts b/src/@types/modules.d.ts new file mode 100644 index 00000000..b1f45c78 --- /dev/null +++ b/src/@types/modules.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/src/Avatar.jsx b/src/Avatar.tsx similarity index 74% rename from src/Avatar.jsx rename to src/Avatar.tsx index fcfc3339..eda272a3 100644 --- a/src/Avatar.jsx +++ b/src/Avatar.tsx @@ -1,5 +1,6 @@ import React, { useMemo } from "react"; import classNames from "classnames"; + import styles from "./Avatar.module.css"; const backgroundColors = [ @@ -13,7 +14,7 @@ const backgroundColors = [ "#74D12C", ]; -function hashStringToArrIndex(str, arrLength) { +function hashStringToArrIndex(str: string, arrLength: number) { let sum = 0; for (let i = 0; i < str.length; i++) { @@ -23,7 +24,16 @@ function hashStringToArrIndex(str, arrLength) { return sum % arrLength; } -export function Avatar({ +interface Props extends React.HTMLAttributes { + bgKey?: string; + src: string; + fallback: string; + size?: number; + className: string; + style: React.CSSProperties; +} + +export const Avatar: React.FC = ({ bgKey, src, fallback, @@ -31,7 +41,7 @@ export function Avatar({ className, style, ...rest -}) { +}) => { const backgroundColor = useMemo(() => { const index = hashStringToArrIndex( bgKey || fallback || src || "", @@ -40,6 +50,7 @@ export function Avatar({ return backgroundColors[index]; }, [bgKey, src, fallback]); + /* eslint-disable jsx-a11y/alt-text */ return (
); -} +}; diff --git a/src/auth/generateRandomName.js b/src/auth/generateRandomName.ts similarity index 97% rename from src/auth/generateRandomName.js rename to src/auth/generateRandomName.ts index bcd9d0ae..b58c1114 100644 --- a/src/auth/generateRandomName.js +++ b/src/auth/generateRandomName.ts @@ -19,6 +19,7 @@ import { adjectives, colors, animals, + Config, } from "unique-names-generator"; const elements = [ @@ -142,7 +143,7 @@ const elements = [ "oganesson", ]; -export function generateRandomName(config) { +export function generateRandomName(config: Config): string { return uniqueNamesGenerator({ dictionaries: [colors, adjectives, animals, elements], style: "lowerCase", diff --git a/src/room/PTTButton.jsx b/src/room/PTTButton.tsx similarity index 85% rename from src/room/PTTButton.jsx rename to src/room/PTTButton.tsx index 8448f96a..10f45edd 100644 --- a/src/room/PTTButton.jsx +++ b/src/room/PTTButton.tsx @@ -16,11 +16,23 @@ limitations under the License. import React, { useCallback, useEffect, useState } from "react"; import classNames from "classnames"; + import styles from "./PTTButton.module.css"; import { ReactComponent as MicIcon } from "../icons/Mic.svg"; import { Avatar } from "../Avatar"; -export function PTTButton({ +interface Props { + showTalkOverError: boolean; + activeSpeakerUserId: string; + activeSpeakerDisplayName: string; + activeSpeakerAvatarUrl: string; + activeSpeakerIsLocalUser: boolean; + size: number; + startTalking: () => void; + stopTalking: () => void; +} + +export const PTTButton: React.FC = ({ showTalkOverError, activeSpeakerUserId, activeSpeakerDisplayName, @@ -29,17 +41,17 @@ export function PTTButton({ size, startTalking, stopTalking, -}) { +}) => { const [isHeld, setHeld] = useState(false); const onDocumentMouseUp = useCallback(() => { if (isHeld) stopTalking(); setHeld(false); - }, [isHeld, setHeld]); + }, [isHeld, setHeld, stopTalking]); const onButtonMouseDown = useCallback(() => { setHeld(true); startTalking(); - }, [setHeld]); + }, [setHeld, startTalking]); useEffect(() => { window.addEventListener("mouseup", onDocumentMouseUp); @@ -48,7 +60,6 @@ export function PTTButton({ window.removeEventListener("mouseup", onDocumentMouseUp); }; }, [onDocumentMouseUp]); - return (