Skip to content

Commit

Permalink
feat: add disqus and commento comments providers
Browse files Browse the repository at this point in the history
  • Loading branch information
dynamotn committed Oct 13, 2024
1 parent c5d97db commit 1d58d69
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 33 deletions.
3 changes: 3 additions & 0 deletions quartz.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ const config: QuartzConfig = {
},
},
},
comments: {
provider: "commento",
},
},
plugins: {
transformers: [
Expand Down
27 changes: 27 additions & 0 deletions quartz/cfg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@ export type Analytics =
projectId?: string
}

export type Comments =
| null
| {
provider: "giscus"
repo: `${string}/${string}`
repoId: string
category: string
categoryId: string
mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
strict?: boolean
reactionsEnabled?: boolean
inputPosition?: "top" | "bottom"
}
| {
provider: "commento"
host?: string
cssOverride?: string
noFonts?: boolean
hideDeleted?: boolean
}
| {
provider: "disqus"
shortName: string
}

export interface GlobalConfiguration {
pageTitle: string
pageTitleSuffix?: string
Expand All @@ -56,6 +81,8 @@ export interface GlobalConfiguration {
ignorePatterns: string[]
/** Whether to use created, modified, or published as the default type of date */
defaultDateType: ValidDateType
/** Comments for page */
comments: Comments
/** Base URL to use for CNAME files, sitemaps, and RSS feeds that require an absolute URL.
* Quartz will avoid using this as much as possible and use relative URLs most of the time
*/
Expand Down
69 changes: 40 additions & 29 deletions quartz/components/Comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,53 @@ import { classNames } from "../util/lang"
// @ts-ignore
import script from "./scripts/comments.inline"

type Options = {
provider: "giscus"
options: {
repo: `${string}/${string}`
repoId: string
category: string
categoryId: string
mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
strict?: boolean
reactionsEnabled?: boolean
inputPosition?: "top" | "bottom"
}
}

function boolToStringBool(b: boolean): string {
return b ? "1" : "0"
}

export default ((opts: Options) => {
export default (() => {
const Comments: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => {
return (
<div
class={classNames(displayClass, "giscus")}
data-repo={opts.options.repo}
data-repo-id={opts.options.repoId}
data-category={opts.options.category}
data-category-id={opts.options.categoryId}
data-mapping={opts.options.mapping ?? "url"}
data-strict={boolToStringBool(opts.options.strict ?? true)}
data-reactions-enabled={boolToStringBool(opts.options.reactionsEnabled ?? true)}
data-input-position={opts.options.inputPosition ?? "bottom"}
></div>
)
switch (cfg.comments?.provider) {
case "giscus":
return (
<div id="comment" data-provider={cfg.comments.provider}>
<div
class={classNames(displayClass, "giscus")}
data-repo={cfg.comments?.repo}
data-repo-id={cfg.comments?.repoId}
data-category={cfg.comments?.category}
data-category-id={cfg.comments?.categoryId}
data-mapping={cfg.comments?.mapping ?? "url"}
data-strict={boolToStringBool(cfg.comments?.strict ?? true)}
data-reactions-enabled={boolToStringBool(cfg.comments?.reactionsEnabled ?? true)}
data-input-position={cfg.comments?.inputPosition ?? "bottom"}
></div>
</div>
)
case "commento":
return (
<div id="comment" data-provider={cfg.comments.provider}>
<div
id="commento"
data-host={cfg.comments?.host ?? "cdn.commento.io"}
data-css-override={cfg.comments?.cssOverride ?? ""}
data-no-fonts={cfg.comments?.noFonts ?? true}
data-hide-deleted={cfg.comments?.hideDeleted ?? false}
></div>
</div>
)
case "disqus":
return (
<div id="comment" data-provider={cfg.comments.provider}>
<div id="disqus_thread" data-short-name={cfg.comments?.shortName}></div>
</div>
)
default:
return <></>
}
}

Comments.afterDOMLoaded = script

return Comments
}) satisfies QuartzComponentConstructor<Options>
}) satisfies QuartzComponentConstructor
68 changes: 64 additions & 4 deletions quartz/components/scripts/comments.inline.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const changeTheme = (e: CustomEventMap["themechange"]) => {
const changeGiscusTheme = (e: CustomEventMap["themechange"]) => {
const theme = e.detail.theme
const iframe = document.querySelector("iframe.giscus-frame") as HTMLIFrameElement
if (!iframe) {
Expand Down Expand Up @@ -34,7 +34,7 @@ type GiscusElement = Omit<HTMLElement, "dataset"> & {
}
}

document.addEventListener("nav", () => {
function setupGiscus() {
const giscusContainer = document.querySelector(".giscus") as GiscusElement
if (!giscusContainer) {
return
Expand Down Expand Up @@ -62,6 +62,66 @@ document.addEventListener("nav", () => {

giscusContainer.appendChild(giscusScript)

document.addEventListener("themechange", changeTheme)
window.addCleanup(() => document.removeEventListener("themechange", changeTheme))
document.addEventListener("themechange", changeGiscusTheme)
window.addCleanup(() => document.removeEventListener("themechange", changeGiscusTheme))
}

type CommentoElement = Omit<HTMLElement, "dataset"> & {
dataset: DOMStringMap & {
host: string
cssOverride: string
noFonts: string
hideDeleted: string
}
}

function setupCommento() {
const commentoContainer = document.querySelector("#commento") as CommentoElement
if (!commentoContainer) {
return
}

const commentoScript = document.createElement("script")
commentoScript.src = "https://" + commentoContainer.dataset.host + "/js/commento.js"
commentoScript.defer = true
commentoScript.setAttribute("data-css-override", commentoContainer.dataset.cssOverride)
commentoScript.setAttribute("data-no-fonts", commentoContainer.dataset.noFonts)
commentoScript.setAttribute("data-hide-deleted", commentoContainer.dataset.hideDeleted)

commentoContainer.appendChild(commentoScript)
}

type DisqusElement = Omit<HTMLElement, "dataset"> & {
dataset: DOMStringMap & {
shortName: string
}
}

function setupDisqus() {
const disqusContainer = document.querySelector("#disqus_thread") as DisqusElement
if (!disqusContainer) {
return
}

const disqusScript = document.createElement("script")
disqusScript.src = "https://" + disqusContainer.dataset.shortName + ".disqus.com/embed.js"
disqusScript.setAttribute("data-timestamp", "" + +new Date())

disqusContainer.appendChild(disqusScript)
}

document.addEventListener("nav", () => {
const commentContainer = document.querySelector("#comment")
if (!commentContainer) {
return
}
const provider = commentContainer.getAttribute("data-provider")
switch (provider) {
case "giscus":
setupGiscus()
case "commento":
setupCommento()
case "disqus":
setupDisqus()
}
})

0 comments on commit 1d58d69

Please sign in to comment.