diff --git a/src/components/PendingLabel.jsx b/src/components/PendingLabel.jsx index 42e1a2a5..d8862ddd 100644 --- a/src/components/PendingLabel.jsx +++ b/src/components/PendingLabel.jsx @@ -1,17 +1,19 @@ -import React, { useState, useEffect } from "react"; +import React +// , { useState, useEffect } + from "react"; import { useAccountComment } from "@plebbit/plebbit-react-hooks"; -import useStateString from "../hooks/useStateString"; +// import useStateString from "../hooks/useStateString"; const PendingLabel = ({ commentIndex }) => { const comment = useAccountComment({commentIndex: commentIndex}); - const stateString = useStateString(comment); + // const stateString = useStateString(comment); - const [isLoading, setIsLoading] = useState(true); + // const [isLoading, setIsLoading] = useState(true); - useEffect(() => { - const timer = setTimeout(() => setIsLoading(false), 2000); - return () => clearTimeout(timer); - }, []); + // useEffect(() => { + // const timer = setTimeout(() => setIsLoading(false), 2000); + // return () => clearTimeout(timer); + // }, []); if (commentIndex === undefined) return null; @@ -19,7 +21,9 @@ const PendingLabel = ({ commentIndex }) => { comment.cid ? ( {comment.cid.slice(2, 14)} ) : ( - (comment.state === "failed" || (stateString === undefined && !isLoading)) ? ( + (comment.state === "failed" + // || (stateString === undefined && !isLoading) + ) ? ( Failed diff --git a/src/components/Post.jsx b/src/components/Post.jsx index a9dc83e1..260e6304 100644 --- a/src/components/Post.jsx +++ b/src/components/Post.jsx @@ -1,6 +1,6 @@ import React from 'react'; import ReactMarkdown from 'react-markdown'; -// import { Link } from 'react-router-dom'; +import { Link } from 'react-router-dom'; import rehypeSanitize, { defaultSchema } from 'rehype-sanitize'; import breaks from 'remark-breaks'; @@ -39,31 +39,60 @@ const blockquoteToGreentext = () => (tree) => { }; -// const createQuotelink = (handlequoteclick, comment, children) => { -// const text = children.map((child) => (typeof child === 'string' ? child : child.props.children)).join(''); -// const regex = /(\s|^)(c\/[A-Za-z0-9]{12}|c\/[A-Za-z0-9]{45})(?=\s|$)/g; -// const parts = text.split(regex); +const createQuotelink = (children) => { + const regexC = /(c\/[A-Za-z0-9]{46}|c\/[A-Za-z0-9]{12})/g; + const regexP = /(p\/([A-Za-z0-9]{52}|[A-Za-z0-9-.]*\.eth))/g; + const regexU = /(u\/([A-Za-z0-9]{52}|[A-Za-z0-9-.]*\.eth))/g; + const regexPC = /(p\/([A-Za-z0-9]{52}|[A-Za-z0-9-.]*\.eth)\/c\/[A-Za-z0-9]{46})/g; -// return parts.flatMap((part, i) => { -// if (regex.test(part)) { -// return [ -// -// {part.trim()} -// , -// ]; -// } else { -// return [part]; -// } -// }); -// }; + const regexArray = [regexU, regexPC, regexP, regexC]; + let parts = [children]; + + regexArray.forEach(regex => { + parts = parts.flatMap((child, i) => { + if (typeof child === 'string') { + const newParts = []; + let match; + let lastIndex = 0; + + while ((match = regex.exec(child)) !== null) { + const matchedText = match[0]; + const index = match.index; + + if (index > lastIndex) { + newParts.push(child.substring(lastIndex, index)); + } + + newParts.push( + {}} + > + {matchedText} + + ); + + lastIndex = index + matchedText.length; + } + + if (lastIndex < child.length) { + newParts.push(child.substring(lastIndex)); + } + + return newParts; + } else { + return child; + } + }); + }); + + return parts; +}; -const Post = ({ content, handlequoteclick, comment }) => { + +const Post = ({ content }) => { const doubleNewlineContent = content?.replaceAll(/\n(?!\n)/g, '\n\n'); return ( @@ -76,10 +105,10 @@ const Post = ({ content, handlequoteclick, comment }) => { video: ({ src }) => {src}, source: ({ src }) => {src}, gif: ({ src }) => {src}, - p: ({ children }) =>
{children}
, + p: ({ children }) =>
{createQuotelink(children)}
, }} /> ); }; -export default Post; \ No newline at end of file +export default React.memo(Post); \ No newline at end of file diff --git a/src/components/PostOnHover.jsx b/src/components/PostOnHover.jsx index 4bb35302..fbf7306c 100644 --- a/src/components/PostOnHover.jsx +++ b/src/components/PostOnHover.jsx @@ -190,15 +190,15 @@ const PostOnHover = ({ cid, feed }) => {
- {reply.author.displayName - ? reply.author.displayName.length > 20 + {reply.author?.displayName + ? reply.author?.displayName.length > 20 ? - {reply.author.displayName.slice(0, 20) + " (...)"} + {reply.author?.displayName.slice(0, 20) + " (...)"} : - {reply.author.displayName} + {reply.author?.displayName} : Anonymous}   diff --git a/src/components/StateLabel.jsx b/src/components/StateLabel.jsx index 98ea0482..c6398285 100644 --- a/src/components/StateLabel.jsx +++ b/src/components/StateLabel.jsx @@ -17,16 +17,18 @@ const StateLabel = ({ commentIndex, className }) => { return ( commentIndex && stateString !== "Succeeded" ? ( - (comment.state === "failed" || (stateString === undefined && !isLoading && comment.cid === undefined)) ? ( - -
- ( - - Failed - - ) -
+ (comment.state === "failed") ? ( + null ) : ( + stateString === undefined && !isLoading && comment.cid === undefined ? ( + +
+ ( + + + ) +
+ ) : (
( @@ -35,7 +37,7 @@ const StateLabel = ({ commentIndex, className }) => {
) - ) + )) ) : null ); }; diff --git a/src/components/modals/SettingsModal.jsx b/src/components/modals/SettingsModal.jsx index 534e714f..62bca6f0 100755 --- a/src/components/modals/SettingsModal.jsx +++ b/src/components/modals/SettingsModal.jsx @@ -1,22 +1,22 @@ import React, { useState, useEffect, useRef } from "react"; import { Link, useLocation, useNavigate } from "react-router-dom"; -import { confirmAlert } from "react-confirm-alert"; import Modal from "react-modal"; import { deleteCaches, exportAccount, importAccount, setAccount, setActiveAccount, useAccount, useAccounts } from "@plebbit/plebbit-react-hooks"; import { StyledModal } from "../styled/modals/SettingsModal.styled"; -import { AuthorDeleteAlert } from '../styled/views/Thread.styled'; -import useGeneralStore from "../../hooks/stores/useGeneralStore"; import useError from "../../hooks/useError"; import useSuccess from "../../hooks/useSuccess"; +import useAnonModeStore from '../../hooks/stores/useAnonModeStore'; +import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json' const {version} = packageJson const SettingsModal = ({ isOpen, closeModal }) => { const { - anonymousMode, setAnonymousMode, selectedStyle, } = useGeneralStore(state => state); + + const { anonymousMode, setAnonymousMode } = useAnonModeStore(); const navigate = useNavigate(); const location = useLocation(); @@ -194,38 +194,6 @@ const SettingsModal = ({ isOpen, closeModal }) => { } }; - - const handleAnonymousMode = () => { - confirmAlert({ - customUI: ({ onClose }) => { - return ( - -
-

- { !anonymousMode ? - "Enabling anonymous mode will turn off all account-based features, such as subscribing to boards." : - "Disabling anonymous mode will turn on all account-based features, such as subscribing to boards." - } -

-
- - -
-
-
- ) - } - }) - }; - - return ( { ]
- {/* */}
*/} -
+ + ## Board Admins +   + + Sticky +   + Closed + +
+ Rules +   +
+ {getDate(subplebbit.createdAt)} +   +
+
+
+ {subplebbit.rules.map((rule, index) => ( + + {index + 1}. {rule} +
+
+ ))} +
+
+ +
+ {}} className="button-mobile">View Thread +
+ + + + : null} + {subplebbit.description ? + <> +
+
+
+
+
+ {subplebbit.suggested?.avatarUrl ? ( +
+ +
+ + board avatar + +
+
+ ) : null} + + Welcome to {subplebbit.title || subplebbit.address} +   + ## Board Admins +   + {getDate(subplebbit.createdAt)} +   + Sticky +   + Closed +   + [ + {}} style={{textDecoration: "none"}} className="reply-link">Reply + ] + + { + threadMenuRefs.current[subplebbit.pubsubTopic] = el; + }} + className='post-menu-button' + rotated={openMenuCid === subplebbit.pubsubTopic} + onClick={(event) => { + event.stopPropagation(); + const rect = threadMenuRefs.current[subplebbit.pubsubTopic].getBoundingClientRect(); + setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); + setOpenMenuCid(prevCid => (prevCid === subplebbit.pubsubTopic ? null : subplebbit.pubsubTopic)); + }} + > + ▶ + + {createPortal( + {postMenuCatalogRef.current = el}} + onClick={(event) => event.stopPropagation()} + style={{position: "absolute", + top: menuPosition.top + 7, + left: menuPosition.left}}> +
+
    +
  • handleOptionClick(subplebbit.pubsubTopic)}>Hide thread
  • + {/* {isModerator ? ( + <> + change description + + ) : null} */} +
+
+
, document.body + )} +
+
+
+ {subplebbit.description} +
+
+
+
+
+
+
+ {subplebbit.rules ? +
: +
+ } +
+
+
+ + + ## Board Admins +   + + Sticky +   + Closed + +
+ Welcome to {subplebbit.title || subplebbit.address} +   +
+ {getDate(subplebbit.createdAt)} +   +
+ {subplebbit.suggested?.avatarUrl ? ( +
+
+ + board avatar +
image
+
+
+
+ ) : null} +
+
+ {subplebbit.description} +
+
+
+
+ {}} className="button-mobile">View Thread +
+
+
+ + : null} + { + const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; + const commentMediaInfo = getCommentMediaInfo(thread); + const fallbackImgUrl = "assets/filedeleted-res.gif"; + return ( + +
+
+
+
+
+ {commentMediaInfo?.url ? ( +
+ + {commentMediaInfo?.type === "webpage" ? ( +
+ + {thread.thumbnailUrl ? ( + {commentMediaInfo.type} e.target.src = fallbackImgUrl} /> + ) : null} + +
+ ) : null} + {commentMediaInfo?.type === "image" ? ( +
+ {commentMediaInfo.type} e.target.src = fallbackImgUrl} /> - ) : null} - -
- ) : null} - {commentMediaInfo?.type === "image" ? ( -
+ +
+ ) : null} + {commentMediaInfo?.type === "video" ? ( - {commentMediaInfo.type} e.target.src = fallbackImgUrl} /> -
- ) : null} - {commentMediaInfo?.type === "video" ? ( - - - ) : null} - {commentMediaInfo?.type === "audio" ? ( - - - ) : null} -
- ) : null} - - {thread.title ? ( - thread.title.length > 75 ? - - - {thread.title.slice(0, 75) + " (...)"} + ) : null} + {commentMediaInfo?.type === "audio" ? ( + + - - : - {thread.title} - ) - : null}  - {thread.author.displayName - ? thread.author.displayName.length > 20 - ? - - {thread.author.displayName.slice(0, 20) + " (...)"} - - - : - {thread.author.displayName} - : - Anonymous} -   - (u/ - handleAddressClick(thread.author.shortAddress)} - > - {thread.author.shortAddress} - ) -   - {getDate(thread.timestamp)} -   - - c/ - { - if (e.button === 2) return; - e.preventDefault(); - setIsReplyOpen(true); - setSelectedShortCid(thread.shortCid); - setSelectedParentCid(thread.cid); - }} title="Reply to this post">{thread.shortCid} -   -   - [ - setSelectedThread(thread.cid)} className="reply-link" >Reply - ] - -   - {thread.pinned ? ( - <> -   - Sticky - - ) : null} - {thread.locked ? ( - <> -   - Closed - - ) : null} - { - threadMenuRefs.current[thread.cid] = el; - }} - className='post-menu-button' - rotated={openMenuCid === thread.cid} - onClick={(event) => { - event.stopPropagation(); - const rect = threadMenuRefs.current[thread.cid].getBoundingClientRect(); - setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); - setOpenMenuCid(prevCid => (prevCid === thread.cid ? null : thread.cid)); - }} - > - ▶ - - {createPortal( - {postMenuCatalogRef.current = el}} - onClick={(event) => event.stopPropagation()} - style={{position: "absolute", - top: menuPosition.top + 7, - left: menuPosition.left}}> -
-
    -
  • handleOptionClick(thread.cid)}>Hide thread
  • - {thread.author.shortAddress === account?.author.shortAddress ? ( - <> -
  • handleAuthorEditClick(thread)}>Edit post
  • -
  • handleAuthorDeleteClick(thread)}>Delete post
  • - - ) : null} - {isModerator ? ( - <> - {thread.author.shortAddress === account?.author.shortAddress ? ( - null - ) : ( -
  • { - setModeratingCommentCid(thread.cid) - setIsModerationOpen(true); - handleOptionClick(thread.cid); - setDeletePost(true); - }}> - Delete post -
  • - )} -
  • { - setModeratingCommentCid(thread.cid) - setIsModerationOpen(true); - handleOptionClick(thread.cid); - }}> - Mod tools -
  • - - ) : null} - {(commentMediaInfo && ( - commentMediaInfo.type === 'image' || - (commentMediaInfo.type === 'webpage' && - commentMediaInfo.thumbnail))) ? ( -
  • {setIsImageSearchOpen(true)}} - onMouseLeave={() => {setIsImageSearchOpen(false)}}> - Image search » -
      -
    • handleOptionClick(thread.cid)}> - Google -
    • -
    • handleOptionClick(thread.cid)}> - Yandex -
    • -
    • handleOptionClick(thread.cid)}> - SauceNAO -
    • -
    -
  • - ) : null - } -
-
-
, document.body - )} - -
- {thread.content ? ( - thread.content?.length > 1000 ? - -
- - (...) -
- - -
- Post too long.  - setSelectedThread(thread.cid)} className="ttl-link">Click here -  to view. -
-
-
- :
- - - -
) - : null} -
-
-
- - {omittedCount > 0 ? ( - <> - {thread.content ? null :
} - - - {omittedCount} post{omittedCount > 1 ? "s" : ""} omitted. Click  - setSelectedThread(thread.cid)} className="ttl-link">here -  to view. - - - - ) : null} -
- {displayedReplies?.map((reply, index) => { - const replyMediaInfo = getCommentMediaInfo(reply); - const fallbackImgUrl = "assets/filedeleted-res.gif"; - const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); - return ( -
-
{'>>'}
-
-
- - {reply.author.displayName - ? reply.author.displayName.length > 20 - ? - - {reply.author.displayName.slice(0, 20) + " (...)"} - - - : - {reply.author.displayName} - : - Anonymous} -   - handleAddressClick(reply.author.shortAddress)} - > - (u/ - {reply.author?.shortAddress ? - ( - - {reply.author?.shortAddress} - - ) : ( - - {account?.author?.shortAddress} - - ) - } - ) - - + ) : null} + + {thread.title ? ( + thread.title.length > 75 ? + + + {thread.title.slice(0, 75) + " (...)"} + + + : + {thread.title} + ) + : null}  + {thread.author.displayName + ? thread.author.displayName.length > 20 + ? + + {thread.author.displayName.slice(0, 20) + " (...)"} + + + : + {thread.author.displayName} + : + Anonymous}   - {getDate(reply.timestamp)} + (u/ + handleAddressClick(thread.author.shortAddress)} + > + {thread.author.shortAddress} + ) +   + {getDate(thread.timestamp)}   c/ - {reply.shortCid ? ( - { - if (e.button === 2) return; - e.preventDefault(); - setIsReplyOpen(true); - setSelectedShortCid(reply.shortCid); - setSelectedParentCid(reply.cid); - }} title="Reply to this post">{reply.shortCid} - ) : ( - - )} -   + { + if (e.button === 2) return; + e.preventDefault(); + setSelectedThreadCid(thread.cid); + setIsReplyOpen(true); + setSelectedShortCid(thread.shortCid); + setSelectedParentCid(thread.cid); + }} title="Reply to this post">{thread.shortCid} +   + {thread.pinned ? ( + <> +   + Sticky + + ) : null} + {thread.locked ? ( + <> +   + Closed + + ) : null} +   + [ + setSelectedThread(thread.cid)} className="reply-link" >Reply + ] + + { - replyMenuRefs.current[reply.cid] = el; - }} - className='post-menu-button' - rotated={openMenuCid === reply.cid} - onClick={(event) => { - event.stopPropagation(); - const rect = replyMenuRefs.current[reply.cid].getBoundingClientRect(); - setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); - setOpenMenuCid(prevCid => (prevCid === reply.cid ? null : reply.cid)); - }} - > - ▶ - - {createPortal( - {postMenuCatalogRef.current = el}} - onClick={(event) => event.stopPropagation()} - style={{position: "absolute", - top: menuPosition.top + 7, - left: menuPosition.left}}> -
{ + threadMenuRefs.current[thread.cid] = el; + }} + className='post-menu-button' + rotated={openMenuCid === thread.cid} + onClick={(event) => { + event.stopPropagation(); + const rect = threadMenuRefs.current[thread.cid].getBoundingClientRect(); + setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); + setOpenMenuCid(prevCid => (prevCid === thread.cid ? null : thread.cid)); + }} > -
    -
  • handleOptionClick(reply.cid)}>Hide post
  • - {reply.author.shortAddress === account?.author.shortAddress ? ( - <> -
  • handleAuthorEditClick(reply)}>Edit post
  • -
  • handleAuthorDeleteClick(reply)}>Delete post
  • - - ) : null} - {isModerator ? ( - <> - {reply.author.shortAddress === account?.author.shortAddress ? ( - null - ) : ( -
  • { - setModeratingCommentCid(reply.cid) + ▶ + + {createPortal( + {postMenuCatalogRef.current = el}} + onClick={(event) => event.stopPropagation()} + style={{position: "absolute", + top: menuPosition.top + 7, + left: menuPosition.left}}> +
    +
      +
    • handleOptionClick(thread.cid)}>Hide thread
    • + {thread.author.shortAddress === account?.author.shortAddress ? ( + <> +
    • handleAuthorEditClick(thread)}>Edit post
    • +
    • handleAuthorDeleteClick(thread.cid)}>Delete post
    • + + ) : null} + {isModerator ? ( + <> + {thread.author.shortAddress === account?.author.shortAddress ? ( + null + ) : ( +
    • { + setModeratingCommentCid(thread.cid) + setIsModerationOpen(true); + handleOptionClick(thread.cid); + setDeletePost(true); + }}> + Delete post +
    • + )} +
    • { + setModeratingCommentCid(thread.cid) setIsModerationOpen(true); - handleOptionClick(reply.cid); - setDeletePost(true); + handleOptionClick(thread.cid); }}> - Delete post + Mod tools
    • - )} -
    • { - setModeratingCommentCid(reply.cid) - setIsModerationOpen(true); - handleOptionClick(reply.cid); - }}> - Mod tools -
    • - - ) : null} - {(replyMediaInfo && ( - replyMediaInfo.type === 'image' || - (replyMediaInfo.type === 'webpage' && - replyMediaInfo.thumbnail))) ? ( -
    • {setIsImageSearchOpen(true)}} - onMouseLeave={() => {setIsImageSearchOpen(false)}}> - Image search » -
        -
      • handleOptionClick(reply.cid)}> - Google -
      • -
      • handleOptionClick(reply.cid)}> - Yandex -
      • -
      • handleOptionClick(reply.cid)}> - SauceNAO -
      • -
      -
    • - ) : null - } -
    -
    -
    , document.body - )} + + ) : null} + {(commentMediaInfo && ( + commentMediaInfo.type === 'image' || + (commentMediaInfo.type === 'webpage' && + commentMediaInfo.thumbnail))) ? ( +
  • {setIsImageSearchOpen(true)}} + onMouseLeave={() => {setIsImageSearchOpen(false)}}> + Image search » +
      +
    • handleOptionClick(thread.cid)}> + Google +
    • +
    • handleOptionClick(thread.cid)}> + Yandex +
    • +
    • handleOptionClick(thread.cid)}> + SauceNAO +
    • +
    +
  • + ) : null + } +
