feat: add support for giscus & utterances comments

This commit is contained in:
welpo
2023-07-12 18:44:28 +02:00
parent 93c8b577b8
commit 19d120019b
17 changed files with 333 additions and 99 deletions

81
static/js/giscus.js Normal file
View File

@@ -0,0 +1,81 @@
function setGiscusTheme(newTheme) {
// Get the giscus iframe.
const frame = document.querySelector('iframe.giscus-frame');
if (frame) {
// If the iframe exists, send a message to set the theme.
frame.contentWindow.postMessage(
{ giscus: { setConfig: { theme: newTheme } } },
'https://giscus.app'
);
}
}
// Function to initialize Giscus. This function is run when the window loads.
function initGiscus() {
// Get the div that will contain the comments.
const commentsDiv = document.querySelector('.comments');
if (commentsDiv) {
// Get the various settings from data attributes on the div.
const repo = commentsDiv.getAttribute('data-repo');
const repoId = commentsDiv.getAttribute('data-repo-id');
const category = commentsDiv.getAttribute('data-category');
const categoryId = commentsDiv.getAttribute('data-category-id');
const strictTitleMatching = commentsDiv.getAttribute('data-strict');
const term = commentsDiv.getAttribute('data-term');
const reactionsEnabled = commentsDiv.getAttribute('data-reactions-enabled');
const inputPosition = commentsDiv.getAttribute('data-input-position');
const lightTheme = commentsDiv.getAttribute('data-light-theme');
const darkTheme = commentsDiv.getAttribute('data-dark-theme');
const lang = commentsDiv.getAttribute('data-lang');
const lazyLoading = commentsDiv.getAttribute('data-lazy-loading');
// Create a new script tag that will load the Giscus script.
const script = document.createElement('script');
script.src = 'https://giscus.app/client.js';
script.async = true;
// Set the various settings as data attributes on the script tag.
script.setAttribute('data-repo', repo);
script.setAttribute('data-repo-id', repoId);
script.setAttribute('data-category', category);
script.setAttribute('data-category-id', categoryId);
script.setAttribute('data-term', term);
script.setAttribute('data-strict', strictTitleMatching);
script.setAttribute('data-reactions-enabled', reactionsEnabled);
script.setAttribute('data-emit-metadata', '0');
script.setAttribute('data-input-position', inputPosition);
script.setAttribute('data-lang', lang);
script.setAttribute('crossorigin', 'anonymous');
// Set the mapping if it is provided.
const mapping = commentsDiv.getAttribute('data-mapping');
if (mapping) {
script.setAttribute('data-mapping', mapping);
}
// Choose the correct theme based on the current theme of the document.
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
const selectedTheme = currentTheme === 'dark' ? darkTheme : lightTheme;
script.setAttribute('data-theme', selectedTheme);
// Set the loading attribute if lazy loading is enabled.
if (lazyLoading === 'true') {
script.setAttribute('data-loading', 'lazy');
}
// Add the script tag to the div.
commentsDiv.appendChild(script);
// Listen for theme changes and update the Giscus theme when they occur.
window.addEventListener('themeChanged', (event) => {
const selectedTheme = event.detail.theme === 'dark' ? darkTheme : lightTheme;
setGiscusTheme(selectedTheme);
});
}
}
// Initialize Giscus when the window loads.
window.addEventListener('load', () => {
initGiscus();
});

1
static/js/giscus_min.js Normal file
View File

@@ -0,0 +1 @@
function setGiscusTheme(t){var e=document.querySelector("iframe.giscus-frame");e&&e.contentWindow.postMessage({giscus:{setConfig:{theme:t}}},"https://giscus.app")}function initGiscus(){var t=document.querySelector(".comments");if(t){var e=t.getAttribute("data-repo"),a=t.getAttribute("data-repo-id"),i=t.getAttribute("data-category"),r=t.getAttribute("data-category-id"),d=t.getAttribute("data-strict"),s=t.getAttribute("data-term"),u=t.getAttribute("data-reactions-enabled"),n=t.getAttribute("data-input-position");const b=t.getAttribute("data-light-theme"),A=t.getAttribute("data-dark-theme");var o=t.getAttribute("data-lang"),c=t.getAttribute("data-lazy-loading"),g=document.createElement("script"),e=(g.src="https://giscus.app/client.js",g.async=!0,g.setAttribute("data-repo",e),g.setAttribute("data-repo-id",a),g.setAttribute("data-category",i),g.setAttribute("data-category-id",r),g.setAttribute("data-term",s),g.setAttribute("data-strict",d),g.setAttribute("data-reactions-enabled",u),g.setAttribute("data-emit-metadata","0"),g.setAttribute("data-input-position",n),g.setAttribute("data-lang",o),g.setAttribute("crossorigin","anonymous"),t.getAttribute("data-mapping")),a=(e&&g.setAttribute("data-mapping",e),document.documentElement.getAttribute("data-theme")||"light"),i="dark"===a?A:b;g.setAttribute("data-theme",i),"true"===c&&g.setAttribute("data-loading","lazy"),t.appendChild(g),window.addEventListener("themeChanged",t=>{setGiscusTheme("dark"===t.detail.theme?A:b)})}}window.addEventListener("load",()=>{initGiscus()});

View File

@@ -1,37 +0,0 @@
// Get the theme switcher button element.
const themeSwitcher = document.querySelector(".theme-switcher");
// Retrieve theme from localStorage.
let currentTheme = localStorage.getItem("theme");
// Function to switch between dark and light themes.
function switchTheme() {
// Set the new theme based on the current theme.
currentTheme = currentTheme === "dark" ? "light" : "dark";
document.documentElement.setAttribute("data-theme", currentTheme);
localStorage.setItem("theme", currentTheme);
// Send a message to the Utterances iframe to change its theme.
document.querySelectorAll(".utterances-frame").forEach((frame) => {
frame.contentWindow.postMessage(
{ type: 'set-theme', theme: `github-${currentTheme}` },
'*'
);
});
}
// Initialize the theme switcher button.
themeSwitcher.addEventListener("click", switchTheme, false);
// Update the theme based on system preference if the user hasn't manually changed the theme.
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
if (!localStorage.getItem("theme")) {
currentTheme = e.matches ? "dark" : "light";
document.documentElement.setAttribute("data-theme", currentTheme);
}
});
// Fix the theme switcher button not working on the first click by updating currentTheme.
if (!currentTheme) {
currentTheme = document.documentElement.getAttribute("data-theme");
}

View File

@@ -1 +0,0 @@
const themeSwitcher=document.querySelector(".theme-switcher");let currentTheme=localStorage.getItem("theme");function switchTheme(){currentTheme="dark"===currentTheme?"light":"dark",document.documentElement.setAttribute("data-theme",currentTheme),localStorage.setItem("theme",currentTheme),document.querySelectorAll(".utterances-frame").forEach(e=>{e.contentWindow.postMessage({type:"set-theme",theme:`github-${currentTheme}`},"*")})}themeSwitcher.addEventListener("click",switchTheme,!1),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{localStorage.getItem("theme")||(currentTheme=e.matches?"dark":"light",document.documentElement.setAttribute("data-theme",currentTheme))}),currentTheme||(currentTheme=document.documentElement.getAttribute("data-theme"));

View File

@@ -0,0 +1,33 @@
// Get the theme switcher button element.
const themeSwitcher = document.querySelector(".theme-switcher");
// Retrieve theme from localStorage.
let currentTheme = localStorage.getItem("theme");
// Function to switch between dark and light themes.
function setTheme(theme) {
document.documentElement.setAttribute("data-theme", theme);
localStorage.setItem("theme", theme);
// Dispatch a custom event for utterances and giscus.
const event = new CustomEvent("themeChanged", {
detail: { theme: theme }
});
window.dispatchEvent(event);
}
function switchTheme() {
// Set the new theme based on the current theme.
const newTheme = currentTheme === "dark" ? "light" : "dark";
setTheme(newTheme);
}
themeSwitcher.addEventListener("click", switchTheme, false);
// Update the theme based on system preference if the user hasn't manually changed the theme.
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
if (!localStorage.getItem("theme")) {
const newTheme = e.matches ? "dark" : "light";
setTheme(newTheme);
}
});

View File

