diff --git a/package.json b/package.json index 50b4898b..2863b403 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plebchan", - "version": "0.1.8", + "version": "0.1.9", "private": true, "dependencies": { "@adraffy/ens-normalize": "1.8.3", diff --git a/src/components/OfflineIndicator.jsx b/src/components/OfflineIndicator.jsx index 5f017117..3630a222 100644 --- a/src/components/OfflineIndicator.jsx +++ b/src/components/OfflineIndicator.jsx @@ -17,6 +17,7 @@ const OfflineIndicator = ({ address, className, tooltipPlace }) => { data-tooltip-id="tooltip" data-tooltip-content="Offline" data-tooltip-place={tooltipPlace} + style={{imageRendering: 'pixelated'}} /> )} diff --git a/src/components/PostOnHover.jsx b/src/components/PostOnHover.jsx index fbf7306c..12a1e650 100644 --- a/src/components/PostOnHover.jsx +++ b/src/components/PostOnHover.jsx @@ -85,8 +85,8 @@ const PostOnHover = ({ cid, feed }) => { {reply.replies?.pages?.topAll.comments .sort((a, b) => a.timestamp - b.timestamp) .map((reply, index) => ( -
- {}} +
+ {}} className="quote-link"> c/{reply.shortCid}   diff --git a/src/components/modals/AdminListModal.jsx b/src/components/modals/AdminListModal.jsx new file mode 100644 index 00000000..1b598878 --- /dev/null +++ b/src/components/modals/AdminListModal.jsx @@ -0,0 +1,82 @@ +import React, { useEffect, useState, useRef } from 'react'; +import Modal from 'react-modal'; +import Draggable from 'react-draggable'; +import { StyledModal } from '../styled/modals/ReplyModal.styled'; +import useGeneralStore from '../../hooks/stores/useGeneralStore'; +import { BoardForm } from '../styled/views/Board.styled' +import { Link } from 'react-router-dom'; + + + +const AdminListModal = ({ isOpen, closeModal, roles }) => { + const { + selectedAddress, + selectedStyle, + selectedTitle, + } = useGeneralStore(state => state); + + const [isMobile, setIsMobile] = useState(window.innerWidth <= 480); + const nodeRef = useRef(null); + const rolesList = roles + ? Object.entries(roles).map(([address, { role }]) => ({ address, role })) + : []; + + useEffect(() => { + const handleResize = () => setIsMobile(window.innerWidth <= 480); + window.addEventListener('resize', handleResize); + + // Cleanup function + return () => { + window.removeEventListener('resize', handleResize); + }; + }, [setIsMobile]); + + + return ( + + +
+
+ Admins for {selectedTitle ?? selectedAddress} +
+
+ + {rolesList.map(({ address, role }, index) => ( +

+ • {}} className="quote-link">u/{address}: {role} +

+ ))} +
+
+
+
+
+ ); +}; + +Modal.setAppElement('#root'); + +export default AdminListModal; \ No newline at end of file diff --git a/src/components/modals/ModerationModal.jsx b/src/components/modals/ModerationModal.jsx index fcd53b09..44caad8d 100755 --- a/src/components/modals/ModerationModal.jsx +++ b/src/components/modals/ModerationModal.jsx @@ -130,13 +130,20 @@ const ModerationModal = ({ isOpen, closeModal, deletePost }) => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); diff --git a/src/components/modals/ReplyModal.jsx b/src/components/modals/ReplyModal.jsx index feb8191a..a73ed331 100755 --- a/src/components/modals/ReplyModal.jsx +++ b/src/components/modals/ReplyModal.jsx @@ -188,43 +188,49 @@ const ReplyModal = ({ isOpen, closeModal }) => { }; - useEffect(() => { - const updateSigner = async () => { - if (anonymousMode) { - setExecuteAnonMode(true); + const updateSigner = useCallback(async () => { + if (anonymousMode) { + setExecuteAnonMode(true); - let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; - let signer; + let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; + let signer; - if (!storedSigners[selectedParentCid]) { - signer = await account?.plebbit.createSigner(); - storedSigners[selectedParentCid] = { privateKey: signer?.privateKey, address: signer?.address }; - localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + if (!storedSigners[selectedParentCid]) { + signer = await account?.plebbit.createSigner(); + storedSigners[selectedParentCid] = { privateKey: signer?.privateKey, address: signer?.address }; + localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + } else { + const signerPrivateKey = storedSigners[selectedParentCid].privateKey; - } else { - const signerPrivateKey = storedSigners[selectedParentCid].privateKey; - - try { - signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); - } catch (error) { - console.log(error); - } + try { + signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); + } catch (error) { + console.log(error); } + } - setPublishCommentOptions((prevPublishCommentOptions) => ({ + setPublishCommentOptions(prevPublishCommentOptions => { + const newPublishCommentOptions = { ...prevPublishCommentOptions, signer, author: { ...prevPublishCommentOptions.author, address: signer?.address }, - })); + }; - } - }; + if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) { + return newPublishCommentOptions; + } + return prevPublishCommentOptions; + }); + } + }, [selectedParentCid, anonymousMode, account]); + + useEffect(() => { updateSigner(); - }, [selectedParentCid, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]); + }, [updateSigner]); useEffect(() => { diff --git a/src/components/modals/SettingsModal.jsx b/src/components/modals/SettingsModal.jsx index fc5f3b28..f60d28bc 100755 --- a/src/components/modals/SettingsModal.jsx +++ b/src/components/modals/SettingsModal.jsx @@ -250,7 +250,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
  • - Automatically uses a different account (u/address) per thread. + Automatically use a different u/address per thread to post.
  • Account Data diff --git a/src/components/styled/views/Board.styled.jsx b/src/components/styled/views/Board.styled.jsx index 8a9d1a60..0779b1fc 100644 --- a/src/components/styled/views/Board.styled.jsx +++ b/src/components/styled/views/Board.styled.jsx @@ -1678,13 +1678,13 @@ export const BoardForm = styled.div` .offline-sub { width: 16px; - margin: -5px -4px -4px 3px; + margin: -5px -4px -2px 3px; position: relative; } .offline-reply { width: 16px; - margin: -5px -4px -4px 3px; + margin: -5px -4px -2px 3px; position: relative; } diff --git a/src/components/views/All.jsx b/src/components/views/All.jsx index 7f647b9d..34dd3b47 100755 --- a/src/components/views/All.jsx +++ b/src/components/views/All.jsx @@ -102,23 +102,11 @@ const All = () => { const [moderatorPermissions, setModeratorPermissions] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); - const [displayedReplies, setDisplayedReplies] = useState([]); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; } - // let post.jsx access full cid of user-typed short cid - useEffect(() => { - const newCidTracker = {}; - displayedReplies.forEach((reply) => { - newCidTracker[reply.shortCid] = reply.cid; - }); - setCidTracker(newCidTracker); - }, [displayedReplies]); - - useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); - useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address); @@ -251,6 +239,19 @@ const All = () => { }, {}); }, [flattenedRepliesByThread, accountComments, selectedFeed]); + const allReplies = useMemo(() => { + return selectedFeed.flatMap(thread => filteredRepliesByThread[thread.cid]?.displayedReplies || []); + }, [selectedFeed, filteredRepliesByThread]); + + // let post.jsx access full cid of user-typed short cid + useEffect(() => { + const newCidTracker = {}; + allReplies.forEach((reply) => { + newCidTracker[reply.shortCid] = reply.cid; + }); + setCidTracker(newCidTracker); + }, [allReplies]); + // mobile navbar scroll effect useEffect(() => { const debouncedHandleScroll = debounce(() => { @@ -415,13 +416,20 @@ const All = () => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); // desktop navbar board select functionality const handleClickTitle = (title, address) => { @@ -597,7 +605,6 @@ const All = () => { data={selectedFeed} itemContent={(index, thread) => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; - setDisplayedReplies(displayedReplies); const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = "assets/filedeleted-res.gif"; const isModerator = moderatorPermissions[thread.subplebbitAddress]; diff --git a/src/components/views/AllCatalog.jsx b/src/components/views/AllCatalog.jsx index ec08f7f5..63fa7b1c 100755 --- a/src/components/views/AllCatalog.jsx +++ b/src/components/views/AllCatalog.jsx @@ -278,13 +278,20 @@ const AllCatalog = () => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); // mobile navbar board select functionality diff --git a/src/components/views/Board.jsx b/src/components/views/Board.jsx index 0abe590a..2153687b 100755 --- a/src/components/views/Board.jsx +++ b/src/components/views/Board.jsx @@ -14,6 +14,7 @@ import { PostMenuCatalog } from '../styled/views/Catalog.styled'; import EditModal from '../modals/EditModal'; import EditLabel from '../EditLabel'; import ImageBanner from '../ImageBanner'; +import AdminListModal from '../modals/AdminListModal'; import ModerationModal from '../modals/ModerationModal'; import OfflineIndicator from '../OfflineIndicator'; import PendingLabel from '../PendingLabel'; @@ -100,6 +101,7 @@ const Board = () => { const { subscribed, subscribe, unsubscribe } = useSubscribe({subplebbitAddress: selectedAddress}); const stateString = useStateString(subplebbit); + const [isAdminListOpen, setIsAdminListOpen] = useState(false); const [isReplyOpen, setIsReplyOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [originalCommentContent, setOriginalCommentContent] = useState(null); @@ -119,20 +121,8 @@ const Board = () => { const [postOnHoverHeight, setPostOnHoverHeight] = useState(0); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); - const [displayedReplies, setDisplayedReplies] = useState([]); - const setSelectedThreadCid = (cid) => { - selectedThreadCidRef.current = cid; - } - - // let post.jsx access full cid of user-typed short cid - useEffect(() => { - const newCidTracker = {}; - displayedReplies.forEach((reply) => { - newCidTracker[reply.shortCid] = reply.cid; - }); - setCidTracker(newCidTracker); - }, [displayedReplies]); + const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid;} useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); @@ -244,6 +234,19 @@ const Board = () => { return acc; }, {}); }, [flattenedRepliesByThread, accountComments, selectedFeed]); + + const allReplies = useMemo(() => { + return selectedFeed.flatMap(thread => filteredRepliesByThread[thread.cid]?.displayedReplies || []); + }, [selectedFeed, filteredRepliesByThread]); + + // let post.jsx access full cid of user-typed short cid + useEffect(() => { + const newCidTracker = {}; + allReplies.forEach((reply) => { + newCidTracker[reply.shortCid] = reply.cid; + }); + setCidTracker(newCidTracker); + }, [allReplies]); // temporary title from JSON, gets subplebbitAddress from URL @@ -380,43 +383,49 @@ const Board = () => { }; - useEffect(() => { - const updateSigner = async () => { - if (anonymousMode) { - setExecuteAnonMode(true); + const updateSigner = useCallback(async () => { + if (anonymousMode) { + setExecuteAnonMode(true); - let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; - let signer; + let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; + let signer; - if (!storedSigners[selectedThreadCidRef]) { - signer = await account?.plebbit.createSigner(); - storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address }; - localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + if (!storedSigners[selectedThreadCidRef]) { + signer = await account?.plebbit.createSigner(); + storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address }; + localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + } else { + const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey; - } else { - const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey; - - try { - signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); - } catch (error) { - console.log(error); - } + try { + signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); + } catch (error) { + console.log(error); } + } - setPublishCommentOptions((prevPublishCommentOptions) => ({ + setPublishCommentOptions(prevPublishCommentOptions => { + const newPublishCommentOptions = { ...prevPublishCommentOptions, signer, author: { ...prevPublishCommentOptions.author, address: signer?.address }, - })); + }; - } - }; + if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) { + return newPublishCommentOptions; + } + return prevPublishCommentOptions; + }); + } + }, [selectedThreadCidRef, anonymousMode, account]); + + useEffect(() => { updateSigner(); - }, [selectedThreadCidRef, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]); + }, [updateSigner]); @@ -543,13 +552,21 @@ const Board = () => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); + // desktop navbar board select functionality const handleClickTitle = (title, address) => { @@ -609,6 +626,21 @@ const Board = () => { {((selectedTitle ? selectedTitle : selectedAddress) + " - plebchan")} + setIsAdminListOpen(false)} + roles={subplebbit.roles} /> + setIsEditModalOpen(false)} + originalCommentContent={originalCommentContent} /> + {setIsModerationOpen(false); setDeletePost(false)}} + deletePost={deletePost} /> { selectedStyle={selectedStyle} isOpen={isSettingsOpen} closeModal={() => setIsSettingsOpen(false)} /> - {setIsModerationOpen(false); setDeletePost(false)}} - deletePost={deletePost} /> - setIsEditModalOpen(false)} - originalCommentContent={originalCommentContent} /> <> @@ -821,13 +843,18 @@ const Board = () => { Rules   - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   {getDate(subplebbit.createdAt)}   - Sticky + Sticky   - Closed + Closed   [ Reply @@ -893,13 +920,18 @@ const Board = () => { - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   - Sticky + Sticky   - Closed + Closed
    { Welcome to {subplebbit.title || subplebbit.address}   - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   {getDate(subplebbit.createdAt)}   - Sticky + Sticky   - Closed + Closed   [ Reply @@ -1030,13 +1067,18 @@ const Board = () => { - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   - Sticky + Sticky   - Closed + Closed
    { data={selectedFeed} itemContent={(index, thread) => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; - setDisplayedReplies(displayedReplies); const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = "assets/filedeleted-res.gif"; return ( @@ -1201,14 +1242,18 @@ const Board = () => { <>   Sticky + style={{marginBottom: "-1px", + imageRendering: "pixelated",}} /> ) : null} {thread.locked ? ( <>   Closed + style={{ + marginBottom: "-1px", + imageRendering: "pixelated", + }} /> ) : null}   @@ -1959,11 +2004,13 @@ const Board = () => { {thread.pinned ? ( Sticky + style={{marginTop: "-1px", marginRight: "2px", + imageRendering: "pixelated",}} /> ) : null} {thread.locked ? ( Closed + style={{marginTop: "-1px", marginRight: "2px", + imageRendering: "pixelated",}} /> ) : null}
    diff --git a/src/components/views/Catalog.jsx b/src/components/views/Catalog.jsx index 95ff9e8a..40b175cf 100755 --- a/src/components/views/Catalog.jsx +++ b/src/components/views/Catalog.jsx @@ -282,43 +282,49 @@ const Catalog = () => { }; - useEffect(() => { - const updateSigner = async () => { - if (anonymousMode) { - setExecuteAnonMode(true); + const updateSigner = useCallback(async () => { + if (anonymousMode) { + setExecuteAnonMode(true); - let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; - let signer; + let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; + let signer; - if (!storedSigners[selectedThreadCidRef]) { - signer = await account?.plebbit.createSigner(); - storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address }; - localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + if (!storedSigners[selectedThreadCidRef]) { + signer = await account?.plebbit.createSigner(); + storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address }; + localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + } else { + const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey; - } else { - const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey; - - try { - signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); - } catch (error) { - console.log(error); - } + try { + signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); + } catch (error) { + console.log(error); } + } - setPublishCommentOptions((prevPublishCommentOptions) => ({ + setPublishCommentOptions(prevPublishCommentOptions => { + const newPublishCommentOptions = { ...prevPublishCommentOptions, signer, author: { ...prevPublishCommentOptions.author, address: signer?.address }, - })); + }; - } - }; + if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) { + return newPublishCommentOptions; + } + return prevPublishCommentOptions; + }); + } + }, [selectedThreadCidRef, anonymousMode, account]); + + useEffect(() => { updateSigner(); - }, [selectedThreadCidRef, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]); + }, [updateSigner]); useEffect(() => { @@ -706,8 +712,12 @@ const Catalog = () => { R:0
    - - + +
    { {subplebbit.suggested?.avatarUrl ? (
    - - + +
    ) : null} @@ -783,8 +797,12 @@ const Catalog = () => { {subplebbit.suggested?.avatarUrl ? null : (
    - - + +
    )} { commentMediaInfo.thumbnail))) ? (
    {thread.pinned ? ( - + ) : null} {thread.locked ? ( - + ) : null}
    ) : null} @@ -937,10 +959,14 @@ const Catalog = () => {
    {thread.pinned ? ( - + ) : null} {thread.locked ? ( - + ) : null}
    )} diff --git a/src/components/views/Description.jsx b/src/components/views/Description.jsx index c61204fa..1120b019 100644 --- a/src/components/views/Description.jsx +++ b/src/components/views/Description.jsx @@ -9,6 +9,7 @@ import { Container, NavBar, Header, Break, PostMenu, PostForm } from '../styled/ import { TopBar, BoardForm, Footer, ReplyFormLink} from '../styled/views/Thread.styled'; import { PostMenuCatalog } from '../styled/views/Catalog.styled'; import ImageBanner from '../ImageBanner'; +import AdminListModal from '../modals/AdminListModal'; import OfflineIndicator from '../OfflineIndicator'; import SettingsModal from '../modals/SettingsModal'; import getDate from '../../utils/getDate'; @@ -35,6 +36,7 @@ const Description = () => { const postMenuRef = useRef(null); const postMenuCatalogRef = useRef(null); + const [isAdminListOpen, setIsAdminListOpen] = useState(false); const [prevScrollPos, setPrevScrollPos] = useState(0); const [visible, setVisible] = useState(true); const [menuPosition, setMenuPosition] = useState({top: 0, left: 0}); @@ -123,6 +125,11 @@ const Description = () => { + setIsAdminListOpen(false)} + roles={subplebbit.roles} /> { Welcome to {subplebbit.title || subplebbit.address}   - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   {getDate(subplebbit.createdAt)}   - Sticky + Sticky   - Closed + Closed   [ {}} style={{textDecoration: "none"}} className="reply-link">Reply @@ -362,13 +372,16 @@ const Description = () => { - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   - Sticky + Sticky   - Closed + Closed
    { const postMenuRef = useRef(null); const postMenuCatalogRef = useRef(null); + const [isAdminListOpen, setIsAdminListOpen] = useState(false); const [prevScrollPos, setPrevScrollPos] = useState(0); const [visible, setVisible] = useState(true); const [menuPosition, setMenuPosition] = useState({top: 0, left: 0}); @@ -122,6 +124,11 @@ const Rules = () => { + setIsAdminListOpen(false)} + roles={subplebbit.roles} /> { Rules   - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   {getDate(subplebbit.createdAt)}   - Sticky + Sticky   - Closed + Closed   [ {}} style={{textDecoration: "none"}} className="reply-link">Reply @@ -342,13 +352,16 @@ const Rules = () => { - ## Board Admins + {setIsAdminListOpen(!isAdminListOpen)}} + >## Board Admins   - Sticky + Sticky   - Closed + Closed
    { const [moderatorPermissions, setModeratorPermissions] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); - const [displayedReplies, setDisplayedReplies] = useState([]); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; } - - // let post.jsx access full cid of user-typed short cid - useEffect(() => { - const newCidTracker = {}; - displayedReplies.forEach((reply) => { - newCidTracker[reply.shortCid] = reply.cid; - }); - setCidTracker(newCidTracker); - }, [displayedReplies]); - + useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'}); @@ -249,6 +239,19 @@ const Subscriptions = () => { }, {}); }, [flattenedRepliesByThread, accountComments, selectedFeed]); + const allReplies = useMemo(() => { + return selectedFeed.flatMap(thread => filteredRepliesByThread[thread.cid]?.displayedReplies || []); + }, [selectedFeed, filteredRepliesByThread]); + + // let post.jsx access full cid of user-typed short cid + useEffect(() => { + const newCidTracker = {}; + allReplies.forEach((reply) => { + newCidTracker[reply.shortCid] = reply.cid; + }); + setCidTracker(newCidTracker); + }, [allReplies]); + // mobile navbar scroll effect useEffect(() => { const debouncedHandleScroll = debounce(() => { @@ -415,13 +418,20 @@ const Subscriptions = () => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); // desktop navbar board select functionality const handleClickTitle = (title, address) => { @@ -605,7 +615,6 @@ const Subscriptions = () => { data={selectedFeed} itemContent={(index, thread) => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; - setDisplayedReplies(displayedReplies); const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = "assets/filedeleted-res.gif"; const isModerator = moderatorPermissions[thread.subplebbitAddress]; diff --git a/src/components/views/SubscriptionsCatalog.jsx b/src/components/views/SubscriptionsCatalog.jsx index ef0762c8..34ee696a 100755 --- a/src/components/views/SubscriptionsCatalog.jsx +++ b/src/components/views/SubscriptionsCatalog.jsx @@ -275,13 +275,20 @@ const SubscriptionsCatalog = () => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); // desktop navbar board select functionality const handleClickTitle = (title, address) => { diff --git a/src/components/views/Thread.jsx b/src/components/views/Thread.jsx index 4d7df7dc..b714d8be 100755 --- a/src/components/views/Thread.jsx +++ b/src/components/views/Thread.jsx @@ -347,43 +347,49 @@ const Thread = () => { }; - useEffect(() => { - const updateSigner = async () => { - if (anonymousMode) { - setExecuteAnonMode(true); + const updateSigner = useCallback(async () => { + if (anonymousMode) { + setExecuteAnonMode(true); - let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; - let signer; + let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; + let signer; - if (!storedSigners[selectedThread]) { - signer = await account?.plebbit.createSigner(); - storedSigners[selectedThread] = { privateKey: signer?.privateKey, address: signer?.address }; - localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + if (!storedSigners[selectedThread]) { + signer = await account?.plebbit.createSigner(); + storedSigners[selectedThread] = { privateKey: signer?.privateKey, address: signer?.address }; + localStorage.setItem('storedSigners', JSON.stringify(storedSigners)); + } else { + const signerPrivateKey = storedSigners[selectedThread].privateKey; - } else { - const signerPrivateKey = storedSigners[selectedThread].privateKey; - - try { - signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); - } catch (error) { - console.log(error); - } + try { + signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey}); + } catch (error) { + console.log(error); } + } - setPublishCommentOptions((prevPublishCommentOptions) => ({ + setPublishCommentOptions(prevPublishCommentOptions => { + const newPublishCommentOptions = { ...prevPublishCommentOptions, signer, author: { ...prevPublishCommentOptions.author, address: signer?.address }, - })); + }; - } - }; + if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) { + return newPublishCommentOptions; + } + return prevPublishCommentOptions; + }); + } + }, [selectedThread, anonymousMode, account]); + + useEffect(() => { updateSigner(); - }, [selectedThread, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]); + }, [updateSigner]); useEffect(() => { @@ -509,13 +515,20 @@ const Thread = () => { useEffect(() => { + let isActive = true; if (publishCommentEditOptions && triggerPublishCommentEdit) { (async () => { await publishCommentEdit(); - setTriggerPublishCommentEdit(false); + if (isActive) { + setTriggerPublishCommentEdit(false); + } })(); } - }, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]); + + return () => { + isActive = false; + }; + }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]); // mobile navbar board select functionality const handleSelectChange = (event) => { @@ -893,14 +906,16 @@ const Thread = () => { <>   Sticky + style={{marginBottom: "-1px", + imageRendering: "pixelated",}} /> ) : null} {comment.locked ? ( <>   Closed + style={{marginBottom: "-1px", + imageRendering: "pixelated",}} /> ) : null} {
    + + {comment.pinned ? ( + Sticky + ) : null} + {comment.locked ? ( + Closed + ) : null} +
    {comment.title ? ( comment.title.length > 30 ? diff --git a/yarn.lock b/yarn.lock index 10ff9117..e1ae8c3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2722,21 +2722,6 @@ uuid "8.3.2" zustand "4.0.0" -"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#efa802a1af8c75362e0d9a9afe1bc769f54e34cd": - version "0.0.1" - resolved "https://github.com/plebbit/plebbit-react-hooks.git#efa802a1af8c75362e0d9a9afe1bc769f54e34cd" - dependencies: - "@plebbit/plebbit-js" "https://github.com/plebbit/plebbit-js.git#77a05093408982086c02afea24e1d1923e1ae8a8" - "@plebbit/plebbit-logger" "https://github.com/plebbit/plebbit-logger.git" - assert "2.0.0" - ethers "5.6.9" - localforage "1.10.0" - lodash.isequal "4.5.0" - memoizee "0.4.15" - quick-lru "5.1.1" - uuid "8.3.2" - zustand "4.0.0" - "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": version "0.5.10" resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"