+
+
, document.body + )} -
- {replyMediaInfo?.url ? ( -
-
- Link:  - { - replyMediaInfo?.url.length > 30 ? - replyMediaInfo?.url.slice(0, 30) + "(...)" : - replyMediaInfo?.url - } ({replyMediaInfo?.type}) + + {thread.content ? ( + thread.content?.length > 1000 ? + +
+ + (...) +
+ + +
+ Post too long.  + setSelectedThread(thread.cid)} className="ttl-link">Click here +  to view. +
+
+
+ :
+ + + +
) + : null} +
+
+
+ + {omittedCount > 0 ? ( + <> + {thread.content ? null :
} + + + {omittedCount} post{omittedCount > 1 ? "s" : ""} omitted. Click  + setSelectedThread(thread.cid)} className="ttl-link">here +  to view. + + + + ) : null} +
+ {displayedReplies?.map((reply, index) => { + const replyMediaInfo = getCommentMediaInfo(reply); + const fallbackImgUrl = "assets/filedeleted-res.gif"; + const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); + return ( +
+
{'>>'}
+
+
+ + {reply.author.displayName + ? reply.author.displayName.length > 20 + ? + + {reply.author.displayName.slice(0, 20) + " (...)"} + + + : + {reply.author.displayName} + : + Anonymous} +   + handleAddressClick(reply.author.shortAddress)} + > + (u/ + {reply.author?.shortAddress ? + ( + + {reply.author?.shortAddress} + + ) : ( + + {account?.author?.shortAddress} + + ) + } + ) + + +   + {getDate(reply.timestamp)} +   + + c/ + {reply.shortCid ? ( + { + if (e.button === 2) return; + e.preventDefault(); + setSelectedThreadCid(thread.cid); + setIsReplyOpen(true); + setSelectedShortCid(reply.shortCid); + setSelectedParentCid(reply.cid); + }} title="Reply to this post">{reply.shortCid} + ) : ( + + )} +   + { + replyMenuRefs.current[reply.cid] = el; + }} + className='post-menu-button' + rotated={openMenuCid === reply.cid} + onClick={(event) => { + event.stopPropagation(); + const rect = replyMenuRefs.current[reply.cid].getBoundingClientRect(); + setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); + setOpenMenuCid(prevCid => (prevCid === reply.cid ? null : reply.cid)); + }} + > + ▶ + + {createPortal( + {postMenuCatalogRef.current = el}} + onClick={(event) => event.stopPropagation()} + style={{position: "absolute", + top: menuPosition.top + 7, + left: menuPosition.left}}> +
+
    +
  • handleOptionClick(reply.cid)}>Hide post
  • + {reply.author.shortAddress === account?.author.shortAddress ? ( + <> +
  • handleAuthorEditClick(reply)}>Edit post
  • +
  • handleAuthorDeleteClick(reply.cid)}>Delete post
  • + + ) : null} + {isModerator ? ( + <> + {reply.author.shortAddress === account?.author.shortAddress ? ( + null + ) : ( +
  • { + setModeratingCommentCid(reply.cid) + setIsModerationOpen(true); + handleOptionClick(reply.cid); + setDeletePost(true); + }}> + Delete post +
  • + )} +
  • { + setModeratingCommentCid(reply.cid) + setIsModerationOpen(true); + handleOptionClick(reply.cid); + }}> + Mod tools +
  • + + ) : null} + {(replyMediaInfo && ( + replyMediaInfo.type === 'image' || + (replyMediaInfo.type === 'webpage' && + replyMediaInfo.thumbnail))) ? ( +
  • {setIsImageSearchOpen(true)}} + onMouseLeave={() => {setIsImageSearchOpen(false)}}> + Image search » +
      +
    • handleOptionClick(reply.cid)}> + Google +
    • +
    • handleOptionClick(reply.cid)}> + Yandex +
    • +
    • handleOptionClick(reply.cid)}> + SauceNAO +
    • +
    +
  • + ) : null + } +
