add catalog popups to description and rules

This commit is contained in:
plebeius.eth
2023-09-08 15:29:40 +02:00
parent 876b866348
commit 854a05e4fd
2 changed files with 160 additions and 119 deletions
@@ -150,7 +150,7 @@ export const PostPreview = styled.div`
font-size: 90%; font-size: 90%;
} }
.post-authorAdmin { .post-author-admin {
color: purple; color: purple;
font-weight: 700; font-weight: 700;
} }
+159 -118
View File
@@ -110,6 +110,7 @@ const CatalogPost = ({post}) => {
useLayoutEffect(() => { useLayoutEffect(() => {
const executeLayoutEffectLogic = () => { const executeLayoutEffectLogic = () => {
let ref; let ref;
if (isMediaShowed) { if (isMediaShowed) {
ref = imageRef.current; ref = imageRef.current;
} else { } else {
@@ -348,126 +349,164 @@ const CatalogPost = ({post}) => {
if (post.type === 'rules') { if (post.type === 'rules') {
return ( return (
<div className='thread' <>
onMouseLeave={()=>{handleMouseOnLeaveThread()}}>
{isHoveringOnThread === 'rules' ? {isHoveringOnThread === 'rules' ?
<div style={{left:"100%"}} createPortal(
onMouseOver={() => setIsHoveringOnThread("")} <PostPreview selectedStyle={selectedStyle}>
className={"thread_popup"}> <div ref={popupRef}
<p className="thread_popup_content" style={{color:"white"}}> className="post-preview"
<span className="thread_popup_title">Rules </span> onMouseOver={() => handleMouseOnLeaveThread()}
by
<span className="thread_popup_authorAdmin"> ## Board Admins </span>
{getFormattedTime(subplebbit.createdAt)}</p>
</div> : null }
<BoardForm selectedStyle={selectedStyle} style={{all: 'unset'}}
onMouseOver={() => {
setIsHoveringForMenu('rules');
handleMouseOnLeaveThread();
}}
onMouseLeave={() => setIsHoveringForMenu(false)}>
<div className='meta' title="(R)eplies / (L)ink Replies">
R:&nbsp;<b>0</b>&nbsp;/&nbsp;L:&nbsp;<b>0</b>
<div className='thread-icons'
style={{position: 'absolute', top: '-2px', right: '15px'}}>
<span className="thread-icon sticky-icon" title="Sticky"
style={{ style={{
imageRendering: "pixelated",}} /> visibility: isCalculationDone ? 'visible' : 'hidden',
<span className="thread-icon closed-icon" title="Closed" left:
style={{ isCalculationDone && spaceOnRight > 250 ? textRect.right + 5 :
imageRendering: "pixelated",}} /> isCalculationDone && spaceOnRight < 250 ? textRect.left - popupRect.width - 5
</div> : 'auto',
<PostMenu top: popupPosition.top + 5,
style={{ display: isHoveringForMenu === "rules" ? 'inline-block' : 'none', }}>
position: 'absolute', lineHeight: '1em', marginTop: '-1px', outline: 'none', <span className="post-subject" >
zIndex: '999'}} Rules 
title="Post menu" </span> by 
ref={el => { <span className="post-author-admin"> ## Board Admins </span>
threadMenuRefs.current["rules"] = el; <span className='post-ago'>
postMenuRef.current = el; {thread.timestamp ? getFormattedTime(thread.timestamp) : null}
}} </span>
className='post-menu-button'
id='post-menu-button-catalog'
rotated={openMenuCid === "rules"}
onClick={(event) => {
event.stopPropagation();
const rect = threadMenuRefs.current["rules"].getBoundingClientRect();
setMenuPosition({top: rect.top + window.scrollY, left: rect.left});
setOpenMenuCid(prevCid => (prevCid === "rules" ? null : "rules"));
}}
>
</PostMenu>
</div>
{createPortal(
<PostMenuCatalog selectedStyle={selectedStyle}
ref={el => {postMenuCatalogRef.current = el}}
onClick={(event) => event.stopPropagation()}
style={{position: "absolute",
top: menuPosition.top + 7,
left: menuPosition.left}}>
<div className={`post-menu-thread post-menu-thread-${"rules"}`}
style={{ display: openMenuCid === "rules" ? 'block' : 'none' }}
>
<ul className="post-menu-catalog">
<li onClick={() => {
handleOptionClick("rules");
handleShareClick(selectedAddress, "rules");
}}>Share thread</li>
{/* {isModerator ? (
<>
change rules
</>
) : null} */}
</ul>
</div> </div>
</PostMenuCatalog>, document.body </PostPreview>, document.body
)} )
</BoardForm> : null }
<Link style={{all: "unset", cursor: "pointer"}} to={`/p/${selectedAddress}/rules`} <div className='thread'
onMouseOver={() => { ref={el => {
setIsHoveringForMenu('rules'); threadRefs.current['rules'] = el;
if (!hoverTimeoutId) {
const timeoutId = setTimeout(() => {
setIsHoveringOnThread("rules");
}, 250);
setHoverTimeoutId(timeoutId);
}
}} }}
onMouseLeave={() => setIsHoveringForMenu(false)}> onMouseLeave={()=>{handleMouseOnLeaveThread()}}>
<div className="teaser" style={{maxHeight: '312px'}}> <BoardForm selectedStyle={selectedStyle} style={{all: 'unset'}}
<b>Rules</b> onMouseOver={() => {
{": " + subplebbit.rules?.map((rule, index) => `${index + 1}. ${rule}`).join(' ')} setIsHoveringForMenu('rules');
handleMouseOnLeaveThread();
}}
onMouseLeave={() => setIsHoveringForMenu(false)}>
<div className='meta' title="(R)eplies / (L)ink Replies">
R:&nbsp;<b>0</b>&nbsp;/&nbsp;L:&nbsp;<b>0</b>
<div className='thread-icons'
style={{position: 'absolute', top: '-2px', right: '15px'}}>
<span className="thread-icon sticky-icon" title="Sticky"
style={{
imageRendering: "pixelated",}} />
<span className="thread-icon closed-icon" title="Closed"
style={{
imageRendering: "pixelated",}} />
</div>
<PostMenu
style={{ display: isHoveringForMenu === "rules" ? 'inline-block' : 'none',
position: 'absolute', lineHeight: '1em', marginTop: '-1px', outline: 'none',
zIndex: '999'}}
title="Post menu"
ref={el => {
threadMenuRefs.current["rules"] = el;
postMenuRef.current = el;
}}
className='post-menu-button'
id='post-menu-button-catalog'
rotated={openMenuCid === "rules"}
onClick={(event) => {
event.stopPropagation();
const rect = threadMenuRefs.current["rules"].getBoundingClientRect();
setMenuPosition({top: rect.top + window.scrollY, left: rect.left});
setOpenMenuCid(prevCid => (prevCid === "rules" ? null : "rules"));
}}
>
</PostMenu>
</div> </div>
</Link> {createPortal(
</div> <PostMenuCatalog selectedStyle={selectedStyle}
ref={el => {postMenuCatalogRef.current = el}}
onClick={(event) => event.stopPropagation()}
style={{position: "absolute",
top: menuPosition.top + 7,
left: menuPosition.left}}>
<div className={`post-menu-thread post-menu-thread-${"rules"}`}
style={{ display: openMenuCid === "rules" ? 'block' : 'none' }}
>
<ul className="post-menu-catalog">
<li onClick={() => {
handleOptionClick("rules");
handleShareClick(selectedAddress, "rules");
}}>Share thread</li>
{/* {isModerator ? (
<>
change rules
</>
) : null} */}
</ul>
</div>
</PostMenuCatalog>, document.body
)}
</BoardForm>
<Link style={{all: "unset", cursor: "pointer"}} to={`/p/${selectedAddress}/rules`}>
<div className="teaser" style={{maxHeight: '312px'}}>
<div style={{cursor: 'text'}}>
<span ref={textRef}
onMouseOver={() => {
setIsHoveringOnThread('rules');
setIsHoveringForMenu('rules');
const rect = threadRefs.current['rules'].getBoundingClientRect();
setPopupPosition({top: rect.top + window.scrollY, left: rect.left});
}}
onMouseLeave={() => setIsHoveringForMenu(false)}>
<b>Rules</b>
{": " + subplebbit.rules?.map((rule, index) => `${index + 1}. ${rule}`).join(' ')}
</span>
</div>
</div>
</Link>
</div>
</>
) )
} else if (post.type === 'description') { } else if (post.type === 'description') {
return ( return (
<> <>
{isHoveringOnThread === 'description' ?
createPortal(
<PostPreview selectedStyle={selectedStyle}>
<div ref={popupRef}
className="post-preview"
onMouseOver={() => handleMouseOnLeaveThread()}
style={{
visibility: isCalculationDone ? 'visible' : 'hidden',
left:
isCalculationDone && spaceOnRight > 250
? subplebbit.suggestedAvatarUrl ? imageRect.right + 5 : textRect.right + 5 :
isCalculationDone && spaceOnRight < 250
? subplebbit.suggestedAvatarUrl ? imageRect.left - popupRect.width - 5 : textRect.left - popupRect.width - 5
: 'auto',
top: popupPosition.top + 5,
}}>
<span className="post-subject" >
Welcome to {subplebbit.title || subplebbit.address}
</span> by 
<span className="post-author-admin"> ## Board Admins </span>
<span className='post-ago'>
{thread.timestamp ? getFormattedTime(thread.timestamp) : null}
</span>
</div>
</PostPreview>, document.body
)
: null }
<div className='thread' <div className='thread'
ref={el => {
threadRefs.current['description'] = el;
}}
onMouseLeave={()=>{handleMouseOnLeaveThread()}}> onMouseLeave={()=>{handleMouseOnLeaveThread()}}>
{isHoveringOnThread === 'description' ?
<div style={{left:"100%"}}
onMouseOver={() => setIsHoveringOnThread("")}
className={"thread_popup"}>
<p className="thread_popup_content" style={{color:"white"}}>
<span className="thread_popup_title">Welcome to {subplebbit.title || subplebbit.address} </span>
by
<span className="thread_popup_authorAdmin"> ## Board Admins </span>
{getFormattedTime(subplebbit.createdAt)}</p>
</div> : null }
<Link style={{all: 'unset', cursor: 'pointer'}} to={`/p/${selectedAddress}/description`}> <Link style={{all: 'unset', cursor: 'pointer'}} to={`/p/${selectedAddress}/description`}>
{subplebbit.suggested?.avatarUrl ? ( {subplebbit.suggested?.avatarUrl ? (
<img className='card' <img className='card'
onMouseOver={() => { onMouseOver={() => {
setIsHoveringOnThread('description');
setIsHoveringForMenu('description'); setIsHoveringForMenu('description');
if (!hoverTimeoutId) { const rect = threadRefs.current['description'].getBoundingClientRect();
const timeoutId = setTimeout(() => { setPopupPosition({top: rect.top + window.scrollY, left: rect.left});
setIsHoveringOnThread("description");
}, 250);
setHoverTimeoutId(timeoutId);
}
}} }}
onMouseLeave={() => setIsHoveringForMenu(false)} onMouseLeave={() => setIsHoveringForMenu(false)}
src={subplebbit.suggested.avatarUrl} alt="board avatar" /> src={subplebbit.suggested.avatarUrl} alt="board avatar" />
@@ -578,21 +617,23 @@ const CatalogPost = ({post}) => {
)} )}
</BoardForm> </BoardForm>
<Link style={{all: "unset", cursor: "pointer"}} to={`/p/${selectedAddress}/description`} <Link style={{all: "unset", cursor: "pointer"}} to={`/p/${selectedAddress}/description`}
onClick={() => setSelectedThread("description")} onMouseOver={() => { onClick={() => setSelectedThread("description")}>
setIsHoveringForMenu('description'); <div className="teaser" style={{maxHeight: '170px'}}>
if (!hoverTimeoutId) { <div style={{cursor: 'text'}}>
const timeoutId = setTimeout(() => { <span ref={textRef}
setIsHoveringOnThread("description"); onMouseOver={() => {
}, 250); setIsHoveringOnThread('description');
setHoverTimeoutId(timeoutId); setIsHoveringForMenu('description');
} const rect = threadRefs.current['description'].getBoundingClientRect();
}} setPopupPosition({top: rect.top + window.scrollY, left: rect.left});
onMouseLeave={() => setIsHoveringForMenu(false)}> }}
<div className="teaser" style={{maxHeight: '170px'}}> onMouseLeave={() => setIsHoveringForMenu(false)}>
<b>Welcome to {subplebbit.title || subplebbit.address}!</b> <b>Welcome to {subplebbit.title || subplebbit.address}!</b>
{": " + subplebbit.description} {": " + subplebbit.description}
</span>
</div> </div>
</Link> </div>
</Link>
</div> </div>
</> </>
) )