From 872846dbeb2353e8d5870c3f58ae2f20dcc9b75d Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Sat, 15 Jan 2022 11:28:31 -0500 Subject: [PATCH] giscus comments! --- components/notes/Comments.tsx | 52 ++++++++++---------------------- components/notes/Meta.module.css | 2 +- giscus.json | 4 +++ lib/config.js | 15 ++++++--- package.json | 1 + pages/notes/[slug].tsx | 15 ++++++--- public/humans.txt | 2 +- yarn.lock | 29 +++++++++++++++++- 8 files changed, 73 insertions(+), 47 deletions(-) create mode 100644 giscus.json diff --git a/components/notes/Comments.tsx b/components/notes/Comments.tsx index eb8eb49e..18c773f1 100644 --- a/components/notes/Comments.tsx +++ b/components/notes/Comments.tsx @@ -1,49 +1,29 @@ -import { useRef, useEffect, useState } from "react"; import { useTheme } from "next-themes"; -import { githubRepo } from "../../lib/config"; +import { Giscus } from "@giscus/react"; +import { giscusConfig } from "../../lib/config"; +import type { GiscusProps } from "@giscus/react"; type Props = { - slug: string; + title: string; }; -const Comments = ({ slug }: Props) => { - const [injected, setInjected] = useState(false); - const scriptRef = useRef(null); +const Comments = ({ title }: Props) => { const { resolvedTheme } = useTheme(); - useEffect(() => { - // double check that we're ready for the script and it hasn't already been loaded - if (!scriptRef.current || injected) { - return; - } - - // NOTE: utterances script can't be loaded w/ next/script since the iframe appears literally where the script tag is - const utterances = document.createElement("script"); - utterances.src = "https://utteranc.es/client.js"; - utterances.async = true; - utterances.defer = true; - utterances.crossOrigin = "anonymous"; - - // https://utteranc.es/ - utterances.setAttribute("repo", githubRepo); - utterances.setAttribute("issue-term", `Comments on /notes/${slug}`); - utterances.setAttribute("theme", resolvedTheme === "dark" ? "github-dark" : "github-light"); - utterances.setAttribute("label", "💬 comments"); - - // add inside wrapper div (target for iframe) - scriptRef.current.appendChild(utterances); - setInjected(true); - - // cleanup - return () => utterances.remove(); - }, [resolvedTheme]); // eslint-disable-line react-hooks/exhaustive-deps - return (
+ style={{ marginTop: "2em", paddingTop: "1em", borderTop: "2px solid var(--light)", minHeight: "350px" }} + > + +
); }; diff --git a/components/notes/Meta.module.css b/components/notes/Meta.module.css index 453aab7d..75121732 100644 --- a/components/notes/Meta.module.css +++ b/components/notes/Meta.module.css @@ -21,7 +21,7 @@ .meta > div:last-of-type { /* fix potential layout shift when number of hits loads */ - min-width: 6em; + min-width: 6.5em; margin-right: 0; } diff --git a/giscus.json b/giscus.json new file mode 100644 index 00000000..dd92ee4b --- /dev/null +++ b/giscus.json @@ -0,0 +1,4 @@ +{ + "origins": ["https://jarv.is"], + "originsRegex": ["https://jarvis-git-([A-z0-9]|-)*jakejarvis\\.vercel\\.app"] +} diff --git a/lib/config.js b/lib/config.js index 6cac8639..4fa90fa5 100644 --- a/lib/config.js +++ b/lib/config.js @@ -9,6 +9,11 @@ module.exports = { shortDescription: "Front-End Web Developer in Boston, MA", longDescription: "Hi there! I'm a frontend web developer based in Boston, Massachusetts specializing in the JAMstack, modern JavaScript frameworks, and progressive web apps.", + themeColors: { + // used for ``, should be the same as CSS `--background-outer` var in styles/colors.css + light: "#fcfcfc", + dark: "#252525", + }, githubRepo: "jakejarvis/jarv.is", facebookAppId: "3357248167622283", verifyGoogle: "qQhmLTwjNWYgQ7W42nSTq63xIrTch13X_11mmxBE9zk", @@ -18,10 +23,12 @@ module.exports = { fathomSiteId: "WBGNQUKW", fathomCustomDomain: "https://blue-chilly.jarv.is", webmentionId: "jarv.is", - themeColors: { - // used for ``, should be the same as CSS `--background-outer` var in styles/colors.css - light: "#fcfcfc", - dark: "#252525", + giscusConfig: { + // https://github.com/giscus/giscus-component/tree/main/packages/react#readme + repo: "jakejarvis/jarv.is", + repoId: "MDEwOlJlcG9zaXRvcnk1MzM0MDgxMQ==", + category: "Comments", + categoryId: "DIC_kwDOAy3qi84CAsjS", }, // Me info diff --git a/package.json b/package.json index e867b5ad..da6e359f 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@fontsource/comic-neue": "4.5.0", "@fontsource/inter": "4.5.1", "@fontsource/roboto-mono": "4.5.0", + "@giscus/react": "^1.0.1", "@hcaptcha/react-hcaptcha": "^1.0.0", "@next/bundle-analyzer": "^12.0.8", "@octokit/graphql": "^4.8.0", diff --git a/pages/notes/[slug].tsx b/pages/notes/[slug].tsx index f8f020dc..38a55d88 100644 --- a/pages/notes/[slug].tsx +++ b/pages/notes/[slug].tsx @@ -6,21 +6,28 @@ import { escape } from "html-escaper"; import { getMDXComponent } from "mdx-bundler/client"; import Content from "../../components/Content"; import Meta from "../../components/notes/Meta"; +import Loading from "../../components/loading/Loading"; import CustomCode from "../../components/code-block/Code"; import { getNote, getNoteSlugs } from "../../lib/parse-notes"; import * as config from "../../lib/config"; import type { GetStaticProps, GetStaticPaths } from "next"; import type { NoteType } from "../../types"; -const Comments = dynamic(() => import("../../components/notes/Comments"), { ssr: false }); - const Note = ({ frontMatter, mdxSource }: NoteType) => { const MDXComponent = useMemo(() => getMDXComponent(mdxSource, { process }), [mdxSource]); const [commentsRef, commentsInView] = useInView({ - rootMargin: "100px", // start loading utteranc.es script 100px from end of content + rootMargin: "100px", // start loading comments script 100px from end of content triggerOnce: true, // don't unload one it's loaded (if user scrolls back up) fallbackInView: true, }); + const Comments = dynamic(() => import("../../components/notes/Comments"), { + ssr: false, + loading: () => ( +
+ +
+ ), + }); return ( <> @@ -66,7 +73,7 @@ const Note = ({ frontMatter, mdxSource }: NoteType) => { {frontMatter.noComments !== true && ( -
{commentsInView && }
+
{commentsInView && }
)} ); diff --git a/public/humans.txt b/public/humans.txt index 601c2775..6edcc52d 100644 --- a/public/humans.txt +++ b/public/humans.txt @@ -32,7 +32,7 @@ - Next.js - React - Vercel - - utteranc.es + - Giscus - Fathom Analytics - ...and more: https://jarv.is/uses/ diff --git a/yarn.lock b/yarn.lock index d1efc137..bbc37489 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1083,6 +1083,13 @@ resolved "https://registry.yarnpkg.com/@fontsource/roboto-mono/-/roboto-mono-4.5.0.tgz#27e44fbb1d86a9ef14501493a37eef1d73e60d02" integrity sha512-/6Gm6fJjBHZiFNyvzIKGJkVuyifoc1aoTel+pkzdhxNh7yNhFyokCoChdbbqZEpGKpqs5uld74G5TJthUVFyjw== +"@giscus/react@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@giscus/react/-/react-1.0.1.tgz#3fae2b5e00912a76cb136679f6229d3d6ea28898" + integrity sha512-vViRGjfmDy9xvRIx+6+hocL3iAipbKx4gxtSpQBzOksDwnZS0QbB+r19bYQ08vw8CfHRwE6ws8AOO9yEUrzUyQ== + dependencies: + iframe-resizer-react "^1.1.0" + "@hcaptcha/react-hcaptcha@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.0.0.tgz#53f6f2b21e0c206fc06cb157e6e02d82eb28945c" @@ -3771,6 +3778,19 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +iframe-resizer-react@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/iframe-resizer-react/-/iframe-resizer-react-1.1.0.tgz#5009e019b7a5c7f1c009bff5bcdf0dbf33557465" + integrity sha512-FrytSq91AIJaDgE+6uK/Vdd6IR8CrwLoZ6eGmL2qQMPTzF0xlSV2jaSzRRUh5V2fttD7vzl21jvBl97bV40eBw== + dependencies: + iframe-resizer "^4.3.0" + warning "^4.0.3" + +iframe-resizer@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/iframe-resizer/-/iframe-resizer-4.3.2.tgz#42dd88345d18b9e377b6044dddb98c664ab0ce6b" + integrity sha512-gOWo2hmdPjMQsQ+zTKbses08mDfDEMh4NneGQNP4qwePYujY1lguqP6gnbeJkf154gojWlBhIltlgnMfYjGHWA== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -4359,7 +4379,7 @@ longest-streak@^3.0.0: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.0.1.tgz#c97315b7afa0e7d9525db9a5a2953651432bdc5d" integrity sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg== -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7396,6 +7416,13 @@ vfile@^5.0.0: unist-util-stringify-position "^3.0.0" vfile-message "^3.0.0" +warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + web-namespaces@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"