diff --git a/.eslintrc.js b/.eslintrc.js index 2fbdbf2..a55fb50 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,9 +15,15 @@ module.exports = { extends: [ "eslint:recommended", "plugin:react/recommended", + "plugin:react-hooks/recommended", "prettier", "prettier/@typescript-eslint", ], + settings: { + react: { + version: "16.13.1", + }, + }, parser: "@typescript-eslint/parser", parserOptions: { project: "tsconfig.json", @@ -185,7 +191,6 @@ module.exports = { "no-var": "error", "object-shorthand": "error", "one-var": ["error", "never"], - "prefer-arrow/prefer-arrow-functions": "error", "prefer-const": "error", "prefer-object-spread": "error", "quote-props": "off", @@ -208,9 +213,7 @@ module.exports = { "error", { rules: { - "object-curly-spacing": true, "prefer-conditional-expression": true, - "react-hooks-nesting": true, typedef: [ true, "parameter", diff --git a/package-lock.json b/package-lock.json index 063c646..b7afa5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8956,9 +8956,10 @@ } }, "eslint-plugin-react-hooks": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", - "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.0.tgz", + "integrity": "sha512-36zilUcDwDReiORXmcmTc6rRumu9JIM3WjSvV0nclHoUQ0CNrX866EwONvLR/UqaeqFutbAnVu8PEmctdo2SRQ==", + "dev": true }, "eslint-scope": { "version": "5.0.0", @@ -10152,6 +10153,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "eslint-plugin-react-hooks": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==" + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -21886,12 +21892,6 @@ "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", "dev": true }, - "tslint-react-hooks": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tslint-react-hooks/-/tslint-react-hooks-2.2.2.tgz", - "integrity": "sha512-gtwA14+WevNUtlBhvAD5Ukpxt2qMegYI7IDD8zN/3JXLksdLdEuU/T/oqlI1CtZhMJffqyNn+aqq2oUqUFXiNA==", - "dev": true - }, "tsparticles": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/tsparticles/-/tsparticles-1.14.0.tgz", diff --git a/package.json b/package.json index acdf484..bf90d7c 100644 --- a/package.json +++ b/package.json @@ -86,10 +86,10 @@ "eslint-plugin-jsdoc": "^30.2.1", "eslint-plugin-prefer-arrow": "^1.2.2", "eslint-plugin-react": "^7.20.5", + "eslint-plugin-react-hooks": "^4.1.0", "gatsby-plugin-remove-trailing-slashes": "^2.3.3", "prettier": "^2.0.5", "tslint": "^6.1.2", - "tslint-config-prettier": "^1.18.0", - "tslint-react-hooks": "^2.2.2" + "tslint-config-prettier": "^1.18.0" } } diff --git a/scripts/buildHelpers.js b/scripts/buildHelpers.js index 529090a..80dcabc 100644 --- a/scripts/buildHelpers.js +++ b/scripts/buildHelpers.js @@ -1,4 +1,6 @@ +/* globals module */ const DEFAULT_AVATAR_MODULO = 5 + module.exports = { findMarkdownLink(absolutePath) { // We're assuming this path isn't going to change @@ -28,7 +30,7 @@ module.exports = { return `https://cdn.discordapp.com/embed/avatars/${avatar}.png` }, resolveAuthor(users, author) { - const target = users.find(user => user.identifier === author) + const target = users.find((user) => user.identifier === author) const [name, hash] = this.splitHash(author) const avatar = target ? target.avatar : this.getDefaultAvatar(hash) @@ -39,6 +41,6 @@ module.exports = { } }, resolveAuthors(users, authors) { - return authors.map(author => this.resolveAuthor(users, author)) + return authors.map((author) => this.resolveAuthor(users, author)) }, } diff --git a/scripts/fetchUsers.js b/scripts/fetchUsers.js index 5956f4c..a174971 100644 --- a/scripts/fetchUsers.js +++ b/scripts/fetchUsers.js @@ -1,3 +1,5 @@ +/* globals require, process, console */ +/* eslint-disable @typescript-eslint/no-var-requires */ // This script will be ran periodically through CI // don't touch it const Discord = require("discord.js") @@ -22,27 +24,23 @@ const writeS = (content, dest) => { } client.once("ready", async () => { - // tslint:disable-next-line no-console console.log("Bot ready, fetching user list...") const tph = client.guilds.cache.get(TPH) if (!tph) { throw Error("Bot is not in TPH, cannot fetch users") } const members = await tph.members.fetch() - const memberInfo = members.map(member => ({ + const memberInfo = members.map((member) => ({ avatar: member.user.displayAvatarURL(), identifier: member.user.tag, })) const wrs = fs.createWriteStream(DESTINATION) - // tslint:disable-next-line no-console console.log(`Fetched ${memberInfo.length} users, writing to ${DESTINATION}`) writeS(memberInfo, wrs).on("finish", () => { - // tslint:disable-next-line no-console console.log("Finished writing list") process.exit(0) }) }) -// tslint:disable-next-line no-console console.log("Attempting to log in...") client.login(BOT_TOKEN) diff --git a/src/SidebarProvider.tsx b/src/SidebarProvider.tsx index f69258e..256c645 100644 --- a/src/SidebarProvider.tsx +++ b/src/SidebarProvider.tsx @@ -24,7 +24,7 @@ export const SidebarProvider: FC = ({ children }) => { } else { setCurrent(null) } - }, [location]) + }, [location, getSecondLevel]) const memoizedContextValue = useMemo( () => ({ diff --git a/src/components/ArchivesSidebar/index.tsx b/src/components/ArchivesSidebar/index.tsx index fe93fd8..388d70f 100644 --- a/src/components/ArchivesSidebar/index.tsx +++ b/src/components/ArchivesSidebar/index.tsx @@ -4,7 +4,7 @@ import React, { FC, HTMLAttributes } from "react" import useBuildTree from "../../hooks/useBuildTree" import { useLockBodyScroll } from "../../hooks/useLockBodyScroll" import useSidebar from "../../hooks/useSidebar" -import { IAllArchivesQuery, IFileOrFolder } from "../../types" +import { IFileOrFolder } from "../../types" import { humanize } from "../../utils" import { Sidebar } from "../Sidebar" import * as SC from "./styles" @@ -50,7 +50,7 @@ export const ArchivesSidebar: FC> = (props) => { return ( {sortedTree.map((node) => ( - + ))} ) diff --git a/src/components/FourZeroFour/index.tsx b/src/components/FourZeroFour/index.tsx index 5535c14..1817bb2 100644 --- a/src/components/FourZeroFour/index.tsx +++ b/src/components/FourZeroFour/index.tsx @@ -1,4 +1,4 @@ -import React, { FC, Fragment } from "react" +import React, { FC } from "react" import * as SC from "./styles" interface IPossibleCorrections { diff --git a/src/components/FourZeroFourHint/index.tsx b/src/components/FourZeroFourHint/index.tsx index 35c0ff7..3a8504c 100644 --- a/src/components/FourZeroFourHint/index.tsx +++ b/src/components/FourZeroFourHint/index.tsx @@ -100,7 +100,7 @@ export const FourZeroFourHint: FC = ({ return ( -

Based off of "{search}" you may have meant:

+

Based off of "{search}" you may have meant:

{found}
    diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index ddc0ff2..b28b90d 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -4,6 +4,7 @@ import { DiscordButton } from "../DiscordButton" import { HomePartner } from "../HomePartner" import { WavesBottom, WavesTop } from "../Waves" import * as SC from "./styles" +import { OutMode, MoveDirection } from "react-particles-js" interface IMenuItemProps { to: string @@ -33,6 +34,7 @@ export const Home: FC = () => { { move: { enable: true, speed: 1.5, - direction: "top", + direction: MoveDirection.top, random: false, straight: false, - out_mode: "out", + out_mode: OutMode.out, bounce: false, attract: { enable: false }, }, @@ -67,7 +69,7 @@ export const Home: FC = () => { - The Programmer's Hangout + The Programmer's Hangout about diff --git a/src/components/ResourcesList/index.tsx b/src/components/ResourcesList/index.tsx index c4aa884..aeba34c 100644 --- a/src/components/ResourcesList/index.tsx +++ b/src/components/ResourcesList/index.tsx @@ -67,6 +67,8 @@ const Language = memo( } ) +Language.displayName = "Language" + function sortTree(tree: IFileOrFolder[]) { return sort((a, b) => a.title.localeCompare(b.title), tree) } diff --git a/src/components/ResourcesSidebar/index.tsx b/src/components/ResourcesSidebar/index.tsx index 3742d20..c4821fa 100644 --- a/src/components/ResourcesSidebar/index.tsx +++ b/src/components/ResourcesSidebar/index.tsx @@ -141,6 +141,8 @@ const FirstLevelFolder = memo(({ item }: { item: IFolder }) => { ) }) +FirstLevelFolder.displayName = "FirstLevelFolder" + const ResourceList: FC<{ items: IFileOrFolder[] setExpanded: React.Dispatch> diff --git a/src/components/ResourcesSidebar/useMatchingPath.tsx b/src/components/ResourcesSidebar/useMatchingPath.tsx index a0db98e..d0865b1 100644 --- a/src/components/ResourcesSidebar/useMatchingPath.tsx +++ b/src/components/ResourcesSidebar/useMatchingPath.tsx @@ -8,5 +8,5 @@ export default function useMatchingPath(path: string, callback: () => void) { if (isMatchingPath(path)) { callback() } - }, []) + }, [path, isMatchingPath, callback]) } diff --git a/src/components/Sidebar/index.tsx b/src/components/Sidebar/index.tsx index 761c59b..6e41340 100644 --- a/src/components/Sidebar/index.tsx +++ b/src/components/Sidebar/index.tsx @@ -28,7 +28,7 @@ export const Sidebar: FC>> = ( The
    - Programmer's + Programmer's
    Hangout
    diff --git a/src/components/Toc/index.tsx b/src/components/Toc/index.tsx index fc56f07..a1c8dfb 100644 --- a/src/components/Toc/index.tsx +++ b/src/components/Toc/index.tsx @@ -11,7 +11,7 @@ interface ITocProps { } interface ITitle { - prefix?: string + prefix: string | null title: string } @@ -20,7 +20,7 @@ function extractTitle(title: string): ITitle { const rest = maybePrefix ? title.replace(maybePrefix[0], "") : title return { - prefix: maybePrefix ? `${maybePrefix[0]} ` : undefined, + prefix: maybePrefix ? `${maybePrefix[0]} ` : null, title: rest.trim(), } } diff --git a/src/hooks/useLocalStorage.tsx b/src/hooks/useLocalStorage.tsx index dd8cfa1..8cea92a 100644 --- a/src/hooks/useLocalStorage.tsx +++ b/src/hooks/useLocalStorage.tsx @@ -1,3 +1,4 @@ +/* globals window */ import { useEffect, useState } from "react" export const useLocalStorage = (name: string, initialValue: string) => { diff --git a/src/hooks/useLockBodyScroll.tsx b/src/hooks/useLockBodyScroll.tsx index b11dd56..098556f 100644 --- a/src/hooks/useLockBodyScroll.tsx +++ b/src/hooks/useLockBodyScroll.tsx @@ -1,3 +1,4 @@ +/* globals document */ import { useState } from "react" export const useLockBodyScroll = () => { diff --git a/src/layouts/HomeLayout/index.tsx b/src/layouts/HomeLayout/index.tsx index 9e27ee3..9280a3c 100644 --- a/src/layouts/HomeLayout/index.tsx +++ b/src/layouts/HomeLayout/index.tsx @@ -15,7 +15,7 @@ export const HomeLayout: FC = () => { if (locked) { unlock() } - }, [locked]) + }, [locked, unlock]) return ( diff --git a/src/pages/archives/404.tsx b/src/pages/archives/404.tsx index bea9bc2..6e86591 100644 --- a/src/pages/archives/404.tsx +++ b/src/pages/archives/404.tsx @@ -9,7 +9,10 @@ import { SEO } from "../../components/SEO" import { FourZeroFourHint } from "../../components/FourZeroFourHint" import { FourZeroFour } from "../../components/FourZeroFour" -export default ({ data }: ComponentQuery<{ allFile: FileConnection }>) => ( +// TODO: there has to be a better type for this +const FourZeroFourPage: React.FC<{ data: { allFile: FileConnection } }> = ({ + data, +}: ComponentQuery<{ allFile: FileConnection }>) => ( @@ -26,6 +29,8 @@ export default ({ data }: ComponentQuery<{ allFile: FileConnection }>) => ( ) +export default FourZeroFourPage + export const query = graphql` query { allFile(filter: { sourceInstanceName: { eq: "what-is-archive" } }) { diff --git a/src/pages/archives/index.tsx b/src/pages/archives/index.tsx index 9e3fefd..310fb22 100644 --- a/src/pages/archives/index.tsx +++ b/src/pages/archives/index.tsx @@ -17,7 +17,7 @@ function ArchivesPage() { This regroups the archives of our occasional, temporary channels that cover a piece of technology that might be unknown to part of our users. You can find those on{" "} - The Programmer's Hangout. + The Programmer's Hangout.

    } /> diff --git a/src/pages/resources/404.tsx b/src/pages/resources/404.tsx index cfda1f8..cf6fbe5 100644 --- a/src/pages/resources/404.tsx +++ b/src/pages/resources/404.tsx @@ -8,7 +8,10 @@ import { FourZeroFourHint } from "../../components/FourZeroFourHint" import { SEO } from "../../components/SEO" import { FourZeroFour } from "../../components/FourZeroFour" -export default ({ data }: ComponentQuery<{ allFile: FileConnection }>) => ( +// TODO: there has to be a better type for this +const FourZeroFourPage: React.FC<{ data: { allFile: FileConnection } }> = ({ + data, +}: ComponentQuery<{ allFile: FileConnection }>) => ( @@ -25,6 +28,8 @@ export default ({ data }: ComponentQuery<{ allFile: FileConnection }>) => ( ) +export default FourZeroFourPage + export const query = graphql` query { allFile(filter: { sourceInstanceName: { eq: "resources" } }) { diff --git a/src/pages/resources/index.tsx b/src/pages/resources/index.tsx index dc9413e..7badac6 100644 --- a/src/pages/resources/index.tsx +++ b/src/pages/resources/index.tsx @@ -18,7 +18,7 @@ function ResourcesPage() {

    This is meant as a small knowledge base for commonly answered questions on our Discord community,{" "} - The Programmer's Hangout. + The Programmer's Hangout.

    All of it is open source, and you can contribute to it on{" "} diff --git a/src/utils/index.ts b/src/utils/index.ts index 5a92dad..3e94d0c 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -146,7 +146,7 @@ export function buildToc(headings: Mdx["headings"]): ITocItem[] { return [] } - const strip = (value: string) => value.replace(/^(\d*\-)(.*)/, "$2") + const strip = (value: string) => value.replace(/^(\d*-)(.*)/, "$2") slugger.reset() diff --git a/tsconfig.json b/tsconfig.json index 3bcb642..493e832 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ // "incremental": true, /* Enable incremental compilation */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["ES2019"], /* Specify library files to be included in the compilation. */ + "lib": ["ES2019", "DOM"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */