From 3eb9c5c20f604f8081b913e2577d84992fbfbd60 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 17 Jun 2024 15:39:49 +0200 Subject: [PATCH] fix: performance, logic --- src/app.tsx | 34 ++------------------ src/hooks/use-theme.ts | 60 +++++++++++++++++++++-------------- src/stores/use-theme-store.ts | 4 +-- 3 files changed, 42 insertions(+), 56 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index a469a67a..8b1ea752 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,5 +1,5 @@ import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom'; -import { isAllView, isHomeView, isNotFoundView, isSubscriptionsView } from './lib/utils/view-utils'; +import { isAllView, isSubscriptionsView } from './lib/utils/view-utils'; import useIsMobile from './hooks/use-is-mobile'; import styles from './app.module.css'; import Board from './views/board'; @@ -14,11 +14,8 @@ import ChallengeModal from './components/challenge-modal'; import PostForm from './components/post-form'; import SubplebbitStats from './components/subplebbit-stats'; import TopBar from './components/topbar'; -import { useEffect } from 'react'; -import { nsfwTags } from './views/home/home'; -import useDefaultSubplebbits from './hooks/use-default-subplebbits'; -import useThemeStore from './stores/use-theme-store'; import { timeFilterNames } from './hooks/use-time-filter'; +import useTheme from './hooks/use-theme'; const BoardLayout = () => { const { accountCommentIndex, subplebbitAddress, timeFilterName } = useParams(); @@ -60,32 +57,7 @@ const BoardLayout = () => { }; const GlobalLayout = () => { - const location = useLocation(); - const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>(); - const getTheme = useThemeStore((state) => state.getTheme); - const setTheme = useThemeStore((state) => state.setTheme); - const subplebbits = useDefaultSubplebbits(); - const isInHomeView = isHomeView(location.pathname); - const isInNotFoundView = isNotFoundView(location.pathname, useParams()); - - useEffect(() => { - let theme = 'yotsuba-b'; - - if (isInHomeView || isInNotFoundView) { - theme = 'yotsuba'; - } else if (subplebbitAddress) { - theme = getTheme(subplebbitAddress); - const subplebbit = subplebbits.find((s) => s.address === subplebbitAddress); - - if (subplebbit && subplebbit.tags && subplebbit.tags.some((tag) => nsfwTags.includes(tag)) && theme === 'yotsuba-b') { - theme = 'yotsuba'; - setTheme(subplebbitAddress, 'yotsuba'); - } - } - - document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'); - document.body.classList.add(theme); - }, [location.pathname, subplebbitAddress, getTheme, setTheme, subplebbits, isInHomeView]); + useTheme(); return ( <> diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts index 06ae2e3a..b900c67d 100644 --- a/src/hooks/use-theme.ts +++ b/src/hooks/use-theme.ts @@ -1,46 +1,60 @@ -import { useEffect, useState } from 'react'; +import { useState, useMemo } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import useThemeStore from '../stores/use-theme-store'; import useDefaultSubplebbits from './use-default-subplebbits'; -import { isHomeView } from '../lib/utils/view-utils'; +import { isAllView, isHomeView, isNotFoundView, isSubscriptionsView } from '../lib/utils/view-utils'; import { nsfwTags } from '../views/home/home'; const useTheme = (): [string, (theme: string) => void] => { const location = useLocation(); - const isInHomeView = isHomeView(location.pathname); const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>(); const getTheme = useThemeStore((state) => state.getTheme); - const setTheme = useThemeStore((state) => state.setTheme); + const setThemeStore = useThemeStore((state) => state.setTheme); const subplebbits = useDefaultSubplebbits(); - const [theme, setLocalTheme] = useState('yotsuba-b'); + const params = useParams(); + const isInHomeView = isHomeView(location.pathname); + const isInNotFoundView = isNotFoundView(location.pathname, params); + const isInAllView = isAllView(location.pathname, params); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); - useEffect(() => { - let initialTheme = 'yotsuba-b'; - - if (isInHomeView) { - initialTheme = 'yotsuba'; + const initialTheme = useMemo(() => { + if (isInAllView || isInSubscriptionsView) { + const userTheme = getTheme(isInAllView ? 'all' : 'subscriptions'); + return userTheme || 'yotsuba-b'; + } else if (isInHomeView || isInNotFoundView) { + return 'yotsuba'; } else if (subplebbitAddress) { - initialTheme = getTheme(subplebbitAddress); - const subplebbit = subplebbits.find((s) => s.address === subplebbitAddress); - - if (subplebbit && subplebbit.tags && subplebbit.tags.some((tag) => nsfwTags.includes(tag)) && initialTheme === 'yotsuba-b') { - initialTheme = 'yotsuba'; - setTheme(subplebbitAddress, 'yotsuba'); + const userTheme = getTheme(subplebbitAddress); + if (userTheme) { + return userTheme; } + const subplebbit = subplebbits.find((s) => s.address === subplebbitAddress); + if (subplebbit && subplebbit.tags && subplebbit.tags.some((tag) => nsfwTags.includes(tag))) { + return 'yotsuba'; + } + return 'yotsuba-b'; } + return 'yotsuba'; + }, [location.pathname, subplebbitAddress, subplebbits, getTheme]); - setLocalTheme(initialTheme); + const [theme, setLocalTheme] = useState(initialTheme); + + useMemo(() => { document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'); document.body.classList.add(initialTheme); - }, [subplebbitAddress, subplebbits, getTheme, setTheme, isInHomeView, location.pathname]); + }, [initialTheme]); - const setSubplebbitTheme = (theme: string) => { + const setSubplebbitTheme = (newTheme: string) => { if (subplebbitAddress) { - setTheme(subplebbitAddress, theme); - setLocalTheme(theme); - document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'); - document.body.classList.add(theme); + setThemeStore(subplebbitAddress, newTheme); + } else if (isInAllView) { + setThemeStore('all', newTheme); + } else if (isInSubscriptionsView) { + setThemeStore('subscriptions', newTheme); } + setLocalTheme(newTheme); + document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'); + document.body.classList.add(newTheme); }; return [theme, setSubplebbitTheme]; diff --git a/src/stores/use-theme-store.ts b/src/stores/use-theme-store.ts index d720bba6..d20d9609 100644 --- a/src/stores/use-theme-store.ts +++ b/src/stores/use-theme-store.ts @@ -4,7 +4,7 @@ import localForageLru from '@plebbit/plebbit-react-hooks/dist/lib/localforage-lr interface ThemeState { themes: Record; setTheme: (subplebbitAddress: string, theme: string) => void; - getTheme: (subplebbitAddress: string) => string; + getTheme: (subplebbitAddress: string) => string | null; loadThemes: () => void; } @@ -23,7 +23,7 @@ const useThemeStore = create((set: StoreApi['setState'], }, getTheme: (subplebbitAddress: string) => { const currentThemes = get().themes; - return currentThemes[subplebbitAddress] || 'yotsuba-b'; + return currentThemes[subplebbitAddress] || null; }, loadThemes: async () => { const entries: [string, string][] = await themeStore.entries();