- {replyMediaInfo?.type === "webpage" ? ( -
- - {reply.thumbnailUrl ? ( + , document.body + )} + +
+ {replyMediaInfo?.url ? ( +
+ + {replyMediaInfo?.type === "webpage" ? ( +
+ + {reply.thumbnailUrl ? ( + {replyMediaInfo.type} e.target.src = fallbackImgUrl} /> + ) : null} + +
+ ) : null} + {replyMediaInfo?.type === "image" ? ( +
+ {replyMediaInfo.type} e.target.src = fallbackImgUrl} /> - ) : null} - -
- ) : null} - {replyMediaInfo?.type === "image" ? ( -
+ +
+ ) : null} + {replyMediaInfo?.type === "video" ? ( - {replyMediaInfo.type} e.target.src = fallbackImgUrl} /> -
- ) : null} - {replyMediaInfo?.type === "video" ? ( - - - ) : null} - {replyMediaInfo?.type === "audio" ? ( - - - ) : null} -
- ) : null} - {reply.content ? ( - reply.content?.length > 500 ? - -
+ ) : null} + {replyMediaInfo?.type === "audio" ? ( + + + ) : null} +
+ ) : null} + {reply.content ? ( + reply.content?.length > 500 ? + +
+ {}} key={`r-pm-${index}`} className="quotelink" + ref={el => { + quoteRefs.current[reply.cid] = el; + }} + onClick={(event) => handleQuoteClick(reply, shortParentCid, event)} + onMouseOver={(event) => { + event.stopPropagation(); + handleQuoteHover(reply, shortParentCid, () => { + setOutOfViewCid(reply.parentCid); + const rect = quoteRefs.current[reply.cid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }); + }} + onMouseLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }}> + {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} + + + (...) +
+ + +
+ Comment too long.  + setSelectedThread(thread.cid)} className="ttl-link">Click here +  to view.
+
+
+ :
{}} key={`r-pm-${index}`} className="quotelink" ref={el => { quoteRefs.current[reply.cid] = el; @@ -1382,7 +1725,7 @@ const Board = () => { maxWidth: window.innerWidth - rect.left - rect.width - 5 }); } - }); + }); }} onMouseLeave={() => { removeHighlight(); @@ -1390,360 +1733,362 @@ const Board = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - - (...) -
+ + commentCid={reply.cid} + className="ttl"/> -
- Comment too long.  - setSelectedThread(thread.cid)} className="ttl-link">Click here -  to view.
-
- - :
- {}} key={`r-pm-${index}`} className="quotelink" - ref={el => { - quoteRefs.current[reply.cid] = el; - }} - onClick={(event) => handleQuoteClick(reply, shortParentCid, event)} - onMouseOver={(event) => { - event.stopPropagation(); - handleQuoteHover(reply, shortParentCid, () => { - setOutOfViewCid(reply.parentCid); - const rect = quoteRefs.current[reply.cid].getBoundingClientRect(); - const distanceToRight = window.innerWidth - rect.right; - const distanceToTop = rect.top; - const distanceToBottom = window.innerHeight - rect.bottom; - let top; - - if (distanceToTop < postOnHoverHeight / 2) { - top = window.scrollY - 5; - } else if (distanceToBottom < postOnHoverHeight / 2) { - top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; - } else { - top = rect.top + window.scrollY - postOnHoverHeight / 2; - } - - if (distanceToRight < 200) { - setOutOfViewPosition({ - top, - right: window.innerWidth - rect.left - 10, - maxWidth: rect.left - 5 - }); - } else { - setOutOfViewPosition({ - top, - left: rect.left + rect.width + 5, - maxWidth: window.innerWidth - rect.left - rect.width - 5 - }); - } - }); - }} - onMouseLeave={() => { - removeHighlight(); - setOutOfViewCid(null); - }}> - {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - - - - -
) - : null} + ) + : null} +
- - ) - })} - -
- {index === 0 ? ( -
- ) : ( -
- )} -
-
-
- - - {thread.author.displayName - ? thread.author.displayName.length > 20 - ? - - {thread.author.displayName.slice(0, 20) + " (...)"} - - + ) + })} +
+
+ {index === 0 && (!subplebbit.rules && !subplebbit.description) ? ( +
+ ) : ( +
+ )} +
+
+
+ + + {thread.author.displayName + ? thread.author.displayName.length > 20 + ? + + {thread.author.displayName.slice(0, 20) + " (...)"} + + + : + {thread.author.displayName} : - {thread.author.displayName} - : - Anonymous} -   - handleAddressClick(thread.author.shortAddress)} - > - (u/ - - {thread.author.shortAddress} - - )  - - - {thread.pinned ? ( - Sticky - ) : null} - {thread.locked ? ( - Closed - ) : null} - -
- {thread.title ? ( - thread.title.length > 30 ? - - - {thread.title.slice(0, 30) + " (...)"} + Anonymous} +   + handleAddressClick(thread.author.shortAddress)} + > + (u/ + + {thread.author.shortAddress} - - : - {thread.title} - ) - : null} -
- - {getDate(thread.timestamp)} -   - c/ - { - if (e.button === 2) return; - e.preventDefault(); - setIsReplyOpen(true); - setSelectedShortCid(thread.shortCid); - setSelectedParentCid(thread.cid); - }} title="Reply to this post">{thread.shortCid} - - -
- {thread.link ? ( -
- {commentMediaInfo?.url ? ( - commentMediaInfo.type === "webpage" ? ( -
- - {thread.thumbnailUrl ? ( + )  + + + {thread.pinned ? ( + Sticky + ) : null} + {thread.locked ? ( + Closed + ) : null} + +
+ {thread.title ? ( + thread.title.length > 30 ? + + + {thread.title.slice(0, 30) + " (...)"} + + + : + {thread.title} + ) + : null} + + + {getDate(thread.timestamp)} +   + c/ + { + if (e.button === 2) return; + e.preventDefault(); + setSelectedThreadCid(thread.cid); + setIsReplyOpen(true); + setSelectedShortCid(thread.shortCid); + setSelectedParentCid(thread.cid); + }} title="Reply to this post">{thread.shortCid} + + +
+ {thread.link ? ( +
+ {commentMediaInfo?.url ? ( + commentMediaInfo.type === "webpage" ? ( +
+ + {thread.thumbnailUrl ? ( + thumbnail e.target.src = fallbackImgUrl} /> + ) : null} +
{commentMediaInfo?.type}
+
+
+ ) : commentMediaInfo.type === "image" ? ( +
+ thumbnail e.target.src = fallbackImgUrl} /> - ) : null} -
{commentMediaInfo?.type}
-
-
- ) : commentMediaInfo.type === "image" ? ( -
- - {commentMediaInfo.type} e.target.src = fallbackImgUrl} /> -
{commentMediaInfo?.type}
-
-
- ) : commentMediaInfo.type === "video" ? ( - - - ) : commentMediaInfo.type === "audio" ? ( - - - ) : null - ) : null} -
- ) : null} - {thread.content ? ( - thread.content?.length > 500 ? - -
- - (...) -
+
{commentMediaInfo?.type}
+
+
+ ) : commentMediaInfo.type === "video" ? ( + + + ) : commentMediaInfo.type === "audio" ? ( + + + ) : null + ) : null} +
+ ) : null} + {thread.content ? ( + thread.content?.length > 500 ? + +
+ + (...) +
+ + +
+ Post too long.  + setSelectedThread(thread.cid)} className="ttl-link">Click here +  to view.
+
+
+ :
+ -
- Post too long.  - setSelectedThread(thread.cid)} className="ttl-link">Click here -  to view. -
- - :
- - - -
) - : null} + ) + : null} +
+
+ { + (thread.replyCount + pendingReplyCounts[thread.cid]) === 0 ? + ("No replies") + : (thread.replyCount + pendingReplyCounts[thread.cid]) === 1 ? + ("1 reply") + : (thread.replyCount + pendingReplyCounts[thread.cid]) > 1 ? + ((thread.replyCount + pendingReplyCounts[thread.cid]) + " replies") + : null + } + {setSelectedThread(thread.cid); window.scrollTo(0, 0);}} + className="button-mobile" >View Thread +
-
- { - (thread.replyCount + pendingReplyCounts[thread.cid]) === 0 ? - ("No replies") - : (thread.replyCount + pendingReplyCounts[thread.cid]) === 1 ? - ("1 reply") - : (thread.replyCount + pendingReplyCounts[thread.cid]) > 1 ? - ((thread.replyCount + pendingReplyCounts[thread.cid]) + " replies") - : null - } - {setSelectedThread(thread.cid); window.scrollTo(0, 0);}} - className="button-mobile" >View Thread -
-
- {displayedReplies?.map((reply, index) => { - const replyMediaInfo = getCommentMediaInfo(reply); - const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); - return ( -
-
-
- - - {reply.author.displayName - ? reply.author.displayName.length > 20 - ? - - {reply.author.displayName.slice(0, 20) + " (...)"} - - - : - {reply.author.displayName} - : - Anonymous} -   - handleAddressClick(reply.author.shortAddress)} - > - (u/ - {reply.author?.shortAddress ? - ( - - {reply.author?.shortAddress} + {displayedReplies?.map((reply, index) => { + const replyMediaInfo = getCommentMediaInfo(reply); + const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); + return ( +
+
+
+ + + {reply.author.displayName + ? reply.author.displayName.length > 20 + ? + + {reply.author.displayName.slice(0, 20) + " (...)"} - ) : ( - - {account?.author?.shortAddress} + + : + {reply.author.displayName} + : + Anonymous} +   + handleAddressClick(reply.author.shortAddress)} + > + (u/ + {reply.author?.shortAddress ? + ( + + {reply.author?.shortAddress} - ) - } - )  + ) : ( + + {account?.author?.shortAddress} + + ) + } + )  + +
-
- - - {getDate(reply.timestamp)}  - c/ - {reply.shortCid ? ( - { - if (e.button === 2) return; - e.preventDefault(); - setIsReplyOpen(true); - setSelectedShortCid(reply.shortCid); - setSelectedParentCid(reply.cid); - }} title="Reply to this post">{reply.shortCid} - - ) : ( - - )} - -
- {reply.link ? ( -
- {replyMediaInfo?.url ? ( - replyMediaInfo.type === "webpage" ? ( -
- - {reply.thumbnailUrl ? ( + + {getDate(reply.timestamp)}  + c/ + {reply.shortCid ? ( + { + if (e.button === 2) return; + e.preventDefault(); + setSelectedThreadCid(thread.cid); + setIsReplyOpen(true); + setSelectedShortCid(reply.shortCid); + setSelectedParentCid(reply.cid); + }} title="Reply to this post">{reply.shortCid} + + ) : ( + + )} + +
+ {reply.link ? ( +
+ {replyMediaInfo?.url ? ( + replyMediaInfo.type === "webpage" ? ( +
+ + {reply.thumbnailUrl ? ( + thumbnail e.target.src = fallbackImgUrl} /> + ) : null} +
{replyMediaInfo.type}
+
+
+ ) : replyMediaInfo.type === "image" ? ( +
+ thumbnail e.target.src = fallbackImgUrl} /> - ) : null} -
{replyMediaInfo.type}
-
-
- ) : replyMediaInfo.type === "image" ? ( -
- - {replyMediaInfo.type} e.target.src = fallbackImgUrl} /> -
{replyMediaInfo.type}
-
-
- ) : replyMediaInfo.type === "video" ? ( - -
+ +
+ ) : replyMediaInfo.type === "video" ? ( + + + ) : replyMediaInfo.type === "audio" ? ( + + - ) : replyMediaInfo.type === "audio" ? ( - - - ) : null - ) : null} -
- ) : null} - {reply.content ? ( - reply.content?.length > 500 ? - -
+
{replyMediaInfo.type}
+ + ) : null + ) : null} +
+ ) : null} + {reply.content ? ( + reply.content?.length > 500 ? + +
+ {}} key={`mob-r-pm-${index}`} className="quotelink" + ref={el => { + quoteRefsMobile.current[reply.cid] = el; + }} + onClick={(event) => handleQuoteClick(reply, shortParentCid, event)} + onMouseOver={(event) => { + event.stopPropagation(); + handleQuoteHover(reply, shortParentCid, () => { + setOutOfViewCid(reply.parentCid); + const rect = quoteRefsMobile.current[reply.cid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }); + }} + onMouseLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }}> + {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} + + + (...) +
+ + +
+ Comment too long.  + setSelectedThread(thread.cid)} className="ttl-link">Click here +  to view.
+
+
+ :
{}} key={`mob-r-pm-${index}`} className="quotelink" ref={el => { quoteRefsMobile.current[reply.cid] = el; @@ -1788,141 +2133,82 @@ const Board = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - - (...) -
+ -
- Comment too long.  - setSelectedThread(thread.cid)} className="ttl-link">Click here -  to view.
-
- - :
- {}} key={`mob-r-pm-${index}`} className="quotelink" - ref={el => { - quoteRefsMobile.current[reply.cid] = el; - }} - onClick={(event) => handleQuoteClick(reply, shortParentCid, event)} - onMouseOver={(event) => { - event.stopPropagation(); - handleQuoteHover(reply, shortParentCid, () => { - setOutOfViewCid(reply.parentCid); - const rect = quoteRefsMobile.current[reply.cid].getBoundingClientRect(); - const distanceToRight = window.innerWidth - rect.right; - const distanceToTop = rect.top; - const distanceToBottom = window.innerHeight - rect.bottom; - let top; +
) + : null} + {reply.replyCount > 0 ? ( +
+ {reply.replies?.pages?.topAll.comments + .sort((a, b) => a.timestamp - b.timestamp) + .map((reply, index) => ( +
{ + backlinkRefsMobile.current[reply.cid] = el; + }}> + {}} + onClick={(event) => handleQuoteClick(reply, reply.shortCid, event)} + onMouseOver={(event) => { + event.stopPropagation(); + handleQuoteHover(reply, reply.shortCid, () => { + setOutOfViewCid(reply.cid) + const rect = backlinkRefsMobile.current[reply.cid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; - if (distanceToTop < postOnHoverHeight / 2) { - top = window.scrollY - 5; - } else if (distanceToBottom < postOnHoverHeight / 2) { - top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; - } else { - top = rect.top + window.scrollY - postOnHoverHeight / 2; - } - - if (distanceToRight < 200) { - setOutOfViewPosition({ - top, - right: window.innerWidth - rect.left - 10, - maxWidth: rect.left - 5 + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } }); - } else { - setOutOfViewPosition({ - top, - left: rect.left + rect.width + 5, - maxWidth: window.innerWidth - rect.left - rect.width - 5 - }); - } - }); - }} - onMouseLeave={() => { - removeHighlight(); - setOutOfViewCid(null); - }}> - {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - - - - - ) - : null} - {reply.replyCount > 0 ? ( -
- {reply.replies?.pages?.topAll.comments - .sort((a, b) => a.timestamp - b.timestamp) - .map((reply, index) => ( -
{ - backlinkRefsMobile.current[reply.cid] = el; - }}> - {}} - onClick={(event) => handleQuoteClick(reply, reply.shortCid, event)} - onMouseOver={(event) => { - event.stopPropagation(); - handleQuoteHover(reply, reply.shortCid, () => { - setOutOfViewCid(reply.cid) - const rect = backlinkRefsMobile.current[reply.cid].getBoundingClientRect(); - const distanceToRight = window.innerWidth - rect.right; - const distanceToTop = rect.top; - const distanceToBottom = window.innerHeight - rect.bottom; - let top; - - if (distanceToTop < postOnHoverHeight / 2) { - top = window.scrollY - 5; - } else if (distanceToBottom < postOnHoverHeight / 2) { - top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; - } else { - top = rect.top + window.scrollY - postOnHoverHeight / 2; - } - - if (distanceToRight < 200) { - setOutOfViewPosition({ - top, - right: window.innerWidth - rect.left - 10, - maxWidth: rect.left - 5 - }); - } else { - setOutOfViewPosition({ - top, - left: rect.left + rect.width + 5, - maxWidth: window.innerWidth - rect.left - rect.width - 5 - }); - } - }); - }} - onMouseLeave={() => { - removeHighlight(); - setOutOfViewCid(null); - }} - className="quote-link"> - c/{reply.shortCid} -   + }} + onMouseLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + className="quote-link"> + c/{reply.shortCid} +   +
+ ))}
- ))} -
- ) : null} + ) : null} +
-
- )})} -
- - ); - }} - endReached={tryLoadMore} - useWindowScroll={true} - components={{ Footer: hasMore ? () => : null }} - /> + )})} +
+ + ); + }} + endReached={tryLoadMore} + useWindowScroll={true} + components={{ Footer: hasMore ? () => : null }} + /> + ) : () )}
diff --git a/src/components/views/Catalog.jsx b/src/components/views/Catalog.jsx index ab0f019a..51bac62c 100755 --- a/src/components/views/Catalog.jsx +++ b/src/components/views/Catalog.jsx @@ -7,7 +7,6 @@ import { confirmAlert } from 'react-confirm-alert'; import { Tooltip } from 'react-tooltip'; import { useAccount, useFeed, usePublishComment, usePublishCommentEdit, useSubplebbit, useSubscribe } from '@plebbit/plebbit-react-hooks'; import { debounce } from 'lodash'; -import useGeneralStore from '../../hooks/stores/useGeneralStore'; import { Container, NavBar, Header, Break, PostForm, PostFormLink, PostFormTable, PostMenu, BoardForm } from '../styled/views/Board.styled'; import { Threads, PostMenuCatalog } from '../styled/views/Catalog.styled'; import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled'; @@ -23,6 +22,7 @@ import useClickForm from '../../hooks/useClickForm'; import useError from '../../hooks/useError'; import useStateString from '../../hooks/useStateString'; import useSuccess from '../../hooks/useSuccess'; +import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json' const {version} = packageJson @@ -49,6 +49,7 @@ const Catalog = () => { showPostForm, showPostFormLink, } = useGeneralStore(state => state); + const nameRef = useRef(); const subjectRef = useRef(); @@ -77,7 +78,6 @@ const Catalog = () => { const [menuPosition, setMenuPosition] = useState({top: 0, left: 0}); const [openMenuCid, setOpenMenuCid] = useState(null); - const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: [`${selectedAddress}`], sortType: 'active'}); const { subplebbitAddress } = useParams(); const subplebbit = useSubplebbit({subplebbitAddress: selectedAddress}); @@ -273,8 +273,8 @@ const Catalog = () => { setTriggerPublishComment(true); }; - - + + useEffect(() => { if (publishCommentOptions && triggerPublishComment) { (async () => { @@ -462,7 +462,7 @@ const Catalog = () => { [ All -  /  +  /  Subscriptions ] [ {defaultSubplebbits.map((subplebbit, index) => ( @@ -612,7 +612,7 @@ const Catalog = () => { {feed.length > 0 ? ( <> - + [ handleSubscribe()}> @@ -645,88 +645,44 @@ const Catalog = () => { null ) : ( feed.length > 0 ? ( - - {feed.map((thread, index) => { - const commentMediaInfo = getCommentMediaInfo(thread); - const fallbackImgUrl = "assets/filedeleted-res.gif"; - return ( -
{setIsHoveringOnThread(thread.cid)}} - onMouseLeave={() => {setIsHoveringOnThread('')}}> - {commentMediaInfo?.url ? ( - setSelectedThread(thread.cid)}> - {commentMediaInfo?.type === "webpage" ? ( - thread.thumbnailUrl ? ( - {commentMediaInfo.type} { - e.target.src = fallbackImgUrl - e.target.onerror = null; - }} /> - ) : null - ) : null} - {commentMediaInfo?.type === "image" ? ( - {commentMediaInfo.type} { - e.target.src = fallbackImgUrl - e.target.onerror = null;}} /> - ) : null} - {commentMediaInfo?.type === "video" ? ( -