From dd7da72272fc1cf321c7e461077ca92004e49fb3 Mon Sep 17 00:00:00 2001 From: Sivert Date: Mon, 30 Oct 2023 23:18:46 +0100 Subject: [PATCH] Fix theme switch --- components/Comments.tsx | 34 ++++++++++++---------- components/ThemeWrapper.tsx | 33 ++++++++-------------- components/useScript.tsx | 54 +---------------------------------- package.json | 3 +- pages/_document.tsx | 2 +- pages/posts/[slug].tsx | 21 ++++++++------ utils/useTheme.ts | 33 ++++++++++++++++++++++ yarn.lock | 56 +++++++++++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 99 deletions(-) create mode 100644 utils/useTheme.ts diff --git a/components/Comments.tsx b/components/Comments.tsx index 089caab..5ae1bad 100644 --- a/components/Comments.tsx +++ b/components/Comments.tsx @@ -1,20 +1,24 @@ -import React, { useRef } from "react"; +import React, { useContext } from "react"; +import Giscus from '@giscus/react' +import { ThemeContext } from "./ThemeWrapper"; -import useScript from "./useScript"; +const Comments = () => { + const theme = useContext(ThemeContext); -const Comments = ({ ...props }) => { - const comment = useRef(null); - - useScript({ - url: "https://giscus.app/client.js", - ref: comment, - theme: "noborder_light", - }); - - return ( -
- {
} -
+ return ( ); }; diff --git a/components/ThemeWrapper.tsx b/components/ThemeWrapper.tsx index 3efd5c9..85225b5 100644 --- a/components/ThemeWrapper.tsx +++ b/components/ThemeWrapper.tsx @@ -1,24 +1,20 @@ -import React, { useEffect, useState } from "react"; -import Head from 'next/head' +import React, { useEffect } from "react"; +import Head from "next/head"; import { FaMoon, FaSun } from "react-icons/fa"; import colors from "../tailwind.config"; +import { useTheme } from "utils/useTheme"; + +export const ThemeContext = React.createContext(undefined) export default function ThemeWrapper({ children }) { - const [theme, settheme] = useState<"sivert_dark" | "sivert_light">( - "sivert_dark" - ); - useEffect(() => { - const localTheme = localStorage.getItem("theme"); - if (localTheme) settheme(localTheme as typeof theme); - else localStorage.setItem("theme", 'sivert_dark') - }, []); + const { theme, toggleTheme } = useTheme() useEffect(() => { - if (theme) - localStorage.setItem("theme", theme); - }, [theme]); + document.getElementsByTagName('html')[0].setAttribute('data-theme', theme) + }, [theme]) + return ( - <> + -
{children} -
- +
); } diff --git a/components/useScript.tsx b/components/useScript.tsx index 68a94e7..ae6f429 100644 --- a/components/useScript.tsx +++ b/components/useScript.tsx @@ -1,58 +1,6 @@ import { useEffect, useState } from "react"; -// we need a function that accepts the script src and couple of other parameters - -const useScript = (params) => { - const { url, theme, issueTerm, repo, ref } = params; - - const [status, setStatus] = useState(url ? "loading" : "idle"); - - // run the useEffect when the url of the script changes - useEffect(() => { - if (!url) { - setStatus("idle"); - return; - } - // assuming there are no existing script and creating a new script - - let script = document.createElement("script"); - script.src = url; - script.async = true; - script.crossOrigin = "anonymous"; - script.setAttribute("data-theme", theme); - script.setAttribute("data-input-position", "top"); - script.setAttribute("data-emit-metadata", "0"); - script.setAttribute("data-reactions-enabled", "1"); - script.setAttribute("data-category-id", "DIC_kwDOJFDxMc4CUxCa"); - script.setAttribute("data-category", "Announcements"); - script.setAttribute("data-repo-id", "R_kgDOJFDxMQ"); - script.setAttribute("data-repo", "SivertGullbergHansen/blog.sivert.io"); - script.setAttribute("data-strict", "0"); - script.setAttribute("data-loading", "lazy"); - script.setAttribute("data-lang", "en"); - script.setAttribute("data-mapping", "pathname"); - - // Add script to document body - ref.current.appendChild(script); - - // store status of the script - - const setAttributeStatus = (event) => { - setStatus(event.type === "load" ? "ready" : "error"); - }; - - script.addEventListener("load", setAttributeStatus); - script.addEventListener("error", setAttributeStatus); - - return () => { - // useEffect clean up - if (script) { - script.removeEventListener("load", setAttributeStatus); - script.removeEventListener("error", setAttributeStatus); - } - }; - }, [url]); - return status; +const useScript = () => { }; export default useScript; diff --git a/package.json b/package.json index 529312e..f69264b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "start": "next start" }, "dependencies": { + "@giscus/react": "^2.3.0", "@tailwindcss/line-clamp": "^0.4.2", "contentlayer": "latest", "daisyui": "^2.51.3", @@ -44,4 +45,4 @@ "tailwindcss": "^3.2.6", "typescript": "4.9.5" } -} \ No newline at end of file +} diff --git a/pages/_document.tsx b/pages/_document.tsx index 24aa30b..e811e0f 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -4,7 +4,7 @@ export default function Document() { return ( diff --git a/pages/posts/[slug].tsx b/pages/posts/[slug].tsx index 695d16b..584cb85 100644 --- a/pages/posts/[slug].tsx +++ b/pages/posts/[slug].tsx @@ -8,14 +8,14 @@ import { transition, } from "config/animations"; import StaggerWrapper from "components/StaggerWrapper"; -import React, { useState } from "react"; +import React, { useEffect, useInsertionEffect, useRef, useState } from "react"; import { Components } from "components/MdxConvertedComponents"; import { ImageWithFallback } from "components/ImageWithFallback"; -import { Comments } from "components/Comments"; import { HeadMetaGenerator } from "components/HeadMetaGenerator"; import { FaArrowUp } from "react-icons/fa"; import { motion, useMotionValueEvent, useScroll } from "framer-motion"; import Link from "next/link"; +import { Comments } from "components/Comments"; export async function getStaticPaths() { const paths = allPosts @@ -32,7 +32,7 @@ export async function getStaticProps({ params }) { const post: Post = allPosts.find( (post) => post._raw.flattenedPath === params.slug ); - + return { props: { post, @@ -44,9 +44,10 @@ const PostLayout = ({ post }: { post: Post }) => { const MDXContent = useMDXComponent(post.body.code); const [isOpen, setIsOpen] = useState(false); const scroll = useScroll(); - useMotionValueEvent(scroll.scrollY, "change", (latest) => - setIsOpen(latest > 360) - ); + useMotionValueEvent(scroll.scrollY, "change", (latest) => { + setIsOpen(latest > 360); + }); + const ImageAuthor = () => { const style = "font-medium text-base-content opacity-75 text-sm"; @@ -54,7 +55,11 @@ const PostLayout = ({ post }: { post: Post }) => {

