From e9cfdac18f7111a0fe42900c6f56133ce1819d14 Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Fri, 29 Sep 2023 11:44:05 +0200 Subject: [PATCH] feat(views): show board admin role next to usernames, if any, with capcode colors and admin modal function --- src/components/styled/views/Board.styled.jsx | 76 ++++++++++++- src/components/styled/views/Thread.styled.jsx | 105 ++++++++++++++++-- src/components/views/All.jsx | 72 ++++++++++-- src/components/views/Board.jsx | 89 ++++++++++++--- src/components/views/Subscriptions.jsx | 72 ++++++++++-- src/components/views/Thread.jsx | 76 ++++++++++++- 6 files changed, 433 insertions(+), 57 deletions(-) diff --git a/src/components/styled/views/Board.styled.jsx b/src/components/styled/views/Board.styled.jsx index d7fd8f46..52a7ef36 100644 --- a/src/components/styled/views/Board.styled.jsx +++ b/src/components/styled/views/Board.styled.jsx @@ -1698,10 +1698,6 @@ export const BoardForm = styled.div` margin-right: 14px; } - .capcode-admin { - color: red !important; - } - .ellipsis:after { content: '\\2026'; position: absolute; @@ -1811,6 +1807,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } #post-menu { @@ -1838,6 +1840,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } #post-menu { @@ -1862,6 +1870,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } #post-menu { @@ -1886,6 +1900,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } #post-menu { @@ -1911,6 +1931,12 @@ export const BoardForm = styled.div` .capcode { color: #81a2be !important; + cursor: pointer; + } + + .capcode-admin { + color: #81a2be !important; + cursor: pointer; } #post-menu { @@ -1935,6 +1961,12 @@ export const BoardForm = styled.div` .capcode { color: #f60 !important; + cursor: pointer; + } + + .capcode-admin { + color: #f60 !important; + cursor: pointer; } #post-menu { @@ -3367,6 +3399,12 @@ export const BoardForm = styled.div` return ` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .op-container { background-color: #f5e9e1; @@ -3487,6 +3525,12 @@ export const BoardForm = styled.div` return ` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .op-container { background-color: #d6daf0; @@ -3603,6 +3647,12 @@ export const BoardForm = styled.div` return ` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .op-container { background-color: #f5e9e1; @@ -3722,6 +3772,12 @@ export const BoardForm = styled.div` return ` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .op-container { background-color: #d6daf0; @@ -3837,6 +3893,12 @@ export const BoardForm = styled.div` return ` .capcode { color: #81a2be !important; + cursor: pointer; + } + + .capcode-admin { + color: #81a2be !important; + cursor: pointer; } .op-container { @@ -3963,6 +4025,12 @@ export const BoardForm = styled.div` return ` .capcode { color: #f60 !important; + cursor: pointer; + } + + .capcode-admin { + color: #f60 !important; + cursor: pointer; } .op-container { background-color: #eee; diff --git a/src/components/styled/views/Thread.styled.jsx b/src/components/styled/views/Thread.styled.jsx index 184533df..5803acad 100644 --- a/src/components/styled/views/Thread.styled.jsx +++ b/src/components/styled/views/Thread.styled.jsx @@ -906,10 +906,6 @@ export const BoardForm = styled.div` margin-right: 14px; } - .capcode-admin { - color: red !important; - } - .ellipsis:after { content: '\\2026'; position: absolute; @@ -1001,6 +997,16 @@ export const BoardForm = styled.div` border-left: none !important; border-top: none !important; } + + .capcode { + color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; + } #post-menu { ul { @@ -1026,6 +1032,16 @@ export const BoardForm = styled.div` border-left: none !important; border-top: none !important; } + + .capcode { + color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; + } #post-menu { ul { @@ -1047,6 +1063,16 @@ export const BoardForm = styled.div` return `.highlighted, .highlighted-click, .highlighted-address { background-color: #f0c0b0 !important; } + + .capcode { + color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; + } #post-menu { font-size: 13px !important; @@ -1070,6 +1096,16 @@ export const BoardForm = styled.div` return `.highlighted, .highlighted-click, .highlighted-address { background-color: #d6bad0 !important; } + + .capcode { + color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; + } #post-menu { font-size: 13px !important; @@ -1094,6 +1130,16 @@ export const BoardForm = styled.div` background-color: #1d1d21 !important; outline: 1px solid #111 !important; } + + .capcode { + color: #81a2be !important; + cursor: pointer; + } + + .capcode-admin { + color: #81a2be !important; + cursor: pointer; + } #post-menu { ul { @@ -1116,6 +1162,16 @@ export const BoardForm = styled.div` background-color: #ccc !important; outline: 1px solid #ccc !important; } + + .capcode { + color: #f60 !important; + cursor: pointer; + } + + .capcode-admin { + color: #f60 !important; + cursor: pointer; + } #post-menu { ul { @@ -2506,6 +2562,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .subject-mobile { @@ -2627,6 +2689,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .subject-mobile { @@ -2744,11 +2812,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; } - - .subject-mobile { - color: #cc1105; - font-weight: 700; + + .capcode-admin { + color: red !important; + cursor: pointer; } .date-time-mobile { @@ -2864,6 +2933,12 @@ export const BoardForm = styled.div` .capcode { color: purple !important; + cursor: pointer; + } + + .capcode-admin { + color: red !important; + cursor: pointer; } .subject-mobile { @@ -2980,6 +3055,12 @@ export const BoardForm = styled.div` .capcode { color: #81a2be !important; + cursor: pointer; + } + + .capcode-admin { + color: #81a2be !important; + cursor: pointer; } .poster-address-mobile { @@ -3106,7 +3187,13 @@ export const BoardForm = styled.div` .capcode { color: #f60 !important; - } + cursor: pointer; + } + + .capcode-admin { + color: #f60 !important; + cursor: pointer; + } .subject-mobile { color: #111; diff --git a/src/components/views/All.jsx b/src/components/views/All.jsx index dcd03dda..6d759ee2 100755 --- a/src/components/views/All.jsx +++ b/src/components/views/All.jsx @@ -119,6 +119,7 @@ const All = () => { const [postOnHoverHeight, setPostOnHoverHeight] = useState(0); const [deletePost, setDeletePost] = useState(false); const [moderatorPermissions, setModeratorPermissions] = useState({}); + const [moderatorRole, setModeratorRole] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); const [isThreadThumbnailClicked, setIsThreadThumbnailClicked] = useState({}); @@ -180,6 +181,7 @@ const All = () => { useEffect(() => { let permissions = {}; + let roles = {}; selectedFeed.forEach((thread) => { const subplebbit = subplebbits.find((s) => s && s.address === thread.subplebbitAddress); @@ -192,10 +194,16 @@ const All = () => { } else { permissions[thread.subplebbitAddress] = false; } + + if (!roles[thread.subplebbitAddress]) { + roles[thread.subplebbitAddress] = {}; + } + roles[thread.subplebbitAddress][account?.author.address] = role; } }); setModeratorPermissions(permissions); + setModeratorRole(roles); }, [account?.author.address, selectedFeed, subplebbits]); const handleOptionClick = () => { @@ -718,6 +726,10 @@ const All = () => { const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = 'assets/filedeleted-res.gif'; const canModerate = moderatorPermissions[thread.subplebbitAddress]; + const userRole = moderatorRole[thread.subplebbitAddress]?.[thread?.author.address] || 'user'; + const isOwner = userRole === 'owner'; + const isAdmin = userRole === 'admin'; + const isModerator = userRole === 'moderator'; let displayWidth, displayHeight, displayWidthMobile, displayHeightMobile; if (thread.linkWidth && thread.linkHeight) { let scale = Math.min(1, 250 / Math.max(thread.linkWidth, thread.linkHeight)); @@ -897,7 +909,7 @@ const All = () => { { ) : ( - + {thread.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}  (u/ { } const replyMediaInfo = getCommentMediaInfo(reply); const fallbackImgUrl = 'assets/filedeleted-res.gif'; + const userRole = moderatorRole[reply.subplebbitAddress]?.[reply?.author.address] || 'user'; + const isOwner = userRole === 'owner'; + const isAdmin = userRole === 'admin'; + const isModerator = userRole === 'moderator'; const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; @@ -1283,7 +1306,7 @@ const All = () => { { ) : ( - + {reply.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}  (u/ { { ) : ( - + {thread.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}   { } const replyMediaInfo = getCommentMediaInfo(reply); const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); + const userRole = moderatorRole[reply.subplebbitAddress]?.[reply?.author.address] || 'user'; + const isOwner = userRole === 'owner'; + const isAdmin = userRole === 'admin'; + const isModerator = userRole === 'moderator'; let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; if (storedSigners[selectedThreadCidRef]) { @@ -2578,7 +2619,7 @@ const All = () => { { ) : ( - + {reply.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}   { useEffect(() => { if (subplebbit?.roles !== undefined) { - const role = subplebbit?.roles[account?.author.address]?.role; + const role = subplebbit?.roles?.[account?.author.address]?.role; if (role === 'moderator' || role === 'admin' || role === 'owner') { setCanModerate(true); @@ -933,7 +933,7 @@ const Board = () => { > Catalog - ]{subplebbit.roles && subplebbit?.roles[account?.author?.address]?.role === 'admin' ? : null} + ]{subplebbit.roles && subplebbit?.roles?.[account?.author?.address]?.role === 'admin' ? : null} {subplebbit?.state === 'succeeded' ? ( <> @@ -1744,6 +1744,9 @@ const Board = () => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = 'assets/filedeleted-res.gif'; + const isOwner = subplebbit?.roles?.[thread.author.address]?.role === 'owner'; + const isAdmin = subplebbit?.roles?.[thread.author.address]?.role === 'admin'; + const isModerator = subplebbit?.roles?.[thread.author.address]?.role === 'moderator'; let displayWidth, displayHeight, displayWidthMobile, displayHeightMobile; if (thread.linkWidth && thread.linkHeight) { let scale = Math.min(1, 250 / Math.max(thread.linkWidth, thread.linkHeight)); @@ -1923,7 +1926,7 @@ const Board = () => { { ) : ( - + {thread.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}  (u/ { } const replyMediaInfo = getCommentMediaInfo(reply); const fallbackImgUrl = 'assets/filedeleted-res.gif'; + const isOwner = subplebbit?.roles?.[reply.author.address]?.role === 'owner'; + const isAdmin = subplebbit?.roles?.[reply.author.address]?.role === 'admin'; + const isModerator = subplebbit?.roles?.[reply.author.address]?.role === 'moderator'; const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; @@ -2328,7 +2347,7 @@ const Board = () => { { ) : ( - + {reply.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}  (u/ { { ) : ( - + {thread.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}   { {displayedReplies?.map((reply, index) => { const replyMediaInfo = getCommentMediaInfo(reply); const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); + const isOwner = subplebbit?.roles?.[reply.author.address]?.role === 'owner'; + const isAdmin = subplebbit?.roles?.[reply.author.address]?.role === 'admin'; + const isModerator = subplebbit?.roles?.[reply.author.address]?.role === 'moderator'; let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; if (storedSigners[selectedThreadCidRef]) { @@ -3644,7 +3692,7 @@ const Board = () => { { ) : ( - + {reply.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}   { const [postOnHoverHeight, setPostOnHoverHeight] = useState(0); const [deletePost, setDeletePost] = useState(false); const [moderatorPermissions, setModeratorPermissions] = useState({}); + const [moderatorRole, setModeratorRole] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); const [isThreadThumbnailClicked, setIsThreadThumbnailClicked] = useState({}); @@ -179,6 +180,7 @@ const Subscriptions = () => { useEffect(() => { let permissions = {}; + let roles = {}; selectedFeed.forEach((thread) => { const subplebbit = subplebbits.find((s) => s && s.address === thread.subplebbitAddress); @@ -191,10 +193,16 @@ const Subscriptions = () => { } else { permissions[thread.subplebbitAddress] = false; } + + if (!roles[thread.subplebbitAddress]) { + roles[thread.subplebbitAddress] = {}; + } + roles[thread.subplebbitAddress][account?.author.address] = role; } }); setModeratorPermissions(permissions); + setModeratorRole(roles); }, [account?.author.address, selectedFeed, subplebbits]); const handleOptionClick = () => { @@ -722,6 +730,10 @@ const Subscriptions = () => { const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = 'assets/filedeleted-res.gif'; const canModerate = moderatorPermissions[thread.subplebbitAddress]; + const userRole = moderatorRole[thread.subplebbitAddress]?.[thread?.author.address] || 'user'; + const isOwner = userRole === 'owner'; + const isAdmin = userRole === 'admin'; + const isModerator = userRole === 'moderator'; let displayWidth, displayHeight, displayWidthMobile, displayHeightMobile; if (thread.linkWidth && thread.linkHeight) { let scale = Math.min(1, 250 / Math.max(thread.linkWidth, thread.linkHeight)); @@ -901,7 +913,7 @@ const Subscriptions = () => { { ) : ( - + {thread.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}  (u/ { } const replyMediaInfo = getCommentMediaInfo(reply); const fallbackImgUrl = 'assets/filedeleted-res.gif'; + const userRole = moderatorRole[reply.subplebbitAddress]?.[reply?.author.address] || 'user'; + const isOwner = userRole === 'owner'; + const isAdmin = userRole === 'admin'; + const isModerator = userRole === 'moderator'; const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; @@ -1293,7 +1316,7 @@ const Subscriptions = () => { { ) : ( - + {reply.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}  (u/ { { ) : ( - + {thread.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}   { } const replyMediaInfo = getCommentMediaInfo(reply); const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); + const userRole = moderatorRole[reply.subplebbitAddress]?.[reply?.author.address] || 'user'; + const isOwner = userRole === 'owner'; + const isAdmin = userRole === 'admin'; + const isModerator = userRole === 'moderator'; let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; if (storedSigners[selectedThreadCidRef]) { @@ -2588,7 +2629,7 @@ const Subscriptions = () => { { ) : ( - + {reply.author.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( +  ## Board Owner + ) : isAdmin ? ( +  ## Board Admin + ) : isModerator ? ( +  ## Board Mod + ) : null}   { useAnonMode(selectedThread, anonymousMode && executeAnonMode); + const [isAdminListOpen, setIsAdminListOpen] = useState(false); const originalComment = useComment({ commentCid: selectedThread }); const [comment, setComment] = useState(originalComment); const { subplebbitAddress, threadCid } = useParams(); const subplebbit = useSubplebbit({ subplebbitAddress: originalComment.subplebbitAddress }); const selectedAddress = subplebbit.address; + const isOwner = subplebbit?.roles?.[comment.author?.address]?.role === 'owner'; + const isAdmin = subplebbit?.roles?.[comment.author?.address]?.role === 'admin'; + const isModerator = subplebbit?.roles?.[comment.author?.address]?.role === 'moderator'; const stateString = useStateString(comment); @@ -642,6 +647,7 @@ const Thread = () => { + setIsAdminListOpen(false)} roles={subplebbit?.roles} /> setIsCreateBoardOpen(false)} /> setIsReplyOpen(false)} /> setIsSettingsOpen(false)} /> @@ -1078,7 +1084,7 @@ const Thread = () => { <> { ) : ( - + {comment?.author?.displayName} ) ) : ( - + Anonymous )} + {isOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}   { } const replyMediaInfo = getCommentMediaInfo(reply); const fallbackImgUrl = 'assets/filedeleted-res.gif'; + const isReplyOwner = subplebbit?.roles?.[reply.author.address]?.role === 'owner'; + const isReplyAdmin = subplebbit?.roles?.[reply.author.address]?.role === 'admin'; + const isReplyModerator = subplebbit?.roles?.[reply.author.address]?.role === 'moderator'; const shortParentCid = findShortParentCid(reply.parentCid, comment); let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; @@ -1404,7 +1426,7 @@ const Thread = () => { <> { ) : ( - + {reply.author?.displayName ?? reply.displayName} ) ) : ( - + Anonymous )} + {isReplyOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isReplyAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isReplyModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}  (u/ { Anonymous )} + {isOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}   { {sortedReplies.map((reply, index) => { const replyMediaInfo = getCommentMediaInfo(reply); const shortParentCid = findShortParentCid(reply.parentCid, comment); + const isReplyOwner = subplebbit?.roles?.[reply.author.address]?.role === 'owner'; + const isReplyAdmin = subplebbit?.roles?.[reply.author.address]?.role === 'admin'; + const isReplyModerator = subplebbit?.roles?.[reply.author.address]?.role === 'moderator'; let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {}; let signerAddress; if (storedSigners[selectedThread]) { @@ -2498,6 +2549,19 @@ const Thread = () => { Anonymous )} + {isReplyOwner ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Owner + + ) : isReplyAdmin ? ( + setIsAdminListOpen(true)} className='name capcode-admin'> +  ## Board Admin + + ) : isReplyModerator ? ( + setIsAdminListOpen(true)} className='name capcode'> +  ## Board Mod + + ) : null}  (u/