mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "plebchan",
|
"name": "plebchan",
|
||||||
"version": "0.1.8",
|
"version": "0.1.9",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adraffy/ens-normalize": "1.8.3",
|
"@adraffy/ens-normalize": "1.8.3",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const OfflineIndicator = ({ address, className, tooltipPlace }) => {
|
|||||||
data-tooltip-id="tooltip"
|
data-tooltip-id="tooltip"
|
||||||
data-tooltip-content="Offline"
|
data-tooltip-content="Offline"
|
||||||
data-tooltip-place={tooltipPlace}
|
data-tooltip-place={tooltipPlace}
|
||||||
|
style={{imageRendering: 'pixelated'}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ const PostOnHover = ({ cid, feed }) => {
|
|||||||
{reply.replies?.pages?.topAll.comments
|
{reply.replies?.pages?.topAll.comments
|
||||||
.sort((a, b) => a.timestamp - b.timestamp)
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
.map((reply, index) => (
|
.map((reply, index) => (
|
||||||
<div style={{display: 'inline-block'}}>
|
<div key={`div-${index}`} style={{display: 'inline-block'}}>
|
||||||
<Link to={() => {}}
|
<Link key={`link-${index}`} to={() => {}}
|
||||||
className="quote-link">
|
className="quote-link">
|
||||||
c/{reply.shortCid}</Link>
|
c/{reply.shortCid}</Link>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
|
import Modal from 'react-modal';
|
||||||
|
import Draggable from 'react-draggable';
|
||||||
|
import { StyledModal } from '../styled/modals/ReplyModal.styled';
|
||||||
|
import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
||||||
|
import { BoardForm } from '../styled/views/Board.styled'
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const AdminListModal = ({ isOpen, closeModal, roles }) => {
|
||||||
|
const {
|
||||||
|
selectedAddress,
|
||||||
|
selectedStyle,
|
||||||
|
selectedTitle,
|
||||||
|
} = useGeneralStore(state => state);
|
||||||
|
|
||||||
|
const [isMobile, setIsMobile] = useState(window.innerWidth <= 480);
|
||||||
|
const nodeRef = useRef(null);
|
||||||
|
const rolesList = roles
|
||||||
|
? Object.entries(roles).map(([address, { role }]) => ({ address, role }))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => setIsMobile(window.innerWidth <= 480);
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
|
||||||
|
// Cleanup function
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
};
|
||||||
|
}, [setIsMobile]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledModal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onRequestClose={closeModal}
|
||||||
|
contentLabel="Reply Modal"
|
||||||
|
shouldCloseOnEsc={true}
|
||||||
|
shouldCloseOnOverlayClick={isMobile}
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
overlayClassName="overlay"
|
||||||
|
style={isMobile ? ({ overlay: { backgroundColor: "rgba(0,0,0,.25)" }}) : ({ overlay: { backgroundColor: "rgba(0,0,0,0)" }})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Draggable handle=".modal-header" nodeRef={nodeRef} disabled={isMobile}>
|
||||||
|
<div className="modal-content" ref={nodeRef}
|
||||||
|
style={{
|
||||||
|
maxWidth: '300px',
|
||||||
|
maxHeight: '250px',
|
||||||
|
}}>
|
||||||
|
<div className="modal-header">
|
||||||
|
Admins for {selectedTitle ?? selectedAddress}
|
||||||
|
<button className="icon" onClick={() => closeModal()} title="close" />
|
||||||
|
</div>
|
||||||
|
<div className='list' style={{
|
||||||
|
padding: '10px',
|
||||||
|
maxHeight: '200px',
|
||||||
|
maxWidth: '300px',
|
||||||
|
overflowY: 'auto',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
wordWrap: 'break-word',
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
}}>
|
||||||
|
<BoardForm selectedStyle={selectedStyle} style={{all: 'unset'}}>
|
||||||
|
{rolesList.map(({ address, role }, index) => (
|
||||||
|
<p key={index}>
|
||||||
|
• <Link to={() => {}} className="quote-link">u/{address}</Link>: {role}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</BoardForm>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Draggable>
|
||||||
|
</StyledModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Modal.setAppElement('#root');
|
||||||
|
|
||||||
|
export default AdminListModal;
|
||||||
@@ -130,13 +130,20 @@ const ModerationModal = ({ isOpen, closeModal, deletePost }) => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -188,43 +188,49 @@ const ReplyModal = ({ isOpen, closeModal }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
const updateSigner = useCallback(async () => {
|
||||||
const updateSigner = async () => {
|
if (anonymousMode) {
|
||||||
if (anonymousMode) {
|
setExecuteAnonMode(true);
|
||||||
setExecuteAnonMode(true);
|
|
||||||
|
|
||||||
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
||||||
let signer;
|
let signer;
|
||||||
|
|
||||||
if (!storedSigners[selectedParentCid]) {
|
if (!storedSigners[selectedParentCid]) {
|
||||||
signer = await account?.plebbit.createSigner();
|
signer = await account?.plebbit.createSigner();
|
||||||
storedSigners[selectedParentCid] = { privateKey: signer?.privateKey, address: signer?.address };
|
storedSigners[selectedParentCid] = { privateKey: signer?.privateKey, address: signer?.address };
|
||||||
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
||||||
|
} else {
|
||||||
|
const signerPrivateKey = storedSigners[selectedParentCid].privateKey;
|
||||||
|
|
||||||
} else {
|
try {
|
||||||
const signerPrivateKey = storedSigners[selectedParentCid].privateKey;
|
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
||||||
|
} catch (error) {
|
||||||
try {
|
console.log(error);
|
||||||
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setPublishCommentOptions((prevPublishCommentOptions) => ({
|
setPublishCommentOptions(prevPublishCommentOptions => {
|
||||||
|
const newPublishCommentOptions = {
|
||||||
...prevPublishCommentOptions,
|
...prevPublishCommentOptions,
|
||||||
signer,
|
signer,
|
||||||
author: {
|
author: {
|
||||||
...prevPublishCommentOptions.author,
|
...prevPublishCommentOptions.author,
|
||||||
address: signer?.address
|
address: signer?.address
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
|
|
||||||
}
|
if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) {
|
||||||
};
|
return newPublishCommentOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevPublishCommentOptions;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [selectedParentCid, anonymousMode, account]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
updateSigner();
|
updateSigner();
|
||||||
}, [selectedParentCid, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]);
|
}, [updateSigner]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
|
|||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
<li className="settings-tip anon-tip">
|
<li className="settings-tip anon-tip">
|
||||||
Automatically uses a different account (u/address) per thread.
|
Automatically use a different u/address per thread to post.
|
||||||
</li>
|
</li>
|
||||||
<li className="settings-option disc">
|
<li className="settings-option disc">
|
||||||
Account Data
|
Account Data
|
||||||
|
|||||||
@@ -1678,13 +1678,13 @@ export const BoardForm = styled.div`
|
|||||||
|
|
||||||
.offline-sub {
|
.offline-sub {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
margin: -5px -4px -4px 3px;
|
margin: -5px -4px -2px 3px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.offline-reply {
|
.offline-reply {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
margin: -5px -4px -4px 3px;
|
margin: -5px -4px -2px 3px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,23 +102,11 @@ const All = () => {
|
|||||||
const [moderatorPermissions, setModeratorPermissions] = useState({});
|
const [moderatorPermissions, setModeratorPermissions] = useState({});
|
||||||
const [executeAnonMode, setExecuteAnonMode] = useState(false);
|
const [executeAnonMode, setExecuteAnonMode] = useState(false);
|
||||||
const [cidTracker, setCidTracker] = useState({});
|
const [cidTracker, setCidTracker] = useState({});
|
||||||
const [displayedReplies, setDisplayedReplies] = useState([]);
|
|
||||||
|
|
||||||
const setSelectedThreadCid = (cid) => {
|
const setSelectedThreadCid = (cid) => {
|
||||||
selectedThreadCidRef.current = cid;
|
selectedThreadCidRef.current = cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let post.jsx access full cid of user-typed short cid
|
|
||||||
useEffect(() => {
|
|
||||||
const newCidTracker = {};
|
|
||||||
displayedReplies.forEach((reply) => {
|
|
||||||
newCidTracker[reply.shortCid] = reply.cid;
|
|
||||||
});
|
|
||||||
setCidTracker(newCidTracker);
|
|
||||||
}, [displayedReplies]);
|
|
||||||
|
|
||||||
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
|
||||||
|
|
||||||
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
||||||
|
|
||||||
const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address);
|
const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address);
|
||||||
@@ -251,6 +239,19 @@ const All = () => {
|
|||||||
}, {});
|
}, {});
|
||||||
}, [flattenedRepliesByThread, accountComments, selectedFeed]);
|
}, [flattenedRepliesByThread, accountComments, selectedFeed]);
|
||||||
|
|
||||||
|
const allReplies = useMemo(() => {
|
||||||
|
return selectedFeed.flatMap(thread => filteredRepliesByThread[thread.cid]?.displayedReplies || []);
|
||||||
|
}, [selectedFeed, filteredRepliesByThread]);
|
||||||
|
|
||||||
|
// let post.jsx access full cid of user-typed short cid
|
||||||
|
useEffect(() => {
|
||||||
|
const newCidTracker = {};
|
||||||
|
allReplies.forEach((reply) => {
|
||||||
|
newCidTracker[reply.shortCid] = reply.cid;
|
||||||
|
});
|
||||||
|
setCidTracker(newCidTracker);
|
||||||
|
}, [allReplies]);
|
||||||
|
|
||||||
// mobile navbar scroll effect
|
// mobile navbar scroll effect
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const debouncedHandleScroll = debounce(() => {
|
const debouncedHandleScroll = debounce(() => {
|
||||||
@@ -415,13 +416,20 @@ const All = () => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
// desktop navbar board select functionality
|
// desktop navbar board select functionality
|
||||||
const handleClickTitle = (title, address) => {
|
const handleClickTitle = (title, address) => {
|
||||||
@@ -597,7 +605,6 @@ const All = () => {
|
|||||||
data={selectedFeed}
|
data={selectedFeed}
|
||||||
itemContent={(index, thread) => {
|
itemContent={(index, thread) => {
|
||||||
const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {};
|
const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {};
|
||||||
setDisplayedReplies(displayedReplies);
|
|
||||||
const commentMediaInfo = getCommentMediaInfo(thread);
|
const commentMediaInfo = getCommentMediaInfo(thread);
|
||||||
const fallbackImgUrl = "assets/filedeleted-res.gif";
|
const fallbackImgUrl = "assets/filedeleted-res.gif";
|
||||||
const isModerator = moderatorPermissions[thread.subplebbitAddress];
|
const isModerator = moderatorPermissions[thread.subplebbitAddress];
|
||||||
|
|||||||
@@ -278,13 +278,20 @@ const AllCatalog = () => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
|
|
||||||
// mobile navbar board select functionality
|
// mobile navbar board select functionality
|
||||||
|
|||||||
+112
-65
@@ -14,6 +14,7 @@ import { PostMenuCatalog } from '../styled/views/Catalog.styled';
|
|||||||
import EditModal from '../modals/EditModal';
|
import EditModal from '../modals/EditModal';
|
||||||
import EditLabel from '../EditLabel';
|
import EditLabel from '../EditLabel';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import AdminListModal from '../modals/AdminListModal';
|
||||||
import ModerationModal from '../modals/ModerationModal';
|
import ModerationModal from '../modals/ModerationModal';
|
||||||
import OfflineIndicator from '../OfflineIndicator';
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import PendingLabel from '../PendingLabel';
|
import PendingLabel from '../PendingLabel';
|
||||||
@@ -100,6 +101,7 @@ const Board = () => {
|
|||||||
const { subscribed, subscribe, unsubscribe } = useSubscribe({subplebbitAddress: selectedAddress});
|
const { subscribed, subscribe, unsubscribe } = useSubscribe({subplebbitAddress: selectedAddress});
|
||||||
const stateString = useStateString(subplebbit);
|
const stateString = useStateString(subplebbit);
|
||||||
|
|
||||||
|
const [isAdminListOpen, setIsAdminListOpen] = useState(false);
|
||||||
const [isReplyOpen, setIsReplyOpen] = useState(false);
|
const [isReplyOpen, setIsReplyOpen] = useState(false);
|
||||||
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
|
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
|
||||||
const [originalCommentContent, setOriginalCommentContent] = useState(null);
|
const [originalCommentContent, setOriginalCommentContent] = useState(null);
|
||||||
@@ -119,20 +121,8 @@ const Board = () => {
|
|||||||
const [postOnHoverHeight, setPostOnHoverHeight] = useState(0);
|
const [postOnHoverHeight, setPostOnHoverHeight] = useState(0);
|
||||||
const [executeAnonMode, setExecuteAnonMode] = useState(false);
|
const [executeAnonMode, setExecuteAnonMode] = useState(false);
|
||||||
const [cidTracker, setCidTracker] = useState({});
|
const [cidTracker, setCidTracker] = useState({});
|
||||||
const [displayedReplies, setDisplayedReplies] = useState([]);
|
|
||||||
|
|
||||||
const setSelectedThreadCid = (cid) => {
|
const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid;}
|
||||||
selectedThreadCidRef.current = cid;
|
|
||||||
}
|
|
||||||
|
|
||||||
// let post.jsx access full cid of user-typed short cid
|
|
||||||
useEffect(() => {
|
|
||||||
const newCidTracker = {};
|
|
||||||
displayedReplies.forEach((reply) => {
|
|
||||||
newCidTracker[reply.shortCid] = reply.cid;
|
|
||||||
});
|
|
||||||
setCidTracker(newCidTracker);
|
|
||||||
}, [displayedReplies]);
|
|
||||||
|
|
||||||
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
||||||
|
|
||||||
@@ -245,6 +235,19 @@ const Board = () => {
|
|||||||
}, {});
|
}, {});
|
||||||
}, [flattenedRepliesByThread, accountComments, selectedFeed]);
|
}, [flattenedRepliesByThread, accountComments, selectedFeed]);
|
||||||
|
|
||||||
|
const allReplies = useMemo(() => {
|
||||||
|
return selectedFeed.flatMap(thread => filteredRepliesByThread[thread.cid]?.displayedReplies || []);
|
||||||
|
}, [selectedFeed, filteredRepliesByThread]);
|
||||||
|
|
||||||
|
// let post.jsx access full cid of user-typed short cid
|
||||||
|
useEffect(() => {
|
||||||
|
const newCidTracker = {};
|
||||||
|
allReplies.forEach((reply) => {
|
||||||
|
newCidTracker[reply.shortCid] = reply.cid;
|
||||||
|
});
|
||||||
|
setCidTracker(newCidTracker);
|
||||||
|
}, [allReplies]);
|
||||||
|
|
||||||
|
|
||||||
// temporary title from JSON, gets subplebbitAddress from URL
|
// temporary title from JSON, gets subplebbitAddress from URL
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -380,43 +383,49 @@ const Board = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
const updateSigner = useCallback(async () => {
|
||||||
const updateSigner = async () => {
|
if (anonymousMode) {
|
||||||
if (anonymousMode) {
|
setExecuteAnonMode(true);
|
||||||
setExecuteAnonMode(true);
|
|
||||||
|
|
||||||
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
||||||
let signer;
|
let signer;
|
||||||
|
|
||||||
if (!storedSigners[selectedThreadCidRef]) {
|
if (!storedSigners[selectedThreadCidRef]) {
|
||||||
signer = await account?.plebbit.createSigner();
|
signer = await account?.plebbit.createSigner();
|
||||||
storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address };
|
storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address };
|
||||||
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
||||||
|
} else {
|
||||||
|
const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey;
|
||||||
|
|
||||||
} else {
|
try {
|
||||||
const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey;
|
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
||||||
|
} catch (error) {
|
||||||
try {
|
console.log(error);
|
||||||
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setPublishCommentOptions((prevPublishCommentOptions) => ({
|
setPublishCommentOptions(prevPublishCommentOptions => {
|
||||||
|
const newPublishCommentOptions = {
|
||||||
...prevPublishCommentOptions,
|
...prevPublishCommentOptions,
|
||||||
signer,
|
signer,
|
||||||
author: {
|
author: {
|
||||||
...prevPublishCommentOptions.author,
|
...prevPublishCommentOptions.author,
|
||||||
address: signer?.address
|
address: signer?.address
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
|
|
||||||
}
|
if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) {
|
||||||
};
|
return newPublishCommentOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevPublishCommentOptions;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [selectedThreadCidRef, anonymousMode, account]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
updateSigner();
|
updateSigner();
|
||||||
}, [selectedThreadCidRef, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]);
|
}, [updateSigner]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -543,13 +552,21 @@ const Board = () => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
|
|
||||||
// desktop navbar board select functionality
|
// desktop navbar board select functionality
|
||||||
const handleClickTitle = (title, address) => {
|
const handleClickTitle = (title, address) => {
|
||||||
@@ -609,6 +626,21 @@ const Board = () => {
|
|||||||
<title>{((selectedTitle ? selectedTitle : selectedAddress) + " - plebchan")}</title>
|
<title>{((selectedTitle ? selectedTitle : selectedAddress) + " - plebchan")}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<Container>
|
<Container>
|
||||||
|
<AdminListModal
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
isOpen={isAdminListOpen}
|
||||||
|
closeModal={() => setIsAdminListOpen(false)}
|
||||||
|
roles={subplebbit.roles} />
|
||||||
|
<EditModal
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
isOpen={isEditModalOpen}
|
||||||
|
closeModal={() => setIsEditModalOpen(false)}
|
||||||
|
originalCommentContent={originalCommentContent} />
|
||||||
|
<ModerationModal
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
isOpen={isModerationOpen}
|
||||||
|
closeModal={() => {setIsModerationOpen(false); setDeletePost(false)}}
|
||||||
|
deletePost={deletePost} />
|
||||||
<ReplyModal
|
<ReplyModal
|
||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isReplyOpen}
|
isOpen={isReplyOpen}
|
||||||
@@ -617,16 +649,6 @@ const Board = () => {
|
|||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isSettingsOpen}
|
isOpen={isSettingsOpen}
|
||||||
closeModal={() => setIsSettingsOpen(false)} />
|
closeModal={() => setIsSettingsOpen(false)} />
|
||||||
<ModerationModal
|
|
||||||
selectedStyle={selectedStyle}
|
|
||||||
isOpen={isModerationOpen}
|
|
||||||
closeModal={() => {setIsModerationOpen(false); setDeletePost(false)}}
|
|
||||||
deletePost={deletePost} />
|
|
||||||
<EditModal
|
|
||||||
selectedStyle={selectedStyle}
|
|
||||||
isOpen={isEditModalOpen}
|
|
||||||
closeModal={() => setIsEditModalOpen(false)}
|
|
||||||
originalCommentContent={originalCommentContent} />
|
|
||||||
<NavBar selectedStyle={selectedStyle}>
|
<NavBar selectedStyle={selectedStyle}>
|
||||||
<>
|
<>
|
||||||
<span className="boardList">
|
<span className="boardList">
|
||||||
@@ -821,13 +843,18 @@ const Board = () => {
|
|||||||
<span className="name-block">
|
<span className="name-block">
|
||||||
<span className="title">Rules</span>
|
<span className="title">Rules</span>
|
||||||
|
|
||||||
<span className="name capcode">## Board Admins</span>
|
<span className="name capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
||||||
|
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
<span>
|
<span>
|
||||||
[
|
[
|
||||||
<Link to={`/p/${selectedAddress}/rules`} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
<Link to={`/p/${selectedAddress}/rules`} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
||||||
@@ -893,13 +920,18 @@ const Board = () => {
|
|||||||
<button className="post-menu-button-mobile"
|
<button className="post-menu-button-mobile"
|
||||||
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
||||||
<span className="name-block-mobile">
|
<span className="name-block-mobile">
|
||||||
<span className="name-mobile capcode">## Board Admins</span>
|
<span className="name-mobile capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="thread-icons-mobile"
|
<span className="thread-icons-mobile"
|
||||||
style={{float: "right", marginRight: "18px"}}>
|
style={{float: "right", marginRight: "18px"}}>
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<span className="subject-mobile"
|
<span className="subject-mobile"
|
||||||
@@ -960,13 +992,18 @@ const Board = () => {
|
|||||||
<span className="name-block">
|
<span className="name-block">
|
||||||
<span className="title">Welcome to {subplebbit.title || subplebbit.address}</span>
|
<span className="title">Welcome to {subplebbit.title || subplebbit.address}</span>
|
||||||
|
|
||||||
<span className="name capcode">## Board Admins</span>
|
<span className="name capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
||||||
|
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
<span>
|
<span>
|
||||||
[
|
[
|
||||||
<Link to={`/p/${selectedAddress}/description`} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
<Link to={`/p/${selectedAddress}/description`} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
||||||
@@ -1030,13 +1067,18 @@ const Board = () => {
|
|||||||
<button className="post-menu-button-mobile"
|
<button className="post-menu-button-mobile"
|
||||||
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
||||||
<span className="name-block-mobile">
|
<span className="name-block-mobile">
|
||||||
<span className="name-mobile capcode">## Board Admins</span>
|
<span className="name-mobile capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="thread-icons-mobile"
|
<span className="thread-icons-mobile"
|
||||||
style={{float: "right", marginRight: "18px"}}>
|
style={{float: "right", marginRight: "18px"}}>
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<span className="subject-mobile"
|
<span className="subject-mobile"
|
||||||
@@ -1076,7 +1118,6 @@ const Board = () => {
|
|||||||
data={selectedFeed}
|
data={selectedFeed}
|
||||||
itemContent={(index, thread) => {
|
itemContent={(index, thread) => {
|
||||||
const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {};
|
const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {};
|
||||||
setDisplayedReplies(displayedReplies);
|
|
||||||
const commentMediaInfo = getCommentMediaInfo(thread);
|
const commentMediaInfo = getCommentMediaInfo(thread);
|
||||||
const fallbackImgUrl = "assets/filedeleted-res.gif";
|
const fallbackImgUrl = "assets/filedeleted-res.gif";
|
||||||
return (
|
return (
|
||||||
@@ -1201,14 +1242,18 @@ const Board = () => {
|
|||||||
<>
|
<>
|
||||||
|
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
||||||
style={{marginBottom: "-3px"}} />
|
style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
{thread.locked ? (
|
{thread.locked ? (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
||||||
style={{marginBottom: "-3px"}} />
|
style={{
|
||||||
|
marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",
|
||||||
|
}} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<span key={`rl1-${index}`}>
|
<span key={`rl1-${index}`}>
|
||||||
@@ -1959,11 +2004,13 @@ const Board = () => {
|
|||||||
<span key={`ti-mob-${index}`} className="thread-icons-mobile" style={{float: "right", marginRight: "18px"}}>
|
<span key={`ti-mob-${index}`} className="thread-icons-mobile" style={{float: "right", marginRight: "18px"}}>
|
||||||
{thread.pinned ? (
|
{thread.pinned ? (
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
||||||
style={{marginBottom: "-3px", marginRight: "2px"}} />
|
style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
) : null}
|
) : null}
|
||||||
{thread.locked ? (
|
{thread.locked ? (
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
||||||
style={{marginBottom: "-3px", marginRight: "2px"}} />
|
style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
) : null}
|
) : null}
|
||||||
</span>
|
</span>
|
||||||
<br key={`mob-br1-${index}`} />
|
<br key={`mob-br1-${index}`} />
|
||||||
|
|||||||
@@ -282,43 +282,49 @@ const Catalog = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
const updateSigner = useCallback(async () => {
|
||||||
const updateSigner = async () => {
|
if (anonymousMode) {
|
||||||
if (anonymousMode) {
|
setExecuteAnonMode(true);
|
||||||
setExecuteAnonMode(true);
|
|
||||||
|
|
||||||
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
||||||
let signer;
|
let signer;
|
||||||
|
|
||||||
if (!storedSigners[selectedThreadCidRef]) {
|
if (!storedSigners[selectedThreadCidRef]) {
|
||||||
signer = await account?.plebbit.createSigner();
|
signer = await account?.plebbit.createSigner();
|
||||||
storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address };
|
storedSigners[selectedThreadCidRef] = { privateKey: signer?.privateKey, address: signer?.address };
|
||||||
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
||||||
|
} else {
|
||||||
|
const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey;
|
||||||
|
|
||||||
} else {
|
try {
|
||||||
const signerPrivateKey = storedSigners[selectedThreadCidRef].privateKey;
|
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
||||||
|
} catch (error) {
|
||||||
try {
|
console.log(error);
|
||||||
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setPublishCommentOptions((prevPublishCommentOptions) => ({
|
setPublishCommentOptions(prevPublishCommentOptions => {
|
||||||
|
const newPublishCommentOptions = {
|
||||||
...prevPublishCommentOptions,
|
...prevPublishCommentOptions,
|
||||||
signer,
|
signer,
|
||||||
author: {
|
author: {
|
||||||
...prevPublishCommentOptions.author,
|
...prevPublishCommentOptions.author,
|
||||||
address: signer?.address
|
address: signer?.address
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
|
|
||||||
}
|
if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) {
|
||||||
};
|
return newPublishCommentOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevPublishCommentOptions;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [selectedThreadCidRef, anonymousMode, account]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
updateSigner();
|
updateSigner();
|
||||||
}, [selectedThreadCidRef, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]);
|
}, [updateSigner]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -706,8 +712,12 @@ const Catalog = () => {
|
|||||||
R:<b>0</b>
|
R:<b>0</b>
|
||||||
<div className='thread-icons'
|
<div className='thread-icons'
|
||||||
style={{position: 'absolute', top: '-2px', right: '15px'}}>
|
style={{position: 'absolute', top: '-2px', right: '15px'}}>
|
||||||
<span className="thread-icon sticky-icon" title="Sticky" />
|
<span className="thread-icon sticky-icon" title="Sticky"
|
||||||
<span className="thread-icon closed-icon" title="Closed" />
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
<span className="thread-icon closed-icon" title="Closed"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</div>
|
</div>
|
||||||
<PostMenu
|
<PostMenu
|
||||||
style={{ display: isHoveringOnThread === "rules" ? 'inline-block' : 'none',
|
style={{ display: isHoveringOnThread === "rules" ? 'inline-block' : 'none',
|
||||||
@@ -773,8 +783,12 @@ const Catalog = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
{subplebbit.suggested?.avatarUrl ? (
|
{subplebbit.suggested?.avatarUrl ? (
|
||||||
<div className='thread-icons'>
|
<div className='thread-icons'>
|
||||||
<span className="thread-icon sticky-icon" title="Sticky" />
|
<span className="thread-icon sticky-icon" title="Sticky"
|
||||||
<span className="thread-icon closed-icon" title="Closed" />
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
<span className="thread-icon closed-icon" title="Closed"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<BoardForm selectedStyle={selectedStyle} style={{all: 'unset'}}>
|
<BoardForm selectedStyle={selectedStyle} style={{all: 'unset'}}>
|
||||||
@@ -783,8 +797,12 @@ const Catalog = () => {
|
|||||||
{subplebbit.suggested?.avatarUrl ? null : (
|
{subplebbit.suggested?.avatarUrl ? null : (
|
||||||
<div className='thread-icons'
|
<div className='thread-icons'
|
||||||
style={{position: 'absolute', top: '-2px', right: '15px'}}>
|
style={{position: 'absolute', top: '-2px', right: '15px'}}>
|
||||||
<span className="thread-icon sticky-icon" title="Sticky" />
|
<span className="thread-icon sticky-icon" title="Sticky"
|
||||||
<span className="thread-icon closed-icon" title="Closed" />
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
<span className="thread-icon closed-icon" title="Closed"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<PostMenu
|
<PostMenu
|
||||||
@@ -917,10 +935,14 @@ const Catalog = () => {
|
|||||||
commentMediaInfo.thumbnail))) ? (
|
commentMediaInfo.thumbnail))) ? (
|
||||||
<div key={`ti-${index}`} className="thread-icons" >
|
<div key={`ti-${index}`} className="thread-icons" >
|
||||||
{thread.pinned ? (
|
{thread.pinned ? (
|
||||||
<span key={`si-${index}`} className="thread-icon sticky-icon" title="Sticky" />
|
<span key={`si-${index}`} className="thread-icon sticky-icon" title="Sticky"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
) : null}
|
) : null}
|
||||||
{thread.locked ? (
|
{thread.locked ? (
|
||||||
<span key={`li-${index}`} className="thread-icon closed-icon" title="Closed" />
|
<span key={`li-${index}`} className="thread-icon closed-icon" title="Closed"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -937,10 +959,14 @@ const Catalog = () => {
|
|||||||
<div className='thread-icons'
|
<div className='thread-icons'
|
||||||
style={{position: 'absolute', top: '-2px', right: '15px'}}>
|
style={{position: 'absolute', top: '-2px', right: '15px'}}>
|
||||||
{thread.pinned ? (
|
{thread.pinned ? (
|
||||||
<span key={`si-${index}`} className="thread-icon sticky-icon" title="Sticky" />
|
<span key={`si-${index}`} className="thread-icon sticky-icon" title="Sticky"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
) : null}
|
) : null}
|
||||||
{thread.locked ? (
|
{thread.locked ? (
|
||||||
<span key={`li-${index}`} className="thread-icon closed-icon" title="Closed" />
|
<span key={`li-${index}`} className="thread-icon closed-icon" title="Closed"
|
||||||
|
style={{
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Container, NavBar, Header, Break, PostMenu, PostForm } from '../styled/
|
|||||||
import { TopBar, BoardForm, Footer, ReplyFormLink} from '../styled/views/Thread.styled';
|
import { TopBar, BoardForm, Footer, ReplyFormLink} from '../styled/views/Thread.styled';
|
||||||
import { PostMenuCatalog } from '../styled/views/Catalog.styled';
|
import { PostMenuCatalog } from '../styled/views/Catalog.styled';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import AdminListModal from '../modals/AdminListModal';
|
||||||
import OfflineIndicator from '../OfflineIndicator';
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import SettingsModal from '../modals/SettingsModal';
|
import SettingsModal from '../modals/SettingsModal';
|
||||||
import getDate from '../../utils/getDate';
|
import getDate from '../../utils/getDate';
|
||||||
@@ -35,6 +36,7 @@ const Description = () => {
|
|||||||
const postMenuRef = useRef(null);
|
const postMenuRef = useRef(null);
|
||||||
const postMenuCatalogRef = useRef(null);
|
const postMenuCatalogRef = useRef(null);
|
||||||
|
|
||||||
|
const [isAdminListOpen, setIsAdminListOpen] = useState(false);
|
||||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||||
const [visible, setVisible] = useState(true);
|
const [visible, setVisible] = useState(true);
|
||||||
const [menuPosition, setMenuPosition] = useState({top: 0, left: 0});
|
const [menuPosition, setMenuPosition] = useState({top: 0, left: 0});
|
||||||
@@ -123,6 +125,11 @@ const Description = () => {
|
|||||||
</title>
|
</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<Container>
|
<Container>
|
||||||
|
<AdminListModal
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
isOpen={isAdminListOpen}
|
||||||
|
closeModal={() => setIsAdminListOpen(false)}
|
||||||
|
roles={subplebbit.roles} />
|
||||||
<SettingsModal
|
<SettingsModal
|
||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isSettingsOpen}
|
isOpen={isSettingsOpen}
|
||||||
@@ -295,13 +302,16 @@ const Description = () => {
|
|||||||
<span className="name-block">
|
<span className="name-block">
|
||||||
<span className="title">Welcome to {subplebbit.title || subplebbit.address}</span>
|
<span className="title">Welcome to {subplebbit.title || subplebbit.address}</span>
|
||||||
|
|
||||||
<span className="name capcode">## Board Admins</span>
|
<span className="name capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
||||||
|
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px", imageRendering: 'pixelated'}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-1px", imageRendering: 'pixelated'}} />
|
||||||
<span>
|
<span>
|
||||||
[
|
[
|
||||||
<Link to={() => {}} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
<Link to={() => {}} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
||||||
@@ -362,13 +372,16 @@ const Description = () => {
|
|||||||
<button className="post-menu-button-mobile"
|
<button className="post-menu-button-mobile"
|
||||||
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
||||||
<span className="name-block-mobile">
|
<span className="name-block-mobile">
|
||||||
<span className="name-mobile capcode">## Board Admins</span>
|
<span className="name-mobile capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="thread-icons-mobile"
|
<span className="thread-icons-mobile"
|
||||||
style={{float: "right", marginRight: "18px"}}>
|
style={{float: "right", marginRight: "18px"}}>
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginTop: "-1px", marginRight: "2px", imageRendering: 'pixelated'}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginTop: "-1px", marginRight: "2px", imageRendering: 'pixelated'}} />
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<span className="subject-mobile"
|
<span className="subject-mobile"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Container, NavBar, Header, Break, PostMenu, PostForm } from '../styled/
|
|||||||
import { TopBar, BoardForm, Footer, ReplyFormLink} from '../styled/views/Thread.styled';
|
import { TopBar, BoardForm, Footer, ReplyFormLink} from '../styled/views/Thread.styled';
|
||||||
import { PostMenuCatalog } from '../styled/views/Catalog.styled';
|
import { PostMenuCatalog } from '../styled/views/Catalog.styled';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import AdminListModal from '../modals/AdminListModal';
|
||||||
import OfflineIndicator from '../OfflineIndicator';
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import SettingsModal from '../modals/SettingsModal';
|
import SettingsModal from '../modals/SettingsModal';
|
||||||
import getDate from '../../utils/getDate';
|
import getDate from '../../utils/getDate';
|
||||||
@@ -34,6 +35,7 @@ const Rules = () => {
|
|||||||
const postMenuRef = useRef(null);
|
const postMenuRef = useRef(null);
|
||||||
const postMenuCatalogRef = useRef(null);
|
const postMenuCatalogRef = useRef(null);
|
||||||
|
|
||||||
|
const [isAdminListOpen, setIsAdminListOpen] = useState(false);
|
||||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||||
const [visible, setVisible] = useState(true);
|
const [visible, setVisible] = useState(true);
|
||||||
const [menuPosition, setMenuPosition] = useState({top: 0, left: 0});
|
const [menuPosition, setMenuPosition] = useState({top: 0, left: 0});
|
||||||
@@ -122,6 +124,11 @@ const Rules = () => {
|
|||||||
</title>
|
</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<Container>
|
<Container>
|
||||||
|
<AdminListModal
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
isOpen={isAdminListOpen}
|
||||||
|
closeModal={() => setIsAdminListOpen(false)}
|
||||||
|
roles={subplebbit.roles} />
|
||||||
<SettingsModal
|
<SettingsModal
|
||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isSettingsOpen}
|
isOpen={isSettingsOpen}
|
||||||
@@ -270,13 +277,16 @@ const Rules = () => {
|
|||||||
<span className="name-block">
|
<span className="name-block">
|
||||||
<span className="title">Rules</span>
|
<span className="title">Rules</span>
|
||||||
|
|
||||||
<span className="name capcode">## Board Admins</span>
|
<span className="name capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
|
||||||
|
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px", imageRendering: 'pixelated'}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-1px", imageRendering: 'pixelated'}} />
|
||||||
<span>
|
<span>
|
||||||
[
|
[
|
||||||
<Link to={() => {}} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
<Link to={() => {}} style={{textDecoration: "none"}} className="reply-link">Reply</Link>
|
||||||
@@ -342,13 +352,16 @@ const Rules = () => {
|
|||||||
<button className="post-menu-button-mobile"
|
<button className="post-menu-button-mobile"
|
||||||
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
style={{ all: 'unset', cursor: 'pointer' }}>...</button>
|
||||||
<span className="name-block-mobile">
|
<span className="name-block-mobile">
|
||||||
<span className="name-mobile capcode">## Board Admins</span>
|
<span className="name-mobile capcode"
|
||||||
|
style={{cursor: 'pointer'}}
|
||||||
|
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||||
|
>## Board Admins</span>
|
||||||
|
|
||||||
<span className="thread-icons-mobile"
|
<span className="thread-icons-mobile"
|
||||||
style={{float: "right", marginRight: "18px"}}>
|
style={{float: "right", marginRight: "18px"}}>
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-3px"}} />
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginTop: "-1px", marginRight: "2px", imageRendering: 'pixelated'}} />
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginBottom: "-3px"}} />
|
<img src="assets/closed.gif" alt="Closed" title="Closed" style={{marginTop: "-1px", marginRight: "2px", imageRendering: 'pixelated'}} />
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<span className="subject-mobile"
|
<span className="subject-mobile"
|
||||||
|
|||||||
@@ -102,21 +102,11 @@ const Subscriptions = () => {
|
|||||||
const [moderatorPermissions, setModeratorPermissions] = useState({});
|
const [moderatorPermissions, setModeratorPermissions] = useState({});
|
||||||
const [executeAnonMode, setExecuteAnonMode] = useState(false);
|
const [executeAnonMode, setExecuteAnonMode] = useState(false);
|
||||||
const [cidTracker, setCidTracker] = useState({});
|
const [cidTracker, setCidTracker] = useState({});
|
||||||
const [displayedReplies, setDisplayedReplies] = useState([]);
|
|
||||||
|
|
||||||
const setSelectedThreadCid = (cid) => {
|
const setSelectedThreadCid = (cid) => {
|
||||||
selectedThreadCidRef.current = cid;
|
selectedThreadCidRef.current = cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let post.jsx access full cid of user-typed short cid
|
|
||||||
useEffect(() => {
|
|
||||||
const newCidTracker = {};
|
|
||||||
displayedReplies.forEach((reply) => {
|
|
||||||
newCidTracker[reply.shortCid] = reply.cid;
|
|
||||||
});
|
|
||||||
setCidTracker(newCidTracker);
|
|
||||||
}, [displayedReplies]);
|
|
||||||
|
|
||||||
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
|
||||||
|
|
||||||
const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'});
|
const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'});
|
||||||
@@ -249,6 +239,19 @@ const Subscriptions = () => {
|
|||||||
}, {});
|
}, {});
|
||||||
}, [flattenedRepliesByThread, accountComments, selectedFeed]);
|
}, [flattenedRepliesByThread, accountComments, selectedFeed]);
|
||||||
|
|
||||||
|
const allReplies = useMemo(() => {
|
||||||
|
return selectedFeed.flatMap(thread => filteredRepliesByThread[thread.cid]?.displayedReplies || []);
|
||||||
|
}, [selectedFeed, filteredRepliesByThread]);
|
||||||
|
|
||||||
|
// let post.jsx access full cid of user-typed short cid
|
||||||
|
useEffect(() => {
|
||||||
|
const newCidTracker = {};
|
||||||
|
allReplies.forEach((reply) => {
|
||||||
|
newCidTracker[reply.shortCid] = reply.cid;
|
||||||
|
});
|
||||||
|
setCidTracker(newCidTracker);
|
||||||
|
}, [allReplies]);
|
||||||
|
|
||||||
// mobile navbar scroll effect
|
// mobile navbar scroll effect
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const debouncedHandleScroll = debounce(() => {
|
const debouncedHandleScroll = debounce(() => {
|
||||||
@@ -415,13 +418,20 @@ const Subscriptions = () => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
// desktop navbar board select functionality
|
// desktop navbar board select functionality
|
||||||
const handleClickTitle = (title, address) => {
|
const handleClickTitle = (title, address) => {
|
||||||
@@ -605,7 +615,6 @@ const Subscriptions = () => {
|
|||||||
data={selectedFeed}
|
data={selectedFeed}
|
||||||
itemContent={(index, thread) => {
|
itemContent={(index, thread) => {
|
||||||
const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {};
|
const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {};
|
||||||
setDisplayedReplies(displayedReplies);
|
|
||||||
const commentMediaInfo = getCommentMediaInfo(thread);
|
const commentMediaInfo = getCommentMediaInfo(thread);
|
||||||
const fallbackImgUrl = "assets/filedeleted-res.gif";
|
const fallbackImgUrl = "assets/filedeleted-res.gif";
|
||||||
const isModerator = moderatorPermissions[thread.subplebbitAddress];
|
const isModerator = moderatorPermissions[thread.subplebbitAddress];
|
||||||
|
|||||||
@@ -275,13 +275,20 @@ const SubscriptionsCatalog = () => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
// desktop navbar board select functionality
|
// desktop navbar board select functionality
|
||||||
const handleClickTitle = (title, address) => {
|
const handleClickTitle = (title, address) => {
|
||||||
|
|||||||
@@ -347,43 +347,49 @@ const Thread = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
const updateSigner = useCallback(async () => {
|
||||||
const updateSigner = async () => {
|
if (anonymousMode) {
|
||||||
if (anonymousMode) {
|
setExecuteAnonMode(true);
|
||||||
setExecuteAnonMode(true);
|
|
||||||
|
|
||||||
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
let storedSigners = JSON.parse(localStorage.getItem('storedSigners')) || {};
|
||||||
let signer;
|
let signer;
|
||||||
|
|
||||||
if (!storedSigners[selectedThread]) {
|
if (!storedSigners[selectedThread]) {
|
||||||
signer = await account?.plebbit.createSigner();
|
signer = await account?.plebbit.createSigner();
|
||||||
storedSigners[selectedThread] = { privateKey: signer?.privateKey, address: signer?.address };
|
storedSigners[selectedThread] = { privateKey: signer?.privateKey, address: signer?.address };
|
||||||
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
localStorage.setItem('storedSigners', JSON.stringify(storedSigners));
|
||||||
|
} else {
|
||||||
|
const signerPrivateKey = storedSigners[selectedThread].privateKey;
|
||||||
|
|
||||||
} else {
|
try {
|
||||||
const signerPrivateKey = storedSigners[selectedThread].privateKey;
|
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
||||||
|
} catch (error) {
|
||||||
try {
|
console.log(error);
|
||||||
signer = await account?.plebbit.createSigner({type: 'ed25519', privateKey: signerPrivateKey});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setPublishCommentOptions((prevPublishCommentOptions) => ({
|
setPublishCommentOptions(prevPublishCommentOptions => {
|
||||||
|
const newPublishCommentOptions = {
|
||||||
...prevPublishCommentOptions,
|
...prevPublishCommentOptions,
|
||||||
signer,
|
signer,
|
||||||
author: {
|
author: {
|
||||||
...prevPublishCommentOptions.author,
|
...prevPublishCommentOptions.author,
|
||||||
address: signer?.address
|
address: signer?.address
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
|
|
||||||
}
|
if (JSON.stringify(prevPublishCommentOptions) !== JSON.stringify(newPublishCommentOptions)) {
|
||||||
};
|
return newPublishCommentOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevPublishCommentOptions;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [selectedThread, anonymousMode, account]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
updateSigner();
|
updateSigner();
|
||||||
}, [selectedThread, anonymousMode, account, setPublishCommentOptions, setNewErrorMessage]);
|
}, [updateSigner]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -509,13 +515,20 @@ const Thread = () => {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let isActive = true;
|
||||||
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
if (publishCommentEditOptions && triggerPublishCommentEdit) {
|
||||||
(async () => {
|
(async () => {
|
||||||
await publishCommentEdit();
|
await publishCommentEdit();
|
||||||
setTriggerPublishCommentEdit(false);
|
if (isActive) {
|
||||||
|
setTriggerPublishCommentEdit(false);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}, [publishCommentEditOptions, triggerPublishCommentEdit, publishCommentEdit]);
|
|
||||||
|
return () => {
|
||||||
|
isActive = false;
|
||||||
|
};
|
||||||
|
}, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);
|
||||||
|
|
||||||
// mobile navbar board select functionality
|
// mobile navbar board select functionality
|
||||||
const handleSelectChange = (event) => {
|
const handleSelectChange = (event) => {
|
||||||
@@ -893,14 +906,16 @@ const Thread = () => {
|
|||||||
<>
|
<>
|
||||||
|
|
||||||
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
||||||
style={{marginBottom: "-3px"}} />
|
style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
{comment.locked ? (
|
{comment.locked ? (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
||||||
style={{marginBottom: "-3px"}} />
|
style={{marginBottom: "-1px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<PostMenu
|
<PostMenu
|
||||||
@@ -1492,6 +1507,18 @@ const Thread = () => {
|
|||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
</span>
|
</span>
|
||||||
|
<span key={`ti-mob-${index}`} className="thread-icons-mobile" style={{float: "right", marginRight: "18px"}}>
|
||||||
|
{comment.pinned ? (
|
||||||
|
<img src="assets/sticky.gif" alt="Sticky" title="Sticky"
|
||||||
|
style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
) : null}
|
||||||
|
{comment.locked ? (
|
||||||
|
<img src="assets/closed.gif" alt="Closed" title="Closed"
|
||||||
|
style={{marginTop: "-1px", marginRight: "2px",
|
||||||
|
imageRendering: "pixelated",}} />
|
||||||
|
) : null}
|
||||||
|
</span>
|
||||||
<br key={`mob-br1-${comment.cid}`} />
|
<br key={`mob-br1-${comment.cid}`} />
|
||||||
{comment.title ? (
|
{comment.title ? (
|
||||||
comment.title.length > 30 ?
|
comment.title.length > 30 ?
|
||||||
|
|||||||
@@ -2722,21 +2722,6 @@
|
|||||||
uuid "8.3.2"
|
uuid "8.3.2"
|
||||||
zustand "4.0.0"
|
zustand "4.0.0"
|
||||||
|
|
||||||
"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#efa802a1af8c75362e0d9a9afe1bc769f54e34cd":
|
|
||||||
version "0.0.1"
|
|
||||||
resolved "https://github.com/plebbit/plebbit-react-hooks.git#efa802a1af8c75362e0d9a9afe1bc769f54e34cd"
|
|
||||||
dependencies:
|
|
||||||
"@plebbit/plebbit-js" "https://github.com/plebbit/plebbit-js.git#77a05093408982086c02afea24e1d1923e1ae8a8"
|
|
||||||
"@plebbit/plebbit-logger" "https://github.com/plebbit/plebbit-logger.git"
|
|
||||||
assert "2.0.0"
|
|
||||||
ethers "5.6.9"
|
|
||||||
localforage "1.10.0"
|
|
||||||
lodash.isequal "4.5.0"
|
|
||||||
memoizee "0.4.15"
|
|
||||||
quick-lru "5.1.1"
|
|
||||||
uuid "8.3.2"
|
|
||||||
zustand "4.0.0"
|
|
||||||
|
|
||||||
"@pmmmwh/react-refresh-webpack-plugin@^0.5.3":
|
"@pmmmwh/react-refresh-webpack-plugin@^0.5.3":
|
||||||
version "0.5.10"
|
version "0.5.10"
|
||||||
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"
|
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"
|
||||||
|
|||||||
Reference in New Issue
Block a user