From 22c1acdd3dbe29cab05626018538dd4361b28933 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 17 Jun 2024 12:17:36 +0200 Subject: [PATCH] feat(subplebbit): add automatic theme based on nsfw or sfw tags --- src/app.tsx | 52 +++++++++++++------ .../board-buttons/board-buttons.tsx | 8 +-- src/components/board-header/board-header.tsx | 4 +- src/components/catalog-row/catalog-row.tsx | 4 +- src/components/post-desktop/post-desktop.tsx | 4 +- .../post-menu-desktop/post-menu-desktop.tsx | 4 +- src/components/post-form/post-form.tsx | 8 +-- src/components/post-mobile/post-mobile.tsx | 6 +-- src/components/reply-modal/reply-modal.tsx | 6 +-- .../interface-settings/interface-settings.tsx | 6 ++- .../subplebbit-description.tsx | 4 +- src/components/topbar/topbar.tsx | 4 +- src/hooks/use-theme.ts | 45 +++++++++++++++- src/hooks/use-time-filter.js | 2 +- src/lib/utils/view-utils.ts | 43 ++++++++++++--- src/stores/use-theme-store.ts | 38 +++++++++++--- src/views/board/board.tsx | 4 +- .../catalog-filters/catalog-filters.tsx | 5 +- src/views/catalog/catalog.tsx | 10 ++-- src/views/not-found/not-found.tsx | 19 +------ 20 files changed, 189 insertions(+), 87 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index ee561a73..a469a67a 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,8 +1,6 @@ -import { useEffect } from 'react'; import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom'; -import { isAllView, isHomeView, isSubscriptionsView } from './lib/utils/view-utils'; +import { isAllView, isHomeView, isNotFoundView, isSubscriptionsView } from './lib/utils/view-utils'; import useIsMobile from './hooks/use-is-mobile'; -import useTheme from './hooks/use-theme'; import styles from './app.module.css'; import Board from './views/board'; import Catalog from './views/catalog'; @@ -16,17 +14,22 @@ 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'; const BoardLayout = () => { - const { accountCommentIndex, subplebbitAddress } = useParams(); + const { accountCommentIndex, subplebbitAddress, timeFilterName } = useParams(); const location = useLocation(); const isMobile = useIsMobile(); - const isInAllView = isAllView(location.pathname); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const isValidAccountCommentIndex = !accountCommentIndex || (!isNaN(parseInt(accountCommentIndex)) && parseInt(accountCommentIndex) >= 0); - if (!isValidAccountCommentIndex) { + if (!isValidAccountCommentIndex || (timeFilterName && !timeFilterNames.includes(timeFilterName))) { return ; } @@ -56,28 +59,47 @@ const BoardLayout = () => { ); }; -const App = () => { +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 [theme] = useTheme(); + const isInNotFoundView = isNotFoundView(location.pathname, useParams()); useEffect(() => { - document.body.classList.forEach((className) => document.body.classList.remove(className)); - const classToAdd = isInHomeView ? 'yotsuba' : theme; - document.body.classList.add(classToAdd); - }, [theme, isInHomeView]); + let theme = 'yotsuba-b'; - const globalLayout = ( + 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]); + + return ( <> ); +}; +const App = () => { return (
- + }> } /> }> } /> diff --git a/src/components/board-buttons/board-buttons.tsx b/src/components/board-buttons/board-buttons.tsx index 73d9eb2d..3a83ccb9 100644 --- a/src/components/board-buttons/board-buttons.tsx +++ b/src/components/board-buttons/board-buttons.tsx @@ -144,11 +144,11 @@ export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView export const MobileBoardButtons = () => { const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, params); const isInCatalogView = isCatalogView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; @@ -190,10 +190,10 @@ export const DesktopBoardButtons = () => { const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const isInCatalogView = isCatalogView(location.pathname, params); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); return ( <> diff --git a/src/components/board-header/board-header.tsx b/src/components/board-header/board-header.tsx index 879a56ba..0227ac26 100644 --- a/src/components/board-header/board-header.tsx +++ b/src/components/board-header/board-header.tsx @@ -20,8 +20,8 @@ const BoardHeader = () => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInAllView = isAllView(location.pathname, params); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; diff --git a/src/components/catalog-row/catalog-row.tsx b/src/components/catalog-row/catalog-row.tsx index 4a00693c..5dacf149 100644 --- a/src/components/catalog-row/catalog-row.tsx +++ b/src/components/catalog-row/catalog-row.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; -import { Link, useLocation } from 'react-router-dom'; +import { Link, useLocation, useParams } from 'react-router-dom'; import { Comment, useComment } from '@plebbit/plebbit-react-hooks'; import { useFloating, offset, shift, size, autoUpdate, Placement } from '@floating-ui/react'; import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils'; @@ -106,7 +106,7 @@ const CatalogPost = ({ post }: { post: Comment }) => { const { hidden } = useHide({ cid }); const location = useLocation(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); const postLink = isInAllView && isDescription ? `/p/all/description` : `/p/${subplebbitAddress}/${isDescription ? 'description' : isRules ? 'rules' : `c/${cid}`}`; diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 09b3071e..97c4fcc8 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -34,9 +34,9 @@ const PostInfo = ({ openReplyModal, post, roles, isHidden }: PostProps) => { const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const shortDisplayName = displayName?.trim().length > 20 ? displayName?.trim().slice(0, 20).trim() + '...' : displayName?.trim(); const authorRole = roles?.[address]?.role; diff --git a/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx b/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx index 80313368..e867d882 100644 --- a/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx +++ b/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx @@ -134,10 +134,10 @@ const PostMenuDesktop = ({ post }: { post: Comment }) => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, params); const isInCatalogView = isCatalogView(location.pathname, params); const isInPostPageView = isPostPageView(location.pathname, params); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const { refs, floatingStyles, context } = useFloating({ placement: 'bottom-start', diff --git a/src/components/post-form/post-form.tsx b/src/components/post-form/post-form.tsx index f9718be4..a66cb6f1 100644 --- a/src/components/post-form/post-form.tsx +++ b/src/components/post-form/post-form.tsx @@ -77,8 +77,8 @@ const PostFormTable = ({ closeForm }: { closeForm: () => void }) => { const subjectRef = useRef(null); const location = useLocation(); - const isInAllView = isAllView(location.pathname); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subscriptions = account?.subscriptions || []; const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); @@ -262,8 +262,8 @@ const PostForm = () => { const isInDescriptionView = isDescriptionView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const isInRulesView = isRulesView(location.pathname, params); - const isInAllView = isAllView(location.pathname); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInAllView = isAllView(location.pathname, params); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const comment = useComment({ commentCid: useParams().commentCid }); const { deleted, locked, removed } = comment || {}; diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index fd1d956e..3805e299 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -26,8 +26,8 @@ const PostInfoAndMedia = ({ openReplyModal, post, roles }: PostProps) => { const { address, displayName, shortAddress } = author || {}; const location = useLocation(); - const isInAllView = isAllView(location.pathname); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const authorRole = roles?.[address]?.role; const shortDisplayName = displayName?.trim().length > 20 ? displayName?.trim().slice(0, 20).trim() + '...' : displayName?.trim(); @@ -196,7 +196,7 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies, showReplies = const { isDescription, isRules } = post || {}; // custom properties, not from api const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, params); const isInPendingPostView = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const linksCount = useCountLinksInReplies(post); diff --git a/src/components/reply-modal/reply-modal.tsx b/src/components/reply-modal/reply-modal.tsx index b53a38bc..77a28ced 100644 --- a/src/components/reply-modal/reply-modal.tsx +++ b/src/components/reply-modal/reply-modal.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import Draggable from 'react-draggable'; -import { setAccount, useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks'; +import { setAccount, useAccount, useAuthorAddress, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import { getFormattedTimeAgo } from '../../lib/utils/time-utils'; import { isValidURL } from '../../lib/utils/url-utils'; @@ -78,8 +78,8 @@ const ReplyModal = ({ closeModal, parentCid, scrollY }: ReplyModalProps) => { }, [parentCid]); const location = useLocation(); - const isInAllView = isAllView(location.pathname); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subplebbit = useSubplebbit({ subplebbitAddress }); const { updatedAt } = subplebbit || {}; const isBoardOffline = subplebbit?.updatedAt && subplebbit.updatedAt < Date.now() / 1000 - 60 * 60; diff --git a/src/components/settings-modal/interface-settings/interface-settings.tsx b/src/components/settings-modal/interface-settings/interface-settings.tsx index 70502659..cf9494eb 100644 --- a/src/components/settings-modal/interface-settings/interface-settings.tsx +++ b/src/components/settings-modal/interface-settings/interface-settings.tsx @@ -65,8 +65,12 @@ const CheckForUpdates = () => { const Style = () => { const [theme, setTheme] = useTheme(); + const handleThemeChange = (e: React.ChangeEvent) => { + setTheme(e.target.value); + }; + return ( - diff --git a/src/components/subplebbit-description/subplebbit-description.tsx b/src/components/subplebbit-description/subplebbit-description.tsx index 4c3c8015..654cc4a3 100644 --- a/src/components/subplebbit-description/subplebbit-description.tsx +++ b/src/components/subplebbit-description/subplebbit-description.tsx @@ -2,7 +2,7 @@ import { Post } from '../../views/post'; import { useTranslation } from 'react-i18next'; import { isAllView } from '../../lib/utils/view-utils'; import { useMultisubMetadata } from '../../hooks/use-default-subplebbits'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; interface DescriptionPostProps { avatarUrl?: string; @@ -16,7 +16,7 @@ interface DescriptionPostProps { const SubplebbitDescription = ({ avatarUrl, createdAt, description, shortAddress, subplebbitAddress, title }: DescriptionPostProps) => { const { t } = useTranslation(); const location = useLocation(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); const multisubMetadata = useMultisubMetadata(); const post = { diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx index 1baf147d..bc611e16 100644 --- a/src/components/topbar/topbar.tsx +++ b/src/components/topbar/topbar.tsx @@ -104,9 +104,9 @@ const TopBarMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, params); const isInCatalogView = isCatalogView(location.pathname, params); - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const selectValue = isInAllView ? 'all' : isInSubscriptionsView ? 'subscriptions' : subplebbitAddress; const boardSelect = ( diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts index afe3047e..06ae2e3a 100644 --- a/src/hooks/use-theme.ts +++ b/src/hooks/use-theme.ts @@ -1,8 +1,49 @@ +import { useEffect, useState } 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 { nsfwTags } from '../views/home/home'; const useTheme = (): [string, (theme: string) => void] => { - const { theme, setTheme } = useThemeStore(); - return [theme, setTheme]; + 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 subplebbits = useDefaultSubplebbits(); + const [theme, setLocalTheme] = useState('yotsuba-b'); + + useEffect(() => { + let initialTheme = 'yotsuba-b'; + + if (isInHomeView) { + initialTheme = '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'); + } + } + + setLocalTheme(initialTheme); + document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'); + document.body.classList.add(initialTheme); + }, [subplebbitAddress, subplebbits, getTheme, setTheme, isInHomeView, location.pathname]); + + const setSubplebbitTheme = (theme: string) => { + if (subplebbitAddress) { + setTheme(subplebbitAddress, theme); + setLocalTheme(theme); + document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'); + document.body.classList.add(theme); + } + }; + + return [theme, setSubplebbitTheme]; }; export default useTheme; diff --git a/src/hooks/use-time-filter.js b/src/hooks/use-time-filter.js index 7ff81fba..62b0a82f 100644 --- a/src/hooks/use-time-filter.js +++ b/src/hooks/use-time-filter.js @@ -40,7 +40,7 @@ if (secondsSinceLastVisit > 30 * day) { timeFilterNamesToSeconds[lastVisitTimeFilterName] = timeFilterNamesToSeconds['24h']; } -const timeFilterNames = [lastVisitTimeFilterName, '1h', '12h', '24h', '48h', 'week', 'month', 'year', 'all']; +export const timeFilterNames = [lastVisitTimeFilterName, '1h', '12h', '24h', '48h', 'week', 'month', 'year', 'all']; const useTimeFilter = () => { const params = useParams(); diff --git a/src/lib/utils/view-utils.ts b/src/lib/utils/view-utils.ts index cd580663..1954f339 100644 --- a/src/lib/utils/view-utils.ts +++ b/src/lib/utils/view-utils.ts @@ -1,3 +1,5 @@ +import { timeFilterNames } from '../../hooks/use-time-filter'; + export type ParamsType = { accountCommentIndex?: string; commentCid?: string; @@ -5,8 +7,25 @@ export type ParamsType = { timeFilterName?: string; }; -export const isAllView = (pathname: string): boolean => { - return pathname.startsWith('/p/all'); +export const isAllView = (pathname: string, params: ParamsType): boolean => { + const { timeFilterName } = params; + + if (timeFilterName && !timeFilterNames.includes(timeFilterName)) { + return false; + } + + return ( + pathname === '/p/all' || + pathname === '/p/all/settings' || + pathname === `/p/all/${timeFilterName}` || + pathname === `/p/all/${timeFilterName}/settings` || + pathname === '/p/all/catalog' || + pathname === '/p/all/catalog/settings' || + pathname === `/p/all/catalog/${timeFilterName}` || + pathname === `/p/all/catalog/${timeFilterName}/settings` || + pathname === '/p/all/description' || + pathname === '/p/all/description/settings' + ); }; export const isBoardView = (pathname: string, params: ParamsType): boolean => { @@ -68,19 +87,31 @@ export const isSettingsView = (pathname: string, params: ParamsType): boolean => ); }; -export const isSubscriptionsView = (pathname: string): boolean => { - return pathname.startsWith('/p/subscriptions'); +export const isSubscriptionsView = (pathname: string, params: ParamsType): boolean => { + const { timeFilterName } = params; + return ( + pathname === '/p/subscriptions' || + pathname === '/p/subscriptions/settings' || + pathname === `/p/subscriptions/${timeFilterName}` || + pathname === `/p/subscriptions/${timeFilterName}/settings` || + pathname === '/p/subscriptions/catalog' || + pathname === '/p/subscriptions/catalog/settings' || + pathname === `/p/subscriptions/catalog/${timeFilterName}` || + pathname === `/p/subscriptions/catalog/${timeFilterName}/settings` + ); }; export const isNotFoundView = (pathname: string, params: ParamsType): boolean => { return ( - !isAllView(pathname) && + !isAllView(pathname, params) && !isBoardView(pathname, params) && !isCatalogView(pathname, params) && !isDescriptionView(pathname, params) && !isHomeView(pathname) && !isPendingPostView(pathname, params) && !isPostPageView(pathname, params) && - !isRulesView(pathname, params) + !isRulesView(pathname, params) && + !isSettingsView(pathname, params) && + !isSubscriptionsView(pathname, params) ); }; diff --git a/src/stores/use-theme-store.ts b/src/stores/use-theme-store.ts index b3e416cf..d720bba6 100644 --- a/src/stores/use-theme-store.ts +++ b/src/stores/use-theme-store.ts @@ -1,16 +1,40 @@ import { create, StoreApi } from 'zustand'; +import localForageLru from '@plebbit/plebbit-react-hooks/dist/lib/localforage-lru/index.js'; interface ThemeState { - theme: string; - setTheme: (theme: string) => void; + themes: Record; + setTheme: (subplebbitAddress: string, theme: string) => void; + getTheme: (subplebbitAddress: string) => string; + loadThemes: () => void; } -const useThemeStore = create((set: StoreApi['setState']) => ({ - theme: localStorage.getItem('theme') || 'yotsuba', - setTheme: (theme: string) => { - localStorage.setItem('theme', theme); - set({ theme }); +const themeStore = localForageLru.createInstance({ + name: 'themeStore', + size: 1000, +}); + +const useThemeStore = create((set: StoreApi['setState'], get: StoreApi['getState']) => ({ + themes: {}, + setTheme: async (subplebbitAddress: string, theme: string) => { + const currentThemes = get().themes; + const updatedThemes = { ...currentThemes, [subplebbitAddress]: theme }; + await themeStore.setItem(subplebbitAddress, theme); + set({ themes: updatedThemes }); + }, + getTheme: (subplebbitAddress: string) => { + const currentThemes = get().themes; + return currentThemes[subplebbitAddress] || 'yotsuba-b'; + }, + loadThemes: async () => { + const entries: [string, string][] = await themeStore.entries(); + const themes: Record = {}; + entries.forEach(([key, value]) => { + themes[key] = value; + }); + set({ themes }); }, })); +useThemeStore.getState().loadThemes(); + export default useThemeStore; diff --git a/src/views/board/board.tsx b/src/views/board/board.tsx index f5e77894..12f356db 100644 --- a/src/views/board/board.tsx +++ b/src/views/board/board.tsx @@ -25,12 +25,12 @@ const Board = () => { const location = useLocation(); const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); const account = useAccount(); const subscriptions = account?.subscriptions; - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subplebbitAddresses = useMemo(() => { if (isInAllView) { diff --git a/src/views/catalog/catalog-filters/catalog-filters.tsx b/src/views/catalog/catalog-filters/catalog-filters.tsx index 10e30005..0bd6da96 100644 --- a/src/views/catalog/catalog-filters/catalog-filters.tsx +++ b/src/views/catalog/catalog-filters/catalog-filters.tsx @@ -9,8 +9,9 @@ const FiltersModal = ({ closeModal }: { closeModal: () => void }) => { const { t } = useTranslation(); const { showAdultBoards, setShowAdultBoards, showGoreBoards, setShowGoreBoards, showTextOnlyThreads, setShowTextOnlyThreads } = useCatalogFiltersStore(); const location = useLocation(); - const isInCatalogView = isCatalogView(location.pathname, useParams()); - const isInAllView = isAllView(location.pathname); + const params = useParams(); + const isInCatalogView = isCatalogView(location.pathname, params); + const isInAllView = isAllView(location.pathname, params); return ( <> diff --git a/src/views/catalog/catalog.tsx b/src/views/catalog/catalog.tsx index 11da68b4..818a98ae 100644 --- a/src/views/catalog/catalog.tsx +++ b/src/views/catalog/catalog.tsx @@ -27,7 +27,7 @@ const useFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolean, subp const { avatarUrl } = suggested || {}; const location = useLocation(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); const multisub = useMultisubMetadata(); const feedWithDescriptionAndRules = useMemo(() => { @@ -90,13 +90,13 @@ const Catalog = () => { const location = useLocation(); const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>(); - const isInAllView = isAllView(location.pathname); + const isInAllView = isAllView(location.pathname, useParams()); const defaultSubplebbits = useDefaultSubplebbits(); const { showAdultBoards, showGoreBoards } = useCatalogFiltersStore(); const account = useAccount(); const subscriptions = account?.subscriptions; - const isInSubscriptionsView = isSubscriptionsView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subplebbitAddresses = useMemo(() => { const filteredDefaultSubplebbits = defaultSubplebbits @@ -121,10 +121,6 @@ const Catalog = () => { return [subplebbitAddress]; }, [isInAllView, isInSubscriptionsView, subplebbitAddress, defaultSubplebbits, subscriptions, showAdultBoards, showGoreBoards]); - useEffect(() => { - console.log(showAdultBoards, showGoreBoards); - }, [showAdultBoards, showGoreBoards]); - const columnCount = Math.floor(useWindowWidth() / columnWidth); // postPerPage based on columnCount for optimized feed, dont change value after first render // eslint-disable-next-line diff --git a/src/views/not-found/not-found.tsx b/src/views/not-found/not-found.tsx index 7e206fe8..df52dfcd 100644 --- a/src/views/not-found/not-found.tsx +++ b/src/views/not-found/not-found.tsx @@ -1,9 +1,8 @@ -import { useEffect, useState, useRef } from 'react'; +import { useState } from 'react'; import { Link, useParams } from 'react-router-dom'; import { HomeLogo } from '../home'; import styles from './not-found.module.css'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; -import useTheme from '../../hooks/use-theme'; const totalNotFoundImages = 2; @@ -20,22 +19,6 @@ const NotFound = () => { const { subplebbitAddress } = useParams(); const isValidSubplebbitAddress = !subplebbitAddress || subplebbitAddress.includes('.') || /^12D3K[a-zA-Z0-9]{44}$/.test(subplebbitAddress); - const [theme, setTheme] = useTheme(); - const previousThemeRef = useRef(theme); - - useEffect(() => { - if (theme !== 'yotsuba') { - previousThemeRef.current = theme; - setTheme('yotsuba'); - } - - return () => { - if (theme === 'yotsuba') { - setTheme(previousThemeRef.current); - } - }; - }, [theme, setTheme]); - return (