-
-
- {reply.content && !hidden &&
}
+
+
+ {content && !hidden &&
}
diff --git a/src/components/settings-modal/plebbit-options/plebbit-options.tsx b/src/components/settings-modal/plebbit-options/plebbit-options.tsx
index 981091fa..1fcc4bf2 100644
--- a/src/components/settings-modal/plebbit-options/plebbit-options.tsx
+++ b/src/components/settings-modal/plebbit-options/plebbit-options.tsx
@@ -1,5 +1,6 @@
import { RefObject, useRef, useState } from 'react';
import { setAccount, useAccount, usePlebbitRpcSettings } from '@plebbit/plebbit-react-hooks';
+import { useTranslation } from 'react-i18next';
import styles from './plebbit-options.module.css';
interface SettingsProps {
@@ -134,6 +135,7 @@ const NodeDataPathSettings = ({ nodeDataPathRef }: SettingsProps) => {
};
const PlebbitOptions = () => {
+ const { t } = useTranslation();
const account = useAccount();
const { plebbitOptions } = account || {};
@@ -204,7 +206,7 @@ const PlebbitOptions = () => {
return (
IPFS gateways:
diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts
index 9ad92adc..9011d9c0 100644
--- a/src/hooks/use-theme.ts
+++ b/src/hooks/use-theme.ts
@@ -4,60 +4,71 @@ import { isAllView, isSubscriptionsView } from '../lib/utils/view-utils';
import useThemeStore from '../stores/use-theme-store';
import useInitialTheme from './use-initial-theme';
+const themeClasses = ['yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'];
+
+const updateThemeClass = (newTheme: string) => {
+ document.body.classList.remove(...themeClasses);
+ if (newTheme) {
+ document.body.classList.add(newTheme);
+ }
+};
+
const useTheme = (): [string, (theme: string) => void] => {
const location = useLocation();
const params = useParams();
const setThemeStore = useThemeStore((state) => state.setTheme);
+ const getTheme = useThemeStore((state) => state.getTheme);
const loadThemes = useThemeStore((state) => state.loadThemes);
+ const initialTheme = useInitialTheme();
+ const [theme, setLocalTheme] = useState(() => initialTheme);
const [themesLoaded, setThemesLoaded] = useState(false);
useEffect(() => {
- const load = async () => {
+ const loadAndApplyThemes = async () => {
await loadThemes();
setThemesLoaded(true);
};
- load();
+
+ loadAndApplyThemes();
}, [loadThemes]);
- const initialTheme = useInitialTheme();
-
- const [theme, setLocalTheme] = useState(initialTheme);
-
useEffect(() => {
- const previousTheme = document.body.className;
- document.body.classList.add(initialTheme);
- return () => {
- document.body.classList.remove(initialTheme);
- if (previousTheme) {
- document.body.classList.add(previousTheme);
- }
- };
- }, [initialTheme]);
+ if (!themesLoaded) return;
- useEffect(() => {
- if (themesLoaded) {
- document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon');
- document.body.classList.add(initialTheme);
- setLocalTheme(initialTheme);
+ const subplebbitAddress = params?.subplebbitAddress;
+ const isInAllView = isAllView(location.pathname, params);
+ const isInSubscriptionsView = isSubscriptionsView(location.pathname, params);
+
+ let storedTheme = null;
+ if (subplebbitAddress) {
+ storedTheme = getTheme(subplebbitAddress);
+ } else if (isInAllView) {
+ storedTheme = getTheme('all');
+ } else if (isInSubscriptionsView) {
+ storedTheme = getTheme('subscriptions');
}
- }, [initialTheme, themesLoaded]);
- const setSubplebbitTheme = (newTheme: string) => {
+ const themeToSet = storedTheme || initialTheme;
+ setLocalTheme(themeToSet);
+ updateThemeClass(themeToSet);
+ }, [initialTheme, location.pathname, params, getTheme, themesLoaded]);
+
+ const setSubplebbitTheme = async (newTheme: string) => {
const subplebbitAddress = params?.subplebbitAddress;
const isInAllView = isAllView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, params);
if (subplebbitAddress) {
- setThemeStore(subplebbitAddress, newTheme);
+ await setThemeStore(subplebbitAddress, newTheme);
} else if (isInAllView) {
- setThemeStore('all', newTheme);
+ await setThemeStore('all', newTheme);
} else if (isInSubscriptionsView) {
- setThemeStore('subscriptions', newTheme);
+ await setThemeStore('subscriptions', newTheme);
}
+
setLocalTheme(newTheme);
- document.body.classList.remove('yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon');
- document.body.classList.add(newTheme);
+ updateThemeClass(newTheme);
};
return [theme, setSubplebbitTheme];
diff --git a/src/stores/use-theme-store.ts b/src/stores/use-theme-store.ts
index d20d9609..85c68e91 100644
--- a/src/stores/use-theme-store.ts
+++ b/src/stores/use-theme-store.ts
@@ -5,7 +5,7 @@ interface ThemeState {
themes: Record;
setTheme: (subplebbitAddress: string, theme: string) => void;
getTheme: (subplebbitAddress: string) => string | null;
- loadThemes: () => void;
+ loadThemes: () => Promise;
}
const themeStore = localForageLru.createInstance({
@@ -35,6 +35,7 @@ const useThemeStore = create((set: StoreApi['setState'],
},
}));
+// Load themes on store initialization
useThemeStore.getState().loadThemes();
export default useThemeStore;
diff --git a/src/themes.css b/src/themes.css
index 6c1fd225..fa176761 100644
--- a/src/themes.css
+++ b/src/themes.css
@@ -424,6 +424,9 @@
--body-font-family: times new roman, serif;
--body-font-size: 16px;
+ /* board banner */
+ --banner-image-border: none;
+
/* board title */
--board-title-font-size: 32px;
--board-address-font-size: 10pt;
@@ -781,6 +784,9 @@
--body-font-family: arial, helvetica, sans-serif;
--body-font-size: 13px;
+ /* board banner */
+ --banner-image-border: none;
+
/* board title */
--board-title-font-size: 28px;
--board-title-font-family: Tahoma, sans-serif;
@@ -990,6 +996,9 @@
--body-font-family: arial, helvetica, sans-serif;
--body-font-size: 13px;
+ /* board banner */
+ --banner-image-border: none;
+
/* board title */
--board-title-font-size: 28px;
--board-title-font-family: Tahoma, sans-serif;
diff --git a/src/views/catalog/catalog-filters/catalog-filters.tsx b/src/views/catalog/catalog-filters/catalog-filters.tsx
index 0bd6da96..91e137b5 100644
--- a/src/views/catalog/catalog-filters/catalog-filters.tsx
+++ b/src/views/catalog/catalog-filters/catalog-filters.tsx
@@ -23,20 +23,20 @@ const FiltersModal = ({ closeModal }: { closeModal: () => void }) => {
{isInCatalogView && (
-
{
setShowFilterModal(false);
}}
>
- Show NSFW Boards Only
+ {t('show_nsfw_boards_only')}
{
setShowFilterModal(false);
}}
>
- Show Worksafe Boards Only
+ {t('show_worksafe_boards_only')}
{
setShowFilterModal(false);
}}
>
- Use Catalog
+ {t('use_catalog')}
>
) : (
@@ -103,7 +103,7 @@ const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => {
setShowFilterModal(false);
}}
>
- Show Worksafe Content Only
+ {t('show_worksafe_content_only')}
{
setShowFilterModal(false);
}}
>
- Show NSFW Content Only
+ {t('show_nsfw_content_only')}
{
setShowFilterModal(false);
}}
>
- Show All Content
+ {t('show_all_content')}
>
)}
diff --git a/src/views/not-found/not-found.module.css b/src/views/not-found/not-found.module.css
index 8702f52c..c31e3884 100644
--- a/src/views/not-found/not-found.module.css
+++ b/src/views/not-found/not-found.module.css
@@ -41,6 +41,8 @@
.boxContent img {
display: block;
margin: auto;
+ max-height: 500px;
+ max-width: 500px;
}
.backToBoard {
diff --git a/src/views/not-found/not-found.tsx b/src/views/not-found/not-found.tsx
index 79394bec..d5c7bf28 100644
--- a/src/views/not-found/not-found.tsx
+++ b/src/views/not-found/not-found.tsx
@@ -1,8 +1,8 @@
import { useState } from 'react';
-import { Link, useParams } from 'react-router-dom';
+import { Link, useLocation } 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 { useSubplebbit } from '@plebbit/plebbit-react-hooks';
const totalNotFoundImages = 2;
@@ -16,8 +16,10 @@ const NotFoundImage = () => {
};
const NotFound = () => {
- const { subplebbitAddress } = useParams();
- const isValidSubplebbitAddress = !subplebbitAddress || subplebbitAddress.includes('.') || /^12D3K[a-zA-Z0-9]{44}$/.test(subplebbitAddress);
+ const location = useLocation();
+ const subplebbitAddress = location.pathname.startsWith('/p/') ? location.pathname.split('/')[2] : '';
+ const subplebbit = useSubplebbit({ subplebbitAddress });
+ const { address, shortAddress } = subplebbit || {};
return (
@@ -30,11 +32,11 @@ const NotFound = () => {
- {subplebbitAddress && isValidSubplebbitAddress && (
+ {address && (
<>
- [Back to p/{Plebbit.getShortAddress(subplebbitAddress)}]
+ [Back to p/{shortAddress}]
>
)}
diff --git a/src/views/post/post.tsx b/src/views/post/post.tsx
index 39119b39..1b36fa40 100644
--- a/src/views/post/post.tsx
+++ b/src/views/post/post.tsx
@@ -28,13 +28,21 @@ export const Post = ({ post, showAllReplies = false, showReplies = true, openRep
const subplebbit = useSubplebbit({ subplebbitAddress: post?.subplebbitAddress });
const isMobile = useIsMobile();
+ let comment = post;
+
+ // handle pending mod or author edit
+ const { editedComment } = useEditedComment({ comment });
+ if (editedComment) {
+ comment = editedComment;
+ }
+
return (
{isMobile ? (
-
+
) : (
-
+
)}
@@ -66,12 +74,6 @@ const PostPage = () => {
post = comment;
}
- // handle pending mod or author edit
- const { editedComment } = useEditedComment({ comment: post });
- if (editedComment) {
- post = editedComment;
- }
-
const { deleted, locked, removed } = post || {};
const isThreadClosed = deleted || locked || removed;