diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx
index 3d6bfcf6..0e68cc1d 100644
--- a/src/components/post-mobile/post-mobile.tsx
+++ b/src/components/post-mobile/post-mobile.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useRef, useState } from 'react';
+import { useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { Link, useLocation, useParams } from 'react-router-dom';
import { Comment, useAccount, useAuthorAvatar, useComment, useEditedComment } from '@plebbit/plebbit-react-hooks';
@@ -8,6 +8,9 @@ import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-util
import { getTextColorForBackground, hashStringToColor } from '../../lib/utils/post-utils';
import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { isAllView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
+import useAnonModeStore from '../../stores/use-anon-mode-store';
+import useAvatarVisibilityStore from '../../stores/use-avatar-visibility-store';
+import useAnonMode from '../../hooks/use-anon-mode';
import useAuthorAddressClick from '../../hooks/use-author-address-click';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import useHide from '../../hooks/use-hide';
@@ -31,6 +34,7 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
const displayName = author?.displayName?.trim();
const authorRole = roles?.[address]?.role;
const { imageUrl: avatarImageUrl } = useAuthorAvatar({ author });
+ const { hideAvatars } = useAvatarVisibilityStore();
const params = useParams();
const location = useLocation();
@@ -44,16 +48,19 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
const isReply = parentCid;
- // pending reply by account is not yet published
+ // comment.author.shortAddress is undefined while the comment publishing state is pending, use account instead
+ // in anon mode, use the newly generated signer.address instead, which will be comment.author.address
+ const { anonMode } = useAnonMode();
+ const { currentAnonSignerAddress } = useAnonModeStore();
const account = useAccount();
- const accountShortAddress = account?.author?.shortAddress;
+ const pendingShortAddress = anonMode ? currentAnonSignerAddress && Plebbit.getShortAddress(currentAnonSignerAddress) : account?.author?.shortAddress;
const stateString = useStateString(post);
const handleUserAddressClick = useAuthorAddressClick();
const numberOfPostsByAuthor = document.querySelectorAll(`[data-author-address="${shortAddress}"][data-post-cid="${postCid}"]`).length;
- const userIDBackgroundColor = hashStringToColor(shortAddress || accountShortAddress);
+ const userIDBackgroundColor = hashStringToColor(shortAddress || pendingShortAddress);
const userIDTextColor = getTextColorForBackground(userIDBackgroundColor);
return (
@@ -82,7 +89,7 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
{!(isDescription || isRules) && (
<>
- {author?.avatar && !(deleted || removed) ? (
+ {author?.avatar && !(deleted || removed) && !hideAvatars ? (
@@ -100,10 +107,10 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
handleUserAddressClick(shortAddress || accountShortAddress, postCid)}
+ onClick={() => handleUserAddressClick(shortAddress || pendingShortAddress, postCid)}
style={{ backgroundColor: userIDBackgroundColor, color: userIDTextColor }}
>
- {shortAddress || accountShortAddress}
+ {shortAddress || pendingShortAddress}
}
content={`${numberOfPostsByAuthor === 1 ? t('1_post_by_this_id') : t('x_posts_by_this_id', { number: numberOfPostsByAuthor })}`}
@@ -154,7 +161,9 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
) : (
<>
c/
-
{state === 'failed' || stateString === 'Failed' ? 'Failed' : 'Pending'}
+
+ {state === 'failed' || stateString === 'Failed' ? _.capitalize(t('failed')) : state === 'pending' ? _.capitalize(t('pending')) : ''}
+
>
))}
@@ -167,15 +176,17 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
};
const ReplyBacklinks = ({ post }: PostProps) => {
- const { cid, parentCid, replyCount } = post || {};
+ const { cid, parentCid } = post || {};
const replies = useReplies(post);
return (
- replyCount > 0 &&
+ cid &&
parentCid &&
- replies && (
+ replies.length > 0 && (
- {replies.map((reply: Comment, index: number) => reply?.parentCid === cid && )}
+ {replies.map(
+ (reply: Comment, index: number) => reply?.parentCid === cid && reply?.cid && ,
+ )}
)
);
@@ -214,7 +225,7 @@ const PostMessageMobile = ({ post }: PostProps) => {
({t('this_post_was_removed')})
-
{`${_.capitalize(t('reason'))}: "${reason}"`}.
+
{`${_.capitalize(t('reason'))}: "${reason}"`}
>
) : (
{_.capitalize(t('this_post_was_removed'))}.
@@ -223,7 +234,7 @@ const PostMessageMobile = ({ post }: PostProps) => {
reason ? (
<>
{t('user_deleted_this_post')}{' '}
-
{`${_.capitalize(t('reason'))}: "${reason}"`}.
+
{`${_.capitalize(t('reason'))}: "${reason}"`}
>
) : (
{t('user_deleted_this_post')}
@@ -334,15 +345,6 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies, showReplies =
const isInPostPageView = isPostPageView(location.pathname, params);
const { hidden, unhide } = useHide({ cid });
- // scroll to reply if pathname is reply permalink (backlink)
- const replyRefs = useRef<(HTMLDivElement | null)[]>([]);
- useEffect(() => {
- const replyIndex = replies.findIndex((reply) => location.pathname === `/p/${subplebbitAddress}/c/${reply?.cid}`);
- if (replyIndex !== -1 && replyRefs.current[replyIndex]) {
- replyRefs.current[replyIndex]?.scrollIntoView();
- }
- }, [location.pathname, replies, subplebbitAddress]);
-
const stateString = useStateString(post);
return (
@@ -391,7 +393,7 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies, showReplies =
replies &&
showReplies &&
(showAllReplies ? replies : replies.slice(-5)).map((reply, index) => (
-
(replyRefs.current[index] = el)}>
+
))}
diff --git a/src/components/reply-modal/reply-modal.tsx b/src/components/reply-modal/reply-modal.tsx
index 1bae61b3..f053f365 100644
--- a/src/components/reply-modal/reply-modal.tsx
+++ b/src/components/reply-modal/reply-modal.tsx
@@ -15,6 +15,7 @@ import styles from './reply-modal.module.css';
import { LinkTypePreviewer } from '../post-form';
import _ from 'lodash';
import useAnonMode from '../../hooks/use-anon-mode';
+import useAnonModeStore from '../../stores/use-anon-mode-store';
interface ReplyModalProps {
closeModal: () => void;
@@ -40,6 +41,8 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, postCid, scrollY, s
const address = comment?.author?.address;
const hasCalledAnonAddressRef = useRef(false);
+ const { setCurrentAnonSignerAddress } = useAnonModeStore();
+
const getAnonAddressForReply = useCallback(async () => {
if (anonMode && !hasCalledAnonAddressRef.current) {
hasCalledAnonAddressRef.current = true;
@@ -52,18 +55,22 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, postCid, scrollY, s
displayName: displayName || undefined,
},
});
+ setCurrentAnonSignerAddress(existingSigner.address);
} else {
const newSigner = await getNewSigner();
- setPublishReplyOptions({
- signer: newSigner,
- author: {
- address: newSigner.address,
- displayName: displayName || undefined,
- },
- });
+ if (newSigner) {
+ setPublishReplyOptions({
+ signer: newSigner,
+ author: {
+ address: newSigner.address,
+ displayName: displayName || undefined,
+ },
+ });
+ setCurrentAnonSignerAddress(newSigner.address);
+ }
}
}
- }, [address, getExistingSigner, getNewSigner, setPublishReplyOptions, anonMode, displayName]);
+ }, [address, getExistingSigner, getNewSigner, setPublishReplyOptions, anonMode, displayName, setCurrentAnonSignerAddress]);
const onPublishReply = () => {
const currentContent = textRef.current?.value.slice(contentPrefix.length).trim() || '';
diff --git a/src/components/reply-quote-preview/reply-quote-preview.tsx b/src/components/reply-quote-preview/reply-quote-preview.tsx
index 6df42524..407aae8c 100644
--- a/src/components/reply-quote-preview/reply-quote-preview.tsx
+++ b/src/components/reply-quote-preview/reply-quote-preview.tsx
@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
-import { Link } from 'react-router-dom';
+import { Link, useNavigate } from 'react-router-dom';
import { Comment, useAccount } from '@plebbit/plebbit-react-hooks';
import { useFloating, offset, shift, size, autoUpdate, Placement } from '@floating-ui/react';
import useIsMobile from '../../hooks/use-is-mobile';
@@ -88,6 +88,19 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
};
}, [update]);
+ const navigate = useNavigate();
+
+ const handleClick = (e: React.MouseEvent, cid: string | undefined, subplebbitAddress: string | undefined) => {
+ e.preventDefault();
+ if (cid && subplebbitAddress) {
+ navigate(`/p/${subplebbitAddress}/c/${cid}`);
+ setTimeout(() => {
+ const element = document.querySelector(`[data-cid="${cid}"]`);
+ element?.scrollIntoView();
+ }, 100);
+ }
+ };
+
const handleMouseOver = (cid: string | undefined) => {
if (!cid) return;
@@ -114,6 +127,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
ref={refs.setReference}
onMouseOver={() => handleMouseOver(backlinkReply?.cid)}
onMouseLeave={() => handleMouseLeave(backlinkReply?.cid)}
+ onClick={(e) => handleClick(e, backlinkReply?.cid, backlinkReply?.subplebbitAddress)}
>
c/{backlinkReply?.shortCid}
@@ -138,8 +152,9 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
className={styles.quoteLink}
onMouseOver={() => handleMouseOver(quotelinkReply?.cid)}
onMouseLeave={() => handleMouseLeave(quotelinkReply?.cid)}
+ onClick={(e) => handleClick(e, quotelinkReply?.cid, quotelinkReply?.subplebbitAddress)}
>
- {`c/${quotelinkReply?.shortCid}`}
+ {quotelinkReply?.shortCid && `c/${quotelinkReply?.shortCid}`}
{quotelinkReply?.author?.address === account?.author?.address && ' (You)'}
@@ -174,6 +189,19 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
};
}, [update]);
+ const navigate = useNavigate();
+
+ const handleClick = (e: React.MouseEvent, cid: string | undefined, subplebbitAddress: string | undefined) => {
+ e.preventDefault();
+ if (cid && subplebbitAddress) {
+ navigate(`/p/${subplebbitAddress}/c/${cid}`);
+ setTimeout(() => {
+ const element = document.querySelector(`[data-cid="${cid}"]`);
+ element?.scrollIntoView();
+ }, 100);
+ }
+ };
+
const handleMouseOver = (cid: string | undefined) => {
if (!cid) return;
@@ -200,11 +228,18 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
onMouseOver={() => handleMouseOver(backlinkReply?.cid)}
onMouseLeave={() => handleMouseLeave(backlinkReply?.cid)}
>
- c/{backlinkReply?.shortCid}{' '}
+ {backlinkReply?.shortCid && `c/${backlinkReply?.shortCid}`}
-
- #
-
+ {backlinkReply?.shortCid && (
+
handleClick(e, backlinkReply?.cid, backlinkReply?.subplebbitAddress)}
+ >
+ {' '}
+ #
+
+ )}
{hoveredCid === backlinkReply?.cid &&
outOfViewCid === backlinkReply?.cid &&
createPortal(
@@ -226,14 +261,19 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
onMouseOver={() => handleMouseOver(quotelinkReply?.cid)}
onMouseLeave={() => handleMouseLeave(quotelinkReply?.cid)}
>
- c/{quotelinkReply?.shortCid}
+ {quotelinkReply?.shortCid && `c/${quotelinkReply?.shortCid}`}
{quotelinkReply?.author?.address === account?.author?.address && ' (You)'}
-
- {' '}
- #
-
-
+ {quotelinkReply?.shortCid && (
+
handleClick(e, quotelinkReply?.cid, quotelinkReply?.subplebbitAddress)}
+ >
+ {' '}
+ #
+
+ )}
{hoveredCid === quotelinkReply?.cid &&
outOfViewCid === quotelinkReply?.cid &&
createPortal(
diff --git a/src/components/settings-modal/account-settings/account-settings.tsx b/src/components/settings-modal/account-settings/account-settings.tsx
index c8a48dc8..12a4af17 100644
--- a/src/components/settings-modal/account-settings/account-settings.tsx
+++ b/src/components/settings-modal/account-settings/account-settings.tsx
@@ -6,15 +6,16 @@ import styles from './account-settings.module.css';
import useAnonModeStore from '../../../stores/use-anon-mode-store';
const AnonMode = () => {
+ const { t } = useTranslation();
const anonMode = useAnonModeStore((state) => state.anonMode);
const setAnonMode = useAnonModeStore((state) => state.setAnonMode);
return (
- Automatically use a different user ID in each thread
+ {t('anon_mode_description')}
);
};
diff --git a/src/components/settings-modal/crypto-address-setting/crypto-address-setting.tsx b/src/components/settings-modal/crypto-address-setting/crypto-address-setting.tsx
index c50019f2..a41e6e5c 100644
--- a/src/components/settings-modal/crypto-address-setting/crypto-address-setting.tsx
+++ b/src/components/settings-modal/crypto-address-setting/crypto-address-setting.tsx
@@ -117,7 +117,7 @@ const CryptoAddressSetting = () => {
{showCryptoAddressInfo && (
- steps to set a .eth user address:
+ steps to set a .eth address as your ID:
-
@@ -130,7 +130,7 @@ const CryptoAddressSetting = () => {
- once you own the address, go to its page, click on "records", then "edit records"
- add a new text record with name "plebbit-author-address" and value: {account?.signer?.address}
- steps to set a .sol user address:
+ steps to set a .sol address as your ID:
-
diff --git a/src/components/settings-modal/interface-settings/interface-settings.module.css b/src/components/settings-modal/interface-settings/interface-settings.module.css
index 650868a8..17c135bf 100644
--- a/src/components/settings-modal/interface-settings/interface-settings.module.css
+++ b/src/components/settings-modal/interface-settings/interface-settings.module.css
@@ -3,7 +3,6 @@
}
.setting {
- text-transform: capitalize;
margin-left: 10px;
margin-top: 10px;
}
@@ -24,4 +23,8 @@
.interfaceSettings {
margin-bottom: 10px;
+}
+
+.setting input[type="checkbox"] {
+ margin-right: 2px;
}
\ No newline at end of file
diff --git a/src/components/settings-modal/interface-settings/interface-settings.tsx b/src/components/settings-modal/interface-settings/interface-settings.tsx
index cf9494eb..9fccc550 100644
--- a/src/components/settings-modal/interface-settings/interface-settings.tsx
+++ b/src/components/settings-modal/interface-settings/interface-settings.tsx
@@ -1,8 +1,10 @@
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
+import useAvatarVisibilityStore from '../../../stores/use-avatar-visibility-store';
import useTheme from '../../../hooks/use-theme';
-import styles from './interface-settings.module.css';
import packageJson from '../../../../package.json';
+import styles from './interface-settings.module.css';
+import _ from 'lodash';
const commitRef = process.env.REACT_APP_COMMIT_REF;
const isElectron = window.isElectron === true;
@@ -107,11 +109,16 @@ const InterfaceLanguage = () => {
const InterfaceSettings = () => {
const { t } = useTranslation();
+ const { hideAvatars, setHideAvatars } = useAvatarVisibilityStore();
+
+ const handleHideAvatarsChange = (e: React.ChangeEvent) => {
+ setHideAvatars(e.target.checked);
+ };
return (
- {t('version')}:{' '}
+ {_.capitalize(t('version'))}:{' '}
{packageJson.version}
@@ -122,13 +129,18 @@ const InterfaceSettings = () => {
)}
- {t('update')}:
+ {_.capitalize(t('update'))}:
- {t('style')}:
+ {_.capitalize(t('style'))}:
- {t('interface_language')}:
+ {_.capitalize(t('interface_language'))}:
+
+
+
);
diff --git a/src/components/settings-modal/plebbit-options/plebbit-options.tsx b/src/components/settings-modal/plebbit-options/plebbit-options.tsx
index 1654603a..b0ca7cd2 100644
--- a/src/components/settings-modal/plebbit-options/plebbit-options.tsx
+++ b/src/components/settings-modal/plebbit-options/plebbit-options.tsx
@@ -230,7 +230,7 @@ const PlebbitOptions = () => {
-
node rpc:
+
node RPC:
diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx
index f13a99f5..27942ec6 100644
--- a/src/components/topbar/topbar.tsx
+++ b/src/components/topbar/topbar.tsx
@@ -85,7 +85,8 @@ const TopBarDesktop = () => {
{renderSubplebbits(projectsSubs)}
{renderSubplebbits(interestsSubs)}
{renderSubplebbits(randomSubs)}
- {renderSubplebbits(internationalSubs)}[
+ {renderSubplebbits(internationalSubs)}
+ {/* [
{
@@ -105,7 +106,7 @@ const TopBarDesktop = () => {
>
Vote
- ]
+ ] */}
[{t('settings')}] [
diff --git a/src/hooks/use-anon-mode.ts b/src/hooks/use-anon-mode.ts
index e932ded5..22f0bc65 100644
--- a/src/hooks/use-anon-mode.ts
+++ b/src/hooks/use-anon-mode.ts
@@ -2,12 +2,13 @@ import { useAccount } from '@plebbit/plebbit-react-hooks';
import useAnonModeStore from '../stores/use-anon-mode-store';
const useAnonMode = (postCid?: string) => {
- const { anonMode, threadSigners, setThreadSigner, setAddressSigner, getAddressSigner } = useAnonModeStore((state) => ({
+ const { anonMode, threadSigners, setThreadSigner, setAddressSigner, getAddressSigner, setCurrentAnonSignerAddress } = useAnonModeStore((state) => ({
anonMode: state.anonMode,
threadSigners: state.threadSigners,
setThreadSigner: state.setThreadSigner,
setAddressSigner: state.setAddressSigner,
getAddressSigner: state.getAddressSigner,
+ setCurrentAnonSignerAddress: state.setCurrentAnonSignerAddress,
}));
const threadSigner = postCid ? threadSigners[postCid] : undefined;
@@ -25,6 +26,7 @@ const useAnonMode = (postCid?: string) => {
} else {
setAddressSigner(signer);
}
+ setCurrentAnonSignerAddress(signer.address);
}
return signer;
} catch (error) {
@@ -33,6 +35,7 @@ const useAnonMode = (postCid?: string) => {
} else {
try {
const signer = await account?.plebbit.createSigner({ type: 'ed25519', privateKey: threadSigner?.privateKey });
+ setCurrentAnonSignerAddress(signer.address);
return signer;
} catch (error) {
console.error('Failed to retrieve anonymous signer:', error);
@@ -43,7 +46,11 @@ const useAnonMode = (postCid?: string) => {
};
const getExistingSigner = (address: string) => {
- return getAddressSigner(address);
+ const signer = getAddressSigner(address);
+ if (signer) {
+ setCurrentAnonSignerAddress(signer.address);
+ }
+ return signer;
};
return { anonMode, getNewSigner, getExistingSigner };
diff --git a/src/hooks/use-replies.ts b/src/hooks/use-replies.ts
index 0426f009..3da6f700 100644
--- a/src/hooks/use-replies.ts
+++ b/src/hooks/use-replies.ts
@@ -1,4 +1,4 @@
-import { useMemo, useCallback, useState, useEffect } from 'react';
+import { useMemo } from 'react';
import { Comment, useAccountComments } from '@plebbit/plebbit-react-hooks';
import { flattenCommentsPages } from '@plebbit/plebbit-react-hooks/dist/lib/utils';
@@ -9,37 +9,26 @@ const useReplies = (comment: Comment) => {
// generate a Set of CIDs from flattened replies for quick lookup
const replyCids = useMemo(() => new Set(flattenedReplies.map((reply) => reply?.cid)), [flattenedReplies]);
- const [filteredAccountComments, setFilteredAccountComments] = useState([]);
-
- const getPostCid = useCallback(
- (accountComment: Comment, allComments: Comment[]): string | null => {
- if (accountComment.parentCid === comment?.cid) {
- return comment?.cid;
- }
- const parent = allComments.find((c) => c.cid === accountComment.parentCid);
- if (!parent) {
- return null;
- }
- return getPostCid(parent, allComments);
- },
- [comment?.cid],
- );
-
const { accountComments } = useAccountComments();
- useEffect(() => {
- const filterComments = (comments: Comment[]) => {
- return comments.filter((accountComment) => {
- const parentCid = accountComment.parentCid;
- if (parentCid === (comment?.cid || 'n/a') || replyCids.has(parentCid)) {
+ const filteredAccountComments = useMemo(() => {
+ const commentMap = new Map(accountComments.map((c) => [c.cid, c]));
+
+ return accountComments.filter((accountComment) => {
+ let currentCid = accountComment.parentCid;
+ while (currentCid && currentCid !== comment?.cid) {
+ if (replyCids.has(currentCid)) {
return true;
}
- return getPostCid(accountComment, comments) === comment?.cid;
- });
- };
-
- setFilteredAccountComments(filterComments(accountComments));
- }, [accountComments, comment?.cid, replyCids, getPostCid]);
+ const parent = commentMap.get(currentCid);
+ if (!parent) {
+ return false;
+ }
+ currentCid = parent.parentCid;
+ }
+ return currentCid === comment?.cid;
+ });
+ }, [accountComments, comment?.cid, replyCids]);
// the account's replies have a delay before getting published, so get them locally from accountComments instead
const accountRepliesNotYetPublished = useMemo(() => {
diff --git a/src/stores/use-anon-mode-store.ts b/src/stores/use-anon-mode-store.ts
index d20ea97a..e9448766 100644
--- a/src/stores/use-anon-mode-store.ts
+++ b/src/stores/use-anon-mode-store.ts
@@ -10,6 +10,8 @@ interface AnonModeState {
getThreadSigner: (postCid: string) => any | undefined;
setAddressSigner: (signer: any) => void;
getAddressSigner: (address: string) => any | undefined;
+ currentAnonSignerAddress: string | null;
+ setCurrentAnonSignerAddress: (address: string | null) => void;
}
const anonModeStore = localForageLru.createInstance({
@@ -39,6 +41,11 @@ const useAnonModeStore = create((set, get) => ({
anonModeStore.setItem(signer.address, signer);
},
getAddressSigner: (address: string) => get().addressSigners[address],
+ currentAnonSignerAddress: null,
+ setCurrentAnonSignerAddress: (address: string | null) => {
+ set({ currentAnonSignerAddress: address });
+ anonModeStore.setItem('currentAnonSignerAddress', address);
+ },
}));
const initializeAnonModeStore = async () => {
@@ -57,15 +64,16 @@ const initializeAnonModeStore = async () => {
}
});
+ const currentAnonSignerAddress = await anonModeStore.getItem('currentAnonSignerAddress');
+
useAnonModeStore.setState((state) => ({
anonMode, // Set the retrieved anonMode state
threadSigners: { ...threadSigners, ...state.threadSigners },
addressSigners: { ...addressSigners, ...state.addressSigners },
+ currentAnonSignerAddress: currentAnonSignerAddress || null,
}));
};
initializeAnonModeStore();
-initializeAnonModeStore();
-
export default useAnonModeStore;
diff --git a/src/stores/use-avatar-visibility-store.ts b/src/stores/use-avatar-visibility-store.ts
new file mode 100644
index 00000000..aa2c3f7e
--- /dev/null
+++ b/src/stores/use-avatar-visibility-store.ts
@@ -0,0 +1,21 @@
+import { create } from 'zustand';
+import { persist } from 'zustand/middleware';
+
+interface AvatarVisibilityState {
+ hideAvatars: boolean;
+ setHideAvatars: (hide: boolean) => void;
+}
+
+const useAvatarVisibilityStore = create()(
+ persist(
+ (set) => ({
+ hideAvatars: false,
+ setHideAvatars: (hide) => set({ hideAvatars: hide }),
+ }),
+ {
+ name: 'avatar-visibility-storage',
+ },
+ ),
+);
+
+export default useAvatarVisibilityStore;
diff --git a/src/views/home/box-modal/box-modal.tsx b/src/views/home/box-modal/box-modal.tsx
index 1f7827d6..3a76b146 100644
--- a/src/views/home/box-modal/box-modal.tsx
+++ b/src/views/home/box-modal/box-modal.tsx
@@ -7,6 +7,7 @@ const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => {
const { t } = useTranslation();
const [showFilterModal, setShowFilterModal] = useState(false);
const modalRef = useRef(null);
+ const buttonRef = useRef(null);
const {
showNsfwBoardsOnly,
@@ -23,11 +24,11 @@ const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => {
const handleClickOutside = useCallback(
(event: MouseEvent) => {
- if (modalRef.current && !modalRef.current.contains(event.target as Node)) {
+ if (modalRef.current && !modalRef.current.contains(event.target as Node) && buttonRef.current && !buttonRef.current.contains(event.target as Node)) {
setShowFilterModal(false);
}
},
- [modalRef, setShowFilterModal],
+ [modalRef, buttonRef, setShowFilterModal],
);
useEffect(() => {
@@ -39,7 +40,7 @@ const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => {
return (
<>
- setShowFilterModal(true)}>
+ !showFilterModal && setShowFilterModal(true)}>
{isBoardsBoxModal ? t('filter') : t('options')} ▼
{showFilterModal && (