From 363f51ab51ae4ee834b6ce39436332f39f820cce Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Tue, 19 Nov 2024 20:38:07 -0800 Subject: [PATCH] refresh theme without reloading page --- frontend/src/LogoContext.jsx | 39 +++++++++++++++++++--------------- frontend/src/hooks/useTheme.js | 17 +++++++++------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/frontend/src/LogoContext.jsx b/frontend/src/LogoContext.jsx index 8d4ff82dd0..3bf499da76 100644 --- a/frontend/src/LogoContext.jsx +++ b/frontend/src/LogoContext.jsx @@ -5,6 +5,7 @@ import DefaultLoginLogoLight from "./media/illustrations/login-logo.svg"; import DefaultLoginLogoDark from "./media/illustrations/login-logo-light.svg"; import System from "./models/system"; +export const REFETCH_LOGO_EVENT = "refetch-logo"; export const LogoContext = createContext(); export function LogoProvider({ children }) { @@ -16,32 +17,36 @@ export function LogoProvider({ children }) { ? DefaultLoginLogoDark : DefaultLoginLogoLight; - useEffect(() => { - async function fetchInstanceLogo() { - try { - const { isCustomLogo, logoURL } = await System.fetchLogo(); - if (logoURL) { - setLogo(logoURL); - setLoginLogo(isCustomLogo ? logoURL : DefaultLoginLogo); - setIsCustomLogo(isCustomLogo); - } else { - localStorage.getItem("theme") !== "default" - ? setLogo(AnythingLLMDark) - : setLogo(AnythingLLM); - setLoginLogo(DefaultLoginLogo); - setIsCustomLogo(false); - } - } catch (err) { + async function fetchInstanceLogo() { + try { + const { isCustomLogo, logoURL } = await System.fetchLogo(); + if (logoURL) { + setLogo(logoURL); + setLoginLogo(isCustomLogo ? logoURL : DefaultLoginLogo); + setIsCustomLogo(isCustomLogo); + } else { localStorage.getItem("theme") !== "default" ? setLogo(AnythingLLMDark) : setLogo(AnythingLLM); setLoginLogo(DefaultLoginLogo); setIsCustomLogo(false); - console.error("Failed to fetch logo:", err); } + } catch (err) { + localStorage.getItem("theme") !== "default" + ? setLogo(AnythingLLMDark) + : setLogo(AnythingLLM); + setLoginLogo(DefaultLoginLogo); + setIsCustomLogo(false); + console.error("Failed to fetch logo:", err); } + } + useEffect(() => { fetchInstanceLogo(); + window.addEventListener(REFETCH_LOGO_EVENT, fetchInstanceLogo); + return () => { + window.removeEventListener(REFETCH_LOGO_EVENT, fetchInstanceLogo); + }; }, []); return ( diff --git a/frontend/src/hooks/useTheme.js b/frontend/src/hooks/useTheme.js index d56488e3d5..0ebb9c877d 100644 --- a/frontend/src/hooks/useTheme.js +++ b/frontend/src/hooks/useTheme.js @@ -1,3 +1,4 @@ +import { REFETCH_LOGO_EVENT } from "@/LogoContext"; import { useState, useEffect } from "react"; const availableThemes = { @@ -26,6 +27,7 @@ export function useTheme() { document.documentElement.setAttribute("data-theme", theme); document.body.classList.toggle("light", theme === "light"); localStorage.setItem("theme", theme); + window.dispatchEvent(new Event(REFETCH_LOGO_EVENT)); }, [theme]); // In development, attach keybind combinations to toggle theme @@ -34,20 +36,21 @@ export function useTheme() { function toggleOnKeybind(e) { if (e.metaKey && e.key === ".") { e.preventDefault(); - const newTheme = theme === "light" ? "default" : "light"; - console.log("toggling theme to ", newTheme); - setTheme(newTheme); + setTheme((prev) => (prev === "light" ? "default" : "light")); } } document.addEventListener("keydown", toggleOnKeybind); return () => document.removeEventListener("keydown", toggleOnKeybind); }, []); - // Refresh on theme change - const setTheme = (newTheme) => { + /** + * Sets the theme of the application and runs any + * other necessary side effects + * @param {string} newTheme The new theme to set + */ + function setTheme(newTheme) { _setTheme(newTheme); - window.location.reload(); - }; + } return { theme, setTheme, availableThemes }; }