@@ -0,0 +1,37 @@
// Get the theme switcher button element.
const themeSwitcher = document.querySelector(".theme-switcher");
// Retrieve theme from localStorage.
let currentTheme = localStorage.getItem("theme");
// Function to set theme
function setTheme(theme, saveToLocalStorage = false) {
document.documentElement.setAttribute("data-theme", theme);
currentTheme = theme;
if (saveToLocalStorage) {
localStorage.setItem("theme", theme);
}
// Dispatch a custom event for utterances and giscus.
const event = new CustomEvent("themeChanged", {
detail: { theme: theme }
});
window.dispatchEvent(event);
}
// Function to switch between dark and light themes.
function switchTheme() {
// Set the new theme based on the current theme.
const newTheme = currentTheme === "dark" ? "light" : "dark";
setTheme(newTheme, true); // Save the theme to localStorage when the user changes it.
}
// Initialize the theme switcher button.
themeSwitcher.addEventListener("click", switchTheme, false);
// Update the theme based on system preference if the user hasn't manually changed the theme.
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
const newTheme = e.matches ? "dark" : "light";
setTheme(newTheme);
});

64
static/js/utterances.js Normal file
View File

@@ -0,0 +1,64 @@
function setUtterancesTheme(newTheme) {
// Get the frame with class "utterances-frame".
const frame = document.querySelector(".utterances-frame");
if (frame) {
// If the iframe exists, send a message to set the theme.
frame.contentWindow.postMessage(
{ type: 'set-theme', theme: newTheme },
'https://utteranc.es'
);
}
}
function initUtterances() {
// Get the comments div.
const commentsDiv = document.querySelector('.comments');
// Check if the comments div exists.
if (commentsDiv) {
// Get all necessary attributes for initializing Utterances.
const repo = commentsDiv.getAttribute('data-repo');
const issueTerm = commentsDiv.getAttribute('data-issue-term');
const label = commentsDiv.getAttribute('data-label');
const lightTheme = commentsDiv.getAttribute('data-light-theme');
const darkTheme = commentsDiv.getAttribute('data-dark-theme');
const lazyLoading = commentsDiv.getAttribute('data-lazy-loading');
// Create a new script element.
const script = document.createElement('script');
script.src = 'https://utteranc.es/client.js';
script.async = true;
script.setAttribute('repo', repo);
script.setAttribute('issue-term', issueTerm);
script.setAttribute('label', label);
// Set the initial theme.
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
const selectedTheme = currentTheme === 'dark' ? darkTheme : lightTheme;
script.setAttribute('theme', selectedTheme);
script.setAttribute('crossorigin', 'anonymous');
// Enable lazy loading if specified.
if (lazyLoading === 'true') {
script.setAttribute('data-loading', 'lazy');
}
// Append the script to the comments div.
commentsDiv.appendChild(script);
// Listen for themeChanged event to update the theme.
window.addEventListener('themeChanged', (event) => {
// Determine the new theme based on the event detail.
const selectedTheme = event.detail.theme === 'dark' ? darkTheme : lightTheme;
// Set the new theme.
setUtterancesTheme(selectedTheme);
});
}
}
// Initialize Utterances once the window has loaded.
window.addEventListener('load', () => {
initUtterances();
});

View File

@@ -0,0 +1 @@
function setUtterancesTheme(t){const e=document.querySelector(".utterances-frame");e&&e.contentWindow.postMessage({type:"set-theme",theme:t},"https://utteranc.es")}function initUtterances(){const t=document.querySelector(".comments");if(t){var e=t.getAttribute("data-repo"),a=t.getAttribute("data-issue-term"),r=t.getAttribute("data-label");const s=t.getAttribute("data-light-theme"),d=t.getAttribute("data-dark-theme");var n=t.getAttribute("data-lazy-loading"),i=document.createElement("script"),e=(i.src="https://utteranc.es/client.js",i.async=!0,i.setAttribute("repo",e),i.setAttribute("issue-term",a),i.setAttribute("label",r),document.documentElement.getAttribute("data-theme")||"light"),a="dark"===e?d:s;i.setAttribute("theme",a),i.setAttribute("crossorigin","anonymous"),"true"===n&&i.setAttribute("data-loading","lazy"),t.appendChild(i),window.addEventListener("themeChanged",t=>{setUtterancesTheme("dark"===t.detail.theme?d:s)})}}window.addEventListener("load",()=>{initUtterances()});