This commit is contained in:
Sujal Choudhari
2023-08-09 18:49:57 +05:30
parent 88ffdb2b4c
commit f293a1ed30
4 changed files with 255 additions and 233 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ const OfflineIndicator = ({ address, className, tooltipPlace }) => {
return ( return (
<> <>
{!isOnline && ( {true && (
<> <>
{" "} {" "}
<img <img
+12 -3
View File
@@ -32,13 +32,22 @@ export const Threads = styled.div`
.thread-icons { .thread-icons {
display: inline; display: inline;
height: 16px;
margin: 2px 0 0 -101px;
position: absolute;
width: 100px; width: 100px;
height: 16px;
position:absolute;
margin: 6px 60px 0 0px;
text-align: right; text-align: right;
top:0;
right:0;
z-index:4;
} }
.thread-icon-has-display{
transform: translate(68px, -4px);
scale: 0.8;
}
.offline-icon { .offline-icon {
height: 16px; height: 16px;
margin: 2px; margin: 2px;
+6 -2
View File
@@ -378,7 +378,11 @@ const AllCatalog = () => {
) : null} ) : null}
</Link> </Link>
) : null} ) : null}
<div key={`ti-`} className="thread-icons" > <div key={`ti-`} className={`thread-icons ${(commentMediaInfo && (
commentMediaInfo.type === 'image' ||
commentMediaInfo.type === 'video' ||
(commentMediaInfo.type === 'webpage' &&
commentMediaInfo.thumbnail))) ? "thread-icon-has-display" :""}`} >
{(commentMediaInfo && ( {(commentMediaInfo && (
commentMediaInfo.type === 'image' || commentMediaInfo.type === 'image' ||
commentMediaInfo.type === 'video' || commentMediaInfo.type === 'video' ||
@@ -386,7 +390,7 @@ const AllCatalog = () => {
commentMediaInfo.thumbnail))) ? ( commentMediaInfo.thumbnail))) ? (
<OfflineIndicator <OfflineIndicator
address={thread.subplebbitAddress} address={thread.subplebbitAddress}
className="thread-icon offline-icon" className={`thread-icon offline-icon `}
tooltipPlace="top" /> tooltipPlace="top" />
) : ( ) : (
<OfflineIndicator <OfflineIndicator
+50 -41
View File
@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import { Link, useNavigate} from 'react-router-dom'; import { Link, useNavigate } from 'react-router-dom';
import { confirmAlert } from 'react-confirm-alert'; import { confirmAlert } from 'react-confirm-alert';
import { Tooltip } from 'react-tooltip'; import { Tooltip } from 'react-tooltip';
import { Virtuoso } from 'react-virtuoso'; import { Virtuoso } from 'react-virtuoso';
@@ -28,7 +28,7 @@ import useGeneralStore from '../../hooks/stores/useGeneralStore';
import useSuccess from '../../hooks/useSuccess'; import useSuccess from '../../hooks/useSuccess';
import useWindowWidth from '../../hooks/useWindowWidth'; import useWindowWidth from '../../hooks/useWindowWidth';
import packageJson from '../../../package.json'; import packageJson from '../../../package.json';
const {version} = packageJson const { version } = packageJson
let lastVirtuosoStates = {} let lastVirtuosoStates = {}
@@ -73,9 +73,9 @@ const SubscriptionsCatalog = () => {
const [moderatorPermissions, setModeratorPermissions] = useState({}); const [moderatorPermissions, setModeratorPermissions] = useState({});
const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false); const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false);
const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'}); const { feed, hasMore, loadMore } = useFeed({ subplebbitAddresses: account?.subscriptions, sortType: 'active' });
const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp)); const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp));
const {subplebbits} = useSubplebbits({subplebbitAddresses: account?.subscriptions, sortType: 'active'}); const { subplebbits } = useSubplebbits({ subplebbitAddresses: account?.subscriptions, sortType: 'active' });
const stateString = useFeedStateString(subplebbits); const stateString = useFeedStateString(subplebbits);
@@ -252,13 +252,13 @@ const SubscriptionsCatalog = () => {
}; };
const CatalogPost = ({post}) => { const CatalogPost = ({ post }) => {
const thread = post; const thread = post;
const commentMediaInfo = getCommentMediaInfo(thread); const commentMediaInfo = getCommentMediaInfo(thread);
const linkCount = countLinks(thread); const linkCount = countLinks(thread);
const fallbackImgUrl = "assets/filedeleted-res.gif"; const fallbackImgUrl = "assets/filedeleted-res.gif";
const [isHoveringOnThread, setIsHoveringOnThread] = useState(false); const [isHoveringOnThread, setIsHoveringOnThread] = useState(false);
const [menuPosition, setMenuPosition] = useState({top: 0, left: 0}); const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
const [openMenuCid, setOpenMenuCid] = useState(null); const [openMenuCid, setOpenMenuCid] = useState(null);
const isModerator = moderatorPermissions[thread.subplebbitAddress]; const isModerator = moderatorPermissions[thread.subplebbitAddress];
@@ -331,10 +331,10 @@ const SubscriptionsCatalog = () => {
return ( return (
<div key={`thread-`} className="thread" <div key={`thread-`} className="thread"
onMouseOver={() => {setIsHoveringOnThread(thread.cid)}} onMouseOver={() => { setIsHoveringOnThread(thread.cid) }}
onMouseLeave={() => {setIsHoveringOnThread('')}}> onMouseLeave={() => { setIsHoveringOnThread('') }}>
{commentMediaInfo?.url ? ( {commentMediaInfo?.url ? (
<Link style={{all: "unset", cursor: "pointer"}} key={`link-`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`} <Link style={{ all: "unset", cursor: "pointer" }} key={`link-`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`}
onClick={() => setSelectedThread(thread.cid)}> onClick={() => setSelectedThread(thread.cid)}>
{commentMediaInfo?.type === "webpage" ? ( {commentMediaInfo?.type === "webpage" ? (
thread.thumbnailUrl ? ( thread.thumbnailUrl ? (
@@ -351,7 +351,8 @@ const SubscriptionsCatalog = () => {
src={commentMediaInfo.url} alt={commentMediaInfo.type} src={commentMediaInfo.url} alt={commentMediaInfo.type}
onError={(e) => { onError={(e) => {
e.target.src = fallbackImgUrl e.target.src = fallbackImgUrl
e.target.onerror = null;}} /> e.target.onerror = null;
}} />
) : null} ) : null}
{commentMediaInfo?.type === "video" ? ( {commentMediaInfo?.type === "video" ? (
<video className="card" key={`fti-`} <video className="card" key={`fti-`}
@@ -368,7 +369,11 @@ const SubscriptionsCatalog = () => {
) : null} ) : null}
</Link> </Link>
) : null} ) : null}
<div key={`ti-`} className="thread-icons" > <div key={`ti-`} className={`thread-icons ${(commentMediaInfo && (
commentMediaInfo.type === 'image' ||
commentMediaInfo.type === 'video' ||
(commentMediaInfo.type === 'webpage' &&
commentMediaInfo.thumbnail))) ? "thread-icon-has-display" : ""}`} >
{(commentMediaInfo && ( {(commentMediaInfo && (
commentMediaInfo.type === 'image' || commentMediaInfo.type === 'image' ||
commentMediaInfo.type === 'video' || commentMediaInfo.type === 'video' ||
@@ -386,7 +391,7 @@ const SubscriptionsCatalog = () => {
)} )}
</div> </div>
<BoardForm selectedStyle={selectedStyle} <BoardForm selectedStyle={selectedStyle}
style={{ all: "unset"}}> style={{ all: "unset" }}>
<div key={`meta-`} className="meta" title="(R)eplies / (L)ink Replies" > <div key={`meta-`} className="meta" title="(R)eplies / (L)ink Replies" >
R:&nbsp;<b key={`b-`}>{thread.replyCount}</b> R:&nbsp;<b key={`b-`}>{thread.replyCount}</b>
{linkCount > 0 ? ( {linkCount > 0 ? (
@@ -396,9 +401,11 @@ const SubscriptionsCatalog = () => {
</> </>
) : null} ) : null}
<PostMenu <PostMenu
style={{ display: isHoveringOnThread === thread.cid ? 'inline-block' : 'none', style={{
display: isHoveringOnThread === thread.cid ? 'inline-block' : 'none',
position: 'absolute', lineHeight: '1em', marginTop: '-1px', outline: 'none', position: 'absolute', lineHeight: '1em', marginTop: '-1px', outline: 'none',
zIndex: '999'}} zIndex: '999'
}}
key={`pmb-`} key={`pmb-`}
title="Post menu" title="Post menu"
ref={el => { ref={el => {
@@ -411,7 +418,7 @@ const SubscriptionsCatalog = () => {
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation();
const rect = threadMenuRefs.current[thread.cid].getBoundingClientRect(); const rect = threadMenuRefs.current[thread.cid].getBoundingClientRect();
setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); setMenuPosition({ top: rect.top + window.scrollY, left: rect.left });
setOpenMenuCid(prevCid => (prevCid === thread.cid ? null : thread.cid)); setOpenMenuCid(prevCid => (prevCid === thread.cid ? null : thread.cid));
}} }}
> >
@@ -420,11 +427,13 @@ const SubscriptionsCatalog = () => {
</div> </div>
{createPortal( {createPortal(
<PostMenuCatalog selectedStyle={selectedStyle} <PostMenuCatalog selectedStyle={selectedStyle}
ref={el => {postMenuCatalogRef.current = el}} ref={el => { postMenuCatalogRef.current = el }}
onClick={(event) => event.stopPropagation()} onClick={(event) => event.stopPropagation()}
style={{position: "absolute", style={{
position: "absolute",
top: menuPosition.top + 7, top: menuPosition.top + 7,
left: menuPosition.left}}> left: menuPosition.left
}}>
<div className={`post-menu-thread post-menu-thread-${thread.cid}`} <div className={`post-menu-thread post-menu-thread-${thread.cid}`}
style={{ display: openMenuCid === thread.cid ? 'block' : 'none' }} style={{ display: openMenuCid === thread.cid ? 'block' : 'none' }}
> >
@@ -473,11 +482,11 @@ const SubscriptionsCatalog = () => {
(commentMediaInfo.type === 'webpage' && (commentMediaInfo.type === 'webpage' &&
commentMediaInfo.thumbnail))) ? ( commentMediaInfo.thumbnail))) ? (
<li <li
onMouseOver={() => {setIsImageSearchOpen(true)}} onMouseOver={() => { setIsImageSearchOpen(true) }}
onMouseLeave={() => {setIsImageSearchOpen(false)}}> onMouseLeave={() => { setIsImageSearchOpen(false) }}>
Image search » Image search »
<ul className="dropdown-menu post-menu-catalog" <ul className="dropdown-menu post-menu-catalog"
style={{display: isImageSearchOpen ? 'block': 'none'}}> style={{ display: isImageSearchOpen ? 'block' : 'none' }}>
<li onClick={() => handleOptionClick(thread.cid)}> <li onClick={() => handleOptionClick(thread.cid)}>
<a <a
href={`https://lens.google.com/uploadbyurl?url=${commentMediaInfo.url}`} href={`https://lens.google.com/uploadbyurl?url=${commentMediaInfo.url}`}
@@ -505,7 +514,7 @@ const SubscriptionsCatalog = () => {
</PostMenuCatalog>, document.body </PostMenuCatalog>, document.body
)} )}
</BoardForm> </BoardForm>
<Link style={{all: "unset", cursor: "pointer"}} key={`link2-`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`} <Link style={{ all: "unset", cursor: "pointer" }} key={`link2-`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`}
onClick={() => setSelectedThread(thread.cid)}> onClick={() => setSelectedThread(thread.cid)}>
<div key={`t-`} className="teaser"> <div key={`t-`} className="teaser">
<b key={`b2-`}>{thread.title ? `${thread.title}` : null}</b> <b key={`b2-`}>{thread.title ? `${thread.title}` : null}</b>
@@ -517,7 +526,7 @@ const SubscriptionsCatalog = () => {
}; };
const CatalogRow = ({row}) => { const CatalogRow = ({ row }) => {
const posts = [] const posts = []
for (const post of row) { for (const post of row) {
posts.push(<CatalogPost key={post?.cid} post={post} />) posts.push(<CatalogPost key={post?.cid} post={post} />)
@@ -559,7 +568,7 @@ const SubscriptionsCatalog = () => {
<ModerationModal <ModerationModal
selectedStyle={selectedStyle} selectedStyle={selectedStyle}
isOpen={isModerationOpen} isOpen={isModerationOpen}
closeModal={() => {setIsModerationOpen(false); setDeletePost(false)}} closeModal={() => { setIsModerationOpen(false); setDeletePost(false) }}
deletePost={deletePost} /> deletePost={deletePost} />
<EditModal <EditModal
selectedStyle={selectedStyle} selectedStyle={selectedStyle}
@@ -571,7 +580,7 @@ const SubscriptionsCatalog = () => {
<span className="boardList"> <span className="boardList">
[ [
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>All</Link> <Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>All</Link>
 /  /
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>Subscriptions</Link> <Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>Subscriptions</Link>
]&nbsp;[ ]&nbsp;[
{defaultSubplebbits.map((subplebbit, index) => ( {defaultSubplebbits.map((subplebbit, index) => (
@@ -589,7 +598,7 @@ const SubscriptionsCatalog = () => {
</span> </span>
<span className="nav"> <span className="nav">
[ [
<span id="button-span" style={{cursor: 'pointer'}} onClick={ <span id="button-span" style={{ cursor: 'pointer' }} onClick={
() => { () => {
window.electron && window.electron.isElectron ? ( window.electron && window.electron.isElectron ? (
setIsCreateBoardOpen(true) setIsCreateBoardOpen(true)
@@ -620,8 +629,8 @@ const SubscriptionsCatalog = () => {
<option key={`option-${subplebbit.address}`} value={subplebbit.address} <option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option> >{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
))} ))}
</select>  </select>
<span id="button-span" style={{cursor: 'pointer'}} onClick={ <span id="button-span" style={{ cursor: 'pointer' }} onClick={
() => alert( () => alert(
'You can create a board with the desktop version of plebchan:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, use plebbit-cli:\nhttps://github.com/plebbit/plebbit-cli\n\n' 'You can create a board with the desktop version of plebchan:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, use plebbit-cli:\nhttps://github.com/plebbit/plebbit-cli\n\n'
) )
@@ -630,7 +639,7 @@ const SubscriptionsCatalog = () => {
<div className="page-jump"> <div className="page-jump">
<Link to={`/p/subscriptions/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link> <Link to={`/p/subscriptions/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
&nbsp; &nbsp;
<Link to="/" onClick={() => {handleStyleChange({target: {value: "Yotsuba"}}); window.scrollTo(0, 0);}}>Home</Link> <Link to="/" onClick={() => { handleStyleChange({ target: { value: "Yotsuba" } }); window.scrollTo(0, 0); }}>Home</Link>
</div> </div>
</div> </div>
</div> </div>
@@ -660,7 +669,7 @@ const SubscriptionsCatalog = () => {
<hr /> <hr />
<span className="style-changer"> <span className="style-changer">
Style: Style:
 
<select id="style-selector" onChange={handleStyleChange} value={selectedStyle}> <select id="style-selector" onChange={handleStyleChange} value={selectedStyle}>
<option value="Yotsuba">Yotsuba</option> <option value="Yotsuba">Yotsuba</option>
<option value="Yotsuba-B">Yotsuba B</option> <option value="Yotsuba-B">Yotsuba B</option>
@@ -683,7 +692,7 @@ const SubscriptionsCatalog = () => {
{subplebbits.state === "succeeded" ? ( {subplebbits.state === "succeeded" ? (
null null
) : ( ) : (
<div id="stats" style={{float: "right", marginTop: "5px"}}> <div id="stats" style={{ float: "right", marginTop: "5px" }}>
<span className={stateString ? "ellipsis" : ""}>{stateString}</span> <span className={stateString ? "ellipsis" : ""}>{stateString}</span>
</div> </div>
)} )}
@@ -693,13 +702,13 @@ const SubscriptionsCatalog = () => {
<Threads selectedStyle={selectedStyle}> <Threads selectedStyle={selectedStyle}>
{feed.length > 1 ? ( {feed.length > 1 ? (
<Virtuoso <Virtuoso
increaseViewportBy={{bottom: 600, top: 600}} increaseViewportBy={{ bottom: 600, top: 600 }}
totalCount={rows?.length || 0} totalCount={rows?.length || 0}
data={rows} data={rows}
style={{maxWidth: '100%'}} style={{ maxWidth: '100%' }}
itemContent={(index, row) => <CatalogRow index={index} row={row} />} itemContent={(index, row) => <CatalogRow index={index} row={row} />}
useWindowScroll={true} useWindowScroll={true}
components={{ Footer: () => hasMore ? <CatalogLoader /> : null}} components={{ Footer: () => hasMore ? <CatalogLoader /> : null }}
endReached={loadMore} endReached={loadMore}
ref={virtuosoRef} ref={virtuosoRef}
restoreStateFrom={lastVirtuosoState} restoreStateFrom={lastVirtuosoState}
@@ -720,7 +729,7 @@ const SubscriptionsCatalog = () => {
marginTop: "2px", marginTop: "2px",
}}> }}>
Style: Style:
 
<select id="style-selector" onChange={handleStyleChange} value={selectedStyle}> <select id="style-selector" onChange={handleStyleChange} value={selectedStyle}>
<option value="Yotsuba">Yotsuba</option> <option value="Yotsuba">Yotsuba</option>
<option value="Yotsuba-B">Yotsuba B</option> <option value="Yotsuba-B">Yotsuba B</option>
@@ -750,7 +759,7 @@ const SubscriptionsCatalog = () => {
</span> </span>
<span className="nav"> <span className="nav">
[ [
<span id="button-span" style={{cursor: 'pointer'}} onClick={ <span id="button-span" style={{ cursor: 'pointer' }} onClick={
() => { () => {
window.electron && window.electron.isElectron ? ( window.electron && window.electron.isElectron ? (
setIsCreateBoardOpen(true) setIsCreateBoardOpen(true)
@@ -766,7 +775,7 @@ const SubscriptionsCatalog = () => {
<Link to={`/p/subscriptions/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link> <Link to={`/p/subscriptions/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
] ]
[ [
<Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}} <Link to="/" onClick={() => handleStyleChange({ target: { value: "Yotsuba" } }
)}>Home</Link> )}>Home</Link>
] ]
</span> </span>
@@ -783,13 +792,13 @@ const SubscriptionsCatalog = () => {
marginTop: "5px", marginTop: "5px",
marginBottom: "15px", marginBottom: "15px",
}}> }}>
<a style={{textDecoration: 'underline'}} href="https://plebbit.com" target="_blank" rel="noopener noreferrer">About</a> <a style={{ textDecoration: 'underline' }} href="https://plebbit.com" target="_blank" rel="noopener noreferrer">About</a>
&nbsp;&nbsp; &nbsp;&nbsp;
<a style={{textDecoration: 'underline'}} href="https://github.com/plebbit/plebchan/releases/latest" target="_blank" rel="noopener noreferrer">App</a> <a style={{ textDecoration: 'underline' }} href="https://github.com/plebbit/plebchan/releases/latest" target="_blank" rel="noopener noreferrer">App</a>
&nbsp;&nbsp; &nbsp;&nbsp;
<a style={{textDecoration: 'underline'}} href="https://twitter.com/plebchan_eth" target="_blank" rel="noopener noreferrer">Twitter</a> <a style={{ textDecoration: 'underline' }} href="https://twitter.com/plebchan_eth" target="_blank" rel="noopener noreferrer">Twitter</a>
&nbsp;&nbsp; &nbsp;&nbsp;
<a style={{textDecoration: 'underline'}} href="https://t.me/plebbit" target="_blank" rel="noopener noreferrer">Telegram</a> <a style={{ textDecoration: 'underline' }} href="https://t.me/plebbit" target="_blank" rel="noopener noreferrer">Telegram</a>
</div> </div>
</Footer> </Footer>
</Container> </Container>