mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-28 08:50:28 -04:00
giscus comments!
This commit is contained in:
parent
6d7ffee7ea
commit
872846dbeb
@ -1,49 +1,29 @@
|
|||||||
import { useRef, useEffect, useState } from "react";
|
|
||||||
import { useTheme } from "next-themes";
|
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 = {
|
type Props = {
|
||||||
slug: string;
|
title: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Comments = ({ slug }: Props) => {
|
const Comments = ({ title }: Props) => {
|
||||||
const [injected, setInjected] = useState(false);
|
|
||||||
const scriptRef = useRef<HTMLDivElement>(null);
|
|
||||||
const { resolvedTheme } = useTheme();
|
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 (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={scriptRef}
|
|
||||||
id="comments"
|
id="comments"
|
||||||
style={{ marginTop: "2em", paddingTop: "1em", borderTop: "2px solid var(--light)" }}
|
style={{ marginTop: "2em", paddingTop: "1em", borderTop: "2px solid var(--light)", minHeight: "350px" }}
|
||||||
|
>
|
||||||
|
<Giscus
|
||||||
|
{...(giscusConfig as GiscusProps)}
|
||||||
|
term={title}
|
||||||
|
mapping="specific"
|
||||||
|
reactionsEnabled="1"
|
||||||
|
emitMetadata="0"
|
||||||
|
theme={resolvedTheme === "dark" ? "dark" : "light"}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
.meta > div:last-of-type {
|
.meta > div:last-of-type {
|
||||||
/* fix potential layout shift when number of hits loads */
|
/* fix potential layout shift when number of hits loads */
|
||||||
min-width: 6em;
|
min-width: 6.5em;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
giscus.json
Normal file
4
giscus.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"origins": ["https://jarv.is"],
|
||||||
|
"originsRegex": ["https://jarvis-git-([A-z0-9]|-)*jakejarvis\\.vercel\\.app"]
|
||||||
|
}
|
@ -9,6 +9,11 @@ module.exports = {
|
|||||||
shortDescription: "Front-End Web Developer in Boston, MA",
|
shortDescription: "Front-End Web Developer in Boston, MA",
|
||||||
longDescription:
|
longDescription:
|
||||||
"Hi there! I'm a frontend web developer based in Boston, Massachusetts specializing in the JAMstack, modern JavaScript frameworks, and progressive web apps.",
|
"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 `<meta name="theme-color" ...>`, should be the same as CSS `--background-outer` var in styles/colors.css
|
||||||
|
light: "#fcfcfc",
|
||||||
|
dark: "#252525",
|
||||||
|
},
|
||||||
githubRepo: "jakejarvis/jarv.is",
|
githubRepo: "jakejarvis/jarv.is",
|
||||||
facebookAppId: "3357248167622283",
|
facebookAppId: "3357248167622283",
|
||||||
verifyGoogle: "qQhmLTwjNWYgQ7W42nSTq63xIrTch13X_11mmxBE9zk",
|
verifyGoogle: "qQhmLTwjNWYgQ7W42nSTq63xIrTch13X_11mmxBE9zk",
|
||||||
@ -18,10 +23,12 @@ module.exports = {
|
|||||||
fathomSiteId: "WBGNQUKW",
|
fathomSiteId: "WBGNQUKW",
|
||||||
fathomCustomDomain: "https://blue-chilly.jarv.is",
|
fathomCustomDomain: "https://blue-chilly.jarv.is",
|
||||||
webmentionId: "jarv.is",
|
webmentionId: "jarv.is",
|
||||||
themeColors: {
|
giscusConfig: {
|
||||||
// used for `<meta name="theme-color" ...>`, should be the same as CSS `--background-outer` var in styles/colors.css
|
// https://github.com/giscus/giscus-component/tree/main/packages/react#readme
|
||||||
light: "#fcfcfc",
|
repo: "jakejarvis/jarv.is",
|
||||||
dark: "#252525",
|
repoId: "MDEwOlJlcG9zaXRvcnk1MzM0MDgxMQ==",
|
||||||
|
category: "Comments",
|
||||||
|
categoryId: "DIC_kwDOAy3qi84CAsjS",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Me info
|
// Me info
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
"@fontsource/comic-neue": "4.5.0",
|
"@fontsource/comic-neue": "4.5.0",
|
||||||
"@fontsource/inter": "4.5.1",
|
"@fontsource/inter": "4.5.1",
|
||||||
"@fontsource/roboto-mono": "4.5.0",
|
"@fontsource/roboto-mono": "4.5.0",
|
||||||
|
"@giscus/react": "^1.0.1",
|
||||||
"@hcaptcha/react-hcaptcha": "^1.0.0",
|
"@hcaptcha/react-hcaptcha": "^1.0.0",
|
||||||
"@next/bundle-analyzer": "^12.0.8",
|
"@next/bundle-analyzer": "^12.0.8",
|
||||||
"@octokit/graphql": "^4.8.0",
|
"@octokit/graphql": "^4.8.0",
|
||||||
|
@ -6,21 +6,28 @@ import { escape } from "html-escaper";
|
|||||||
import { getMDXComponent } from "mdx-bundler/client";
|
import { getMDXComponent } from "mdx-bundler/client";
|
||||||
import Content from "../../components/Content";
|
import Content from "../../components/Content";
|
||||||
import Meta from "../../components/notes/Meta";
|
import Meta from "../../components/notes/Meta";
|
||||||
|
import Loading from "../../components/loading/Loading";
|
||||||
import CustomCode from "../../components/code-block/Code";
|
import CustomCode from "../../components/code-block/Code";
|
||||||
import { getNote, getNoteSlugs } from "../../lib/parse-notes";
|
import { getNote, getNoteSlugs } from "../../lib/parse-notes";
|
||||||
import * as config from "../../lib/config";
|
import * as config from "../../lib/config";
|
||||||
import type { GetStaticProps, GetStaticPaths } from "next";
|
import type { GetStaticProps, GetStaticPaths } from "next";
|
||||||
import type { NoteType } from "../../types";
|
import type { NoteType } from "../../types";
|
||||||
|
|
||||||
const Comments = dynamic(() => import("../../components/notes/Comments"), { ssr: false });
|
|
||||||
|
|
||||||
const Note = ({ frontMatter, mdxSource }: NoteType) => {
|
const Note = ({ frontMatter, mdxSource }: NoteType) => {
|
||||||
const MDXComponent = useMemo(() => getMDXComponent(mdxSource, { process }), [mdxSource]);
|
const MDXComponent = useMemo(() => getMDXComponent(mdxSource, { process }), [mdxSource]);
|
||||||
const [commentsRef, commentsInView] = useInView({
|
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)
|
triggerOnce: true, // don't unload one it's loaded (if user scrolls back up)
|
||||||
fallbackInView: true,
|
fallbackInView: true,
|
||||||
});
|
});
|
||||||
|
const Comments = dynamic(() => import("../../components/notes/Comments"), {
|
||||||
|
ssr: false,
|
||||||
|
loading: () => (
|
||||||
|
<div style={{ display: "block", margin: "5em auto 3.5em auto", textAlign: "center" }}>
|
||||||
|
<Loading boxes={3} width={50} />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -66,7 +73,7 @@ const Note = ({ frontMatter, mdxSource }: NoteType) => {
|
|||||||
<MDXComponent components={{ code: CustomCode }} />
|
<MDXComponent components={{ code: CustomCode }} />
|
||||||
</Content>
|
</Content>
|
||||||
{frontMatter.noComments !== true && (
|
{frontMatter.noComments !== true && (
|
||||||
<div ref={commentsRef}>{commentsInView && <Comments slug={frontMatter.slug} />}</div>
|
<div ref={commentsRef}>{commentsInView && <Comments title={frontMatter.title} />}</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
- Next.js
|
- Next.js
|
||||||
- React
|
- React
|
||||||
- Vercel
|
- Vercel
|
||||||
- utteranc.es
|
- Giscus
|
||||||
- Fathom Analytics
|
- Fathom Analytics
|
||||||
- ...and more: https://jarv.is/uses/
|
- ...and more: https://jarv.is/uses/
|
||||||
|
|
||||||
|
29
yarn.lock
29
yarn.lock
@ -1083,6 +1083,13 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@fontsource/roboto-mono/-/roboto-mono-4.5.0.tgz#27e44fbb1d86a9ef14501493a37eef1d73e60d02"
|
resolved "https://registry.yarnpkg.com/@fontsource/roboto-mono/-/roboto-mono-4.5.0.tgz#27e44fbb1d86a9ef14501493a37eef1d73e60d02"
|
||||||
integrity sha512-/6Gm6fJjBHZiFNyvzIKGJkVuyifoc1aoTel+pkzdhxNh7yNhFyokCoChdbbqZEpGKpqs5uld74G5TJthUVFyjw==
|
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":
|
"@hcaptcha/react-hcaptcha@^1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.0.0.tgz#53f6f2b21e0c206fc06cb157e6e02d82eb28945c"
|
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"
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
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:
|
ignore@^4.0.6:
|
||||||
version "4.0.6"
|
version "4.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
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"
|
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.0.1.tgz#c97315b7afa0e7d9525db9a5a2953651432bdc5d"
|
||||||
integrity sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==
|
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"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||||
@ -7396,6 +7416,13 @@ vfile@^5.0.0:
|
|||||||
unist-util-stringify-position "^3.0.0"
|
unist-util-stringify-position "^3.0.0"
|
||||||
vfile-message "^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:
|
web-namespaces@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
|
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user