Credit:{" "} {post.imageCreditsLink ? ( - + {post.imageCredits} ) : ( @@ -129,7 +134,7 @@ const PostLayout = ({ post }: { post: Post }) => {

- {post.allowComments ? : null} + {post.allowComments ? : null} diff --git a/utils/useTheme.ts b/utils/useTheme.ts new file mode 100644 index 0000000..f64fb32 --- /dev/null +++ b/utils/useTheme.ts @@ -0,0 +1,33 @@ +// theme.js +import { useEffect, useState } from "react"; +import colors from "../tailwind.config"; + +export const useTheme = () => { + const [theme, setTheme] = useState<"sivert_dark" | "sivert_light">(null); + + useEffect(() => { + const localTheme = localStorage.getItem("theme"); + if (localTheme) setTheme(localTheme as typeof theme); + else localStorage.setItem("theme", "sivert_dark"); + }, []); + + useEffect(() => { + if (theme) { + localStorage.setItem("theme", theme); + } + }, [theme]); + + const toggleTheme = () => { + setTheme((currentTheme) => + currentTheme === "sivert_dark" ? "sivert_light" : "sivert_dark" + ); + }; + + return { theme, toggleTheme }; +}; + +export const getThemeColor = (theme) => { + return theme === "sivert_dark" + ? colors.daisyui.themes[0].sivert_dark["base-100"] + : colors.daisyui.themes[0].sivert_light["base-100"]; +}; diff --git a/yarn.lock b/yarn.lock index 7724a9d..b6dc860 100644 --- a/yarn.lock +++ b/yarn.lock @@ -263,6 +263,13 @@ resolved "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz" integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== +"@giscus/react@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@giscus/react/-/react-2.3.0.tgz#1c13f2f96bb67684d4f5288dc1ed3155ff307ce4" + integrity sha512-tj79B+NNBfidhPdXJqWoqRm5Jhoc6CBhXMYwBR9nwTwsrdaB/spcQXmHpKcUuOdXZtlYSwMfCFcBogMNbD+gKQ== + dependencies: + giscus "^1.3.0" + "@grpc/grpc-js@^1.5.9": version "1.8.11" resolved "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.11.tgz" @@ -301,6 +308,18 @@ jsbi "^4.1.0" tslib "^2.3.1" +"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.2.tgz#d693d972974a354034454ec1317eb6afd0b00312" + integrity sha512-jnOD+/+dSrfTWYfSXBXlo5l5f0q1UuJo3tkbMDCYA2lKUYq79jaxqtGEvnRoh049nt1vdo1+45RinipU6FGY2g== + +"@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.6.0": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.3.tgz#25b4eece2592132845d303e091bad9b04cdcfe03" + integrity sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.0.0" + "@mdx-js/esbuild@^2.0.0": version "2.3.0" resolved "https://registry.npmjs.org/@mdx-js/esbuild/-/esbuild-2.3.0.tgz" @@ -726,6 +745,11 @@ resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/trusted-types@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.5.tgz#5cac7e7df3275bb95f79594f192d97da3b4fd5fe" + integrity sha512-I3pkr8j/6tmQtKV/ZzHtuaqYSQvyjGRKH4go60Rr0IDLlFxuRT5V32uvB1mecM5G1EVAUyF/4r4QZ1GHgz+mxA== + "@types/unist@*", "@types/unist@^2.0.0": version "2.0.6" resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" @@ -1366,6 +1390,13 @@ get-caller-file@^2.0.5: resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +giscus@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/giscus/-/giscus-1.3.0.tgz#b413e6e39b7c3aa96c2d2838df99bbf75fd4709d" + integrity sha512-A3tVLgSmpnh2sX9uGjo9MbzmTTEJirSyFUPRvkipvy37y9rhxUYDoh9kO37QVrP7Sc7QuJ+gihB6apkO0yDyTw== + dependencies: + lit "^2.7.5" + github-from-package@0.0.0: version "0.0.0" resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" @@ -1754,6 +1785,31 @@ lilconfig@^2.0.5, lilconfig@^2.0.6: resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== +lit-element@^3.3.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.3.tgz#10bc19702b96ef5416cf7a70177255bfb17b3209" + integrity sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.1.0" + "@lit/reactive-element" "^1.3.0" + lit-html "^2.8.0" + +lit-html@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.8.0.tgz#96456a4bb4ee717b9a7d2f94562a16509d39bffa" + integrity sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q== + dependencies: + "@types/trusted-types" "^2.0.2" + +lit@^2.7.5: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit/-/lit-2.8.0.tgz#4d838ae03059bf9cafa06e5c61d8acc0081e974e" + integrity sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA== + dependencies: + "@lit/reactive-element" "^1.6.0" + lit-element "^3.3.0" + lit-html "^2.8.0" + lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz"