Merge pull request #197 from plebbit/development

Development
This commit is contained in:
plebeius.eth
2023-08-18 17:13:17 +02:00
committed by GitHub
15 changed files with 180 additions and 45 deletions
+2 -2
View File
@@ -38,7 +38,7 @@
"react-scripts": "5.0.1",
"react-toastify": "9.1.1",
"react-tooltip": "5.10.0",
"react-virtuoso": "4.3.2",
"react-virtuoso": "4.5.0",
"rehype-sanitize": "5.0.1",
"remark-breaks": "3.0.2",
"styled-components": "5.3.9",
@@ -120,7 +120,7 @@
}
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "7.21.11",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@capacitor/cli": "3.6.0",
"concurrently": "8.0.1",
"cordova-res": "0.15.4",
+1 -1
View File
@@ -6,7 +6,7 @@ import ForwardRefLink from './ForwardRefLink';
const Post = ({ content, postQuoteOnClick, postQuoteOnOver, postQuoteOnLeave, postQuoteRef }) => {
const doubleNewlineContent = useMemo(() => content?.replaceAll(/\n(?!\n)/g, '\n\n'), [content]);
const doubleNewlineContent = content?.replace(/\n/g, ' \n\n');
const customSchema = useMemo(() => ({
...defaultSchema,
+5 -3
View File
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import Modal from "react-modal";
import { Link } from "react-router-dom";
import { usePublishCommentEdit } from "@plebbit/plebbit-react-hooks";
import { useComment, usePublishCommentEdit } from "@plebbit/plebbit-react-hooks";
import { StyledModal } from "../styled/modals/ModerationModal.styled";
import useGeneralStore from "../../hooks/stores/useGeneralStore";
import useError from "../../hooks/useError";
@@ -20,9 +20,11 @@ const ModerationModal = ({ isOpen, closeModal, deletePost }) => {
setResolveCaptchaPromise,
} = useGeneralStore(state => state);
const [pin, setPin] = useState(false);
const comment = useComment({commentCid: moderatingCommentCid});
const [pin, setPin] = useState(comment?.pinned);
const [deleteThread, setDeleteThread] = useState(deletePost);
const [close, setClose] = useState(false);
const [close, setClose] = useState(comment?.locked);
const [reason, setReason] = useState('');
const [triggerPublishCommentEdit, setTriggerPublishCommentEdit] = useState(false);
-1
View File
@@ -1,7 +1,6 @@
import React, { useState, useEffect, useRef } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import Modal from "react-modal";
import { confirmAlert } from "react-confirm-alert";
import { deleteAccount, deleteCaches, exportAccount, importAccount, setAccount, setActiveAccount, useAccount, useAccounts, useResolvedAuthorAddress } from "@plebbit/plebbit-react-hooks";
import { StyledModal } from "../styled/modals/SettingsModal.styled";
import useError from "../../hooks/useError";
+17 -4
View File
@@ -29,6 +29,7 @@ import SettingsModal from '../modals/SettingsModal';
import findShortParentCid from '../../utils/findShortParentCid';
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
import getDate from '../../utils/getDate';
import getFormattedTime from '../../utils/getFormattedTime';
import handleAddressClick from '../../utils/handleAddressClick';
import handleImageClick from '../../utils/handleImageClick';
import handleQuoteClick from '../../utils/handleQuoteClick';
@@ -851,7 +852,10 @@ const All = () => {
{<VerifiedAuthor commentCid={thread.cid}>{({ shortAuthorAddress }) => (shortAuthorAddress)}</VerifiedAuthor>}
</span>)
&nbsp;
<span key={`dt-${index}`} className="date-time" data-utc="data">{getDate(thread.timestamp)}</span>
<span key={`dt-${index}`}
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(thread.timestamp)}
data-tooltip-place="top">{getDate(thread.timestamp)}</span>
&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span key={`pl1-${index}`}>c/</span>
@@ -1179,7 +1183,10 @@ const All = () => {
</span>
</span>
&nbsp;
<span key={`dt-${index}`} className="date-time" data-utc="data">{getDate(reply.timestamp)}</span>
<span key={`dt-${index}`} className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply.timestamp)}
data-tooltip-place="top">{getDate(reply.timestamp)}</span>
&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span id="reply-button" style={{cursor: 'pointer'}} key={`pl1-${index}`} title="Link to this post">c/</span>
@@ -1778,7 +1785,10 @@ const All = () => {
tooltipPlace="top"
className="offline-mobile-sub" />
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(thread.timestamp)}
data-tooltip-place="top">
{getDate(thread.timestamp)}
&nbsp;
<span key={`mob-no-${index}`}>c/</span>
@@ -2016,7 +2026,10 @@ const All = () => {
tooltipPlace="top"
className="offline-mobile-sub-reply" />
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply.timestamp)}
data-tooltip-place="top">
{getDate(reply.timestamp)}&nbsp;
<span key={`mob-pl1-${index}`}>c/</span>
{reply.shortCid ? (
+46 -10
View File
@@ -30,6 +30,7 @@ import SettingsModal from '../modals/SettingsModal';
import findShortParentCid from '../../utils/findShortParentCid';
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
import getDate from '../../utils/getDate';
import getFormattedTime from '../../utils/getFormattedTime';
import handleAddressClick from '../../utils/handleAddressClick';
import handleImageClick from '../../utils/handleImageClick';
import handleQuoteClick from '../../utils/handleQuoteClick';
@@ -786,6 +787,9 @@ const Board = () => {
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
<option value="all">All</option>
<option value="subscriptions">Subscriptions</option>
{!defaultSubplebbits.some(subplebbit => subplebbit.address === selectedAddress) && (
<option value={selectedAddress}>{selectedAddress}</option>
)}
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
@@ -950,7 +954,10 @@ const Board = () => {
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
>## Board Admins</span>
&nbsp;
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
<span className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(subplebbit.createdAt)}
data-tooltip-place="top">{getDate(subplebbit.createdAt)}</span>
&nbsp;
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px",
imageRendering: "pixelated",}} />
@@ -1040,7 +1047,10 @@ const Board = () => {
style={{marginBottom: "-15px"}}>Rules</span>
&nbsp;
</span>
<span className="date-time-mobile post-number-mobile">{getDate(subplebbit.createdAt)}</span>
<span className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(subplebbit.createdAt)}
data-tooltip-place="top">{getDate(subplebbit.createdAt)}</span>
&nbsp;
</div>
<blockquote className="post-message-mobile">
@@ -1075,7 +1085,10 @@ const Board = () => {
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
>## Board Admins</span>
&nbsp;
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
<span className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(subplebbit.createdAt)}
data-tooltip-place="top">{getDate(subplebbit.createdAt)}</span>
&nbsp;
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px",
imageRendering: "pixelated",}} />
@@ -1165,7 +1178,10 @@ const Board = () => {
style={{marginBottom: "-15px"}}>Rules</span>
&nbsp;
</span>
<span className="date-time-mobile post-number-mobile">{getDate(subplebbit.createdAt)}</span>
<span className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(subplebbit.createdAt)}
data-tooltip-place="top">{getDate(subplebbit.createdAt)}</span>
&nbsp;
</div>
<blockquote className="post-message-mobile">
@@ -1222,7 +1238,10 @@ const Board = () => {
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
>## Board Admins</span>
&nbsp;
<span className="date-time">{getDate(subplebbit.createdAt)}</span>
<span className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(subplebbit.createdAt)}
data-tooltip-place="top">{getDate(subplebbit.createdAt)}</span>
&nbsp;
<img src="assets/sticky.gif" alt="Sticky" title="Sticky" style={{marginBottom: "-1px",
imageRendering: "pixelated",}} />
@@ -1310,7 +1329,10 @@ const Board = () => {
style={{marginBottom: "-15px"}}>Welcome to {subplebbit.title || subplebbit.address}</span>
&nbsp;
</span>
<span className="date-time-mobile post-number-mobile">{getDate(subplebbit.createdAt)}</span>
<span className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(subplebbit.createdAt)}
data-tooltip-place="top">{getDate(subplebbit.createdAt)}</span>
&nbsp;
</div>
{subplebbit.suggested?.avatarUrl ? (
@@ -1510,7 +1532,12 @@ const Board = () => {
<VerifiedAuthor commentCid={thread.cid}>{({ shortAuthorAddress }) => (shortAuthorAddress)}</VerifiedAuthor>
</span>)
&nbsp;
<span key={`dt-${index}`} className="date-time" data-utc="data">{getDate(thread.timestamp)}</span>
<span key={`dt-${index}`} className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(thread?.timestamp)}
data-tooltip-place="top">
{getDate(thread.timestamp)}
</span>
&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span key={`pl1-${index}`}>c/</span>
@@ -1853,7 +1880,10 @@ const Board = () => {
</span>
</span>
&nbsp;
<span key={`dt-${index}`} className="date-time" data-utc="data">{getDate(reply.timestamp)}</span>
<span key={`dt-${index}`} className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply.timestamp)}
data-tooltip-place="top">{getDate(reply.timestamp)}</span>
&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span key={`pl1-${index}`}>c/</span>
@@ -2426,7 +2456,10 @@ const Board = () => {
</span>)
: null}
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(thread.timestamp)}
data-tooltip-place="top">
{getDate(thread.timestamp)}
&nbsp;
<span key={`mob-no-${index}`}>c/</span>
@@ -2653,7 +2686,10 @@ const Board = () => {
</span>
<br key={`mob-br-${index}`} />
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply.timestamp)}
data-tooltip-place="top">
{getDate(reply.timestamp)}&nbsp;
<span key={`mob-pl1-${index}`}>c/</span>
{reply.shortCid ? (
+3
View File
@@ -1148,6 +1148,9 @@ const Catalog = () => {
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
<option value="all">All</option>
<option value="subscriptions">Subscriptions</option>
{!defaultSubplebbits.some(subplebbit => subplebbit.address === selectedAddress) && (
<option value={selectedAddress}>{selectedAddress}</option>
)}
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
+6 -4
View File
@@ -28,7 +28,6 @@ const Description = () => {
isSettingsOpen, setIsSettingsOpen,
selectedAddress, setSelectedAddress,
selectedStyle,
selectedThread,
setSelectedTitle,
} = useGeneralStore(state => state);
@@ -181,7 +180,7 @@ const Description = () => {
}>Create Board</span>
]
[
<Link to={`/p/${selectedAddress}/c/${selectedThread}/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
<Link to={`/p/${selectedAddress}/description/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
]
[
<Link to="/">Home</Link>
@@ -195,6 +194,9 @@ const Description = () => {
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
<option value="all">All</option>
<option value="subscriptions">Subscriptions</option>
{!defaultSubplebbits.some(subplebbit => subplebbit.address === selectedAddress) && (
<option value={selectedAddress}>{selectedAddress}</option>
)}
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
@@ -207,7 +209,7 @@ const Description = () => {
}>Create Board</span>
</div>
<div className="page-jump">
<Link to={`/p/${selectedAddress}/c/${selectedThread}/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
<Link to={`/p/${selectedAddress}/description/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
&nbsp;
<Link to="/" onClick={() => {handleStyleChange({target: {value: "Yotsuba"}}); window.scrollTo(0, 0);}}>Home</Link>
</div>
@@ -493,7 +495,7 @@ const Description = () => {
}>Create Board</span>
]
[
<Link to={`/p/${selectedAddress}/c/${selectedThread}/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
<Link to={`/p/${selectedAddress}/description/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
]
[
<Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}}
+8 -3
View File
@@ -108,8 +108,7 @@ const Home = () => {
</AboutTitle>
<AboutContent>
<div id="content">
<p>Plebchan is a serverless, adminless, decentralized 4chan alternative that uses the <a href="https://plebbit.com" target="_blank" rel="noreferrer">plebbit protocol</a>. Users do not need to register an account before participating in a community; anyone can post comments, share media links, and <button
style={{all: 'unset', cursor: 'pointer'}}
<p>Plebchan is a serverless, adminless, decentralized 4chan alternative that uses the <a href="https://plebbit.com" target="_blank" rel="noreferrer">plebbit protocol</a>. Users do not need to register an account before participating in a community; anyone can post comments, share media links, and <button style={{all: 'unset', cursor: 'pointer'}}
onClick={() =>{
window.electron && window.electron.isElectron ? (
setIsCreateBoardOpen(true)
@@ -119,7 +118,13 @@ const Home = () => {
)
)
}}
>create a board</button>. All the content is just text, and plebchan's speed depends on how many users are <a href="https://github.com/plebbit/whitepaper/blob/master/contribute.md" target="_blank" rel="noreferrer">seeding</a>. Search for any board address above, or feel free to click on a popular board below that interests you and jump right in! </p>
>create a board</button>. All the content is just text, and plebchan's speed depends on how many users are <button style={{all: 'unset', cursor: 'pointer'}}
onClick={() => {
alert(
'You can seed automatically simply by using the plebchan desktop app, which is a plebbit full node. Download it here:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, you can use plebbit-cli with the --seed flag:\nhttps://github.com/plebbit/plebbit-cli\n\n'
)
}}
>seeding</button>. Search for any board address above, or feel free to click on a popular board below that interests you and jump right in! </p>
<br />
<p>There are no global rules, each board is completely independent and its owner decides how/if it should be moderated.</p>
</div>
+3
View File
@@ -177,6 +177,9 @@ const Pending = () => {
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
<option value="all">All</option>
<option value="subscriptions">Subscriptions</option>
{!defaultSubplebbits.some(subplebbit => subplebbit.address === selectedAddress) && (
<option value={selectedAddress}>{selectedAddress}</option>
)}
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
+6 -4
View File
@@ -26,7 +26,6 @@ const Rules = () => {
isSettingsOpen, setIsSettingsOpen,
selectedAddress, setSelectedAddress,
selectedStyle,
selectedThread,
setSelectedTitle,
} = useGeneralStore(state => state);
@@ -187,7 +186,7 @@ const Rules = () => {
}>Create Board</span>
]
[
<Link to={`/p/${selectedAddress}/c/${selectedThread}/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
<Link to={`/p/${selectedAddress}/rules/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
]
[
<Link to="/">Home</Link>
@@ -201,6 +200,9 @@ const Rules = () => {
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
<option value="all">All</option>
<option value="subscriptions">Subscriptions</option>
{!defaultSubplebbits.some(subplebbit => subplebbit.address === selectedAddress) && (
<option value={selectedAddress}>{selectedAddress}</option>
)}
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
@@ -213,7 +215,7 @@ const Rules = () => {
}>Create Board</span>
</div>
<div className="page-jump">
<Link to={`/p/${selectedAddress}/c/${selectedThread}/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
<Link to={`/p/${selectedAddress}/rules/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
&nbsp;
<Link to="/" onClick={() => {handleStyleChange({target: {value: "Yotsuba"}}); window.scrollTo(0, 0);}}>Home</Link>
</div>
@@ -491,7 +493,7 @@ const Rules = () => {
}>Create Board</span>
]
[
<Link to={`/p/${selectedAddress}/c/${selectedThread}/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
<Link to={`/p/${selectedAddress}/rules/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
]
[
<Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}}
+17 -4
View File
@@ -30,6 +30,7 @@ import SettingsModal from '../modals/SettingsModal';
import findShortParentCid from '../../utils/findShortParentCid';
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
import getDate from '../../utils/getDate';
import getFormattedTime from '../../utils/getFormattedTime';
import handleAddressClick from '../../utils/handleAddressClick';
import handleImageClick from '../../utils/handleImageClick';
import handleQuoteClick from '../../utils/handleQuoteClick';
@@ -862,7 +863,10 @@ const Subscriptions = () => {
{<VerifiedAuthor commentCid={thread.cid}>{({ shortAuthorAddress }) => (shortAuthorAddress)}</VerifiedAuthor>}
</span>)
&nbsp;
<span key={`dt-${index}`} className="date-time" data-utc="data">{getDate(thread.timestamp)}</span>
<span key={`dt-${index}`} className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(thread.timestamp)}
data-tooltip-place="top">{getDate(thread.timestamp)}</span>
&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span key={`pl1-${index}`}>c/</span>
@@ -1190,7 +1194,10 @@ const Subscriptions = () => {
</span>
</span>
&nbsp;
<span key={`dt-${index}`} className="date-time" data-utc="data">{getDate(reply.timestamp)}</span>
<span key={`dt-${index}`} className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply.timestamp)}
data-tooltip-place="top">{getDate(reply.timestamp)}</span>
&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span id="reply-button" style={{cursor: 'pointer'}} key={`pl1-${index}`} title="Link to this post">c/</span>
@@ -1789,7 +1796,10 @@ const Subscriptions = () => {
tooltipPlace="top"
className="offline-mobile-sub" />
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(thread.timestamp)}
data-tooltip-place="top">
{getDate(thread.timestamp)}
&nbsp;
<span key={`mob-no-${index}`}>c/</span>
@@ -2027,7 +2037,10 @@ const Subscriptions = () => {
tooltipPlace="top"
className="offline-mobile-sub-reply" />
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply.timestamp)}
data-tooltip-place="top">
{getDate(reply.timestamp)}&nbsp;
<span key={`mob-pl1-${index}`}>c/</span>
{reply.shortCid ? (
+22 -4
View File
@@ -28,6 +28,7 @@ import SettingsModal from '../modals/SettingsModal';
import findShortParentCid from '../../utils/findShortParentCid';
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
import getDate from '../../utils/getDate';
import getFormattedTime from '../../utils/getFormattedTime';
import handleAddressClick from '../../utils/handleAddressClick';
import handleImageClick from '../../utils/handleImageClick';
import handleQuoteClick from '../../utils/handleQuoteClick';
@@ -688,6 +689,9 @@ const Thread = () => {
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
<option value="all">All</option>
<option value="subscriptions">Subscriptions</option>
{!defaultSubplebbits.some(subplebbit => subplebbit.address === selectedAddress) && (
<option value={selectedAddress}>{selectedAddress}</option>
)}
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
@@ -995,7 +999,12 @@ const Thread = () => {
</span>)
</span>
&nbsp;
<span className="date-time" data-utc="data">{getDate(comment?.timestamp)}</span>
<span className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(comment?.timestamp)}
data-tooltip-place="top">
{getDate(comment?.timestamp)}
</span>
&nbsp;
<span className="post-number post-number-desktop">
<span>c/</span>
@@ -1292,7 +1301,10 @@ const Thread = () => {
</span>
</span>
&nbsp;
<span key={`dt-${index}`} className="date-time">
<span key={`dt-${index}`} className="date-time"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply?.timestamp)}
data-tooltip-place="top">
{getDate(reply?.timestamp)}&nbsp;
<span key={`pn-${index}`} className="post-number post-number-desktop">
<span key={`pl1-${index}`}>c/</span>
@@ -1747,7 +1759,10 @@ const Thread = () => {
{comment.title}
</span>) : null}
</span>
<span key={`mob-dt-${comment.cid}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${comment.cid}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(comment?.timestamp)}
data-tooltip-place="top">
{getDate(comment?.timestamp)}
&nbsp;
<span key={`mob-no-${comment.cid}`}>c/</span>
@@ -1940,7 +1955,10 @@ const Thread = () => {
</span>
<br key={`mob-br-${index}`} />
</span>
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile">
<span key={`mob-dt-${index}`} className="date-time-mobile post-number-mobile"
data-tooltip-id="tooltip"
data-tooltip-content={getFormattedTime(reply?.timestamp)}
data-tooltip-place="top">
{getDate(reply?.timestamp)}&nbsp;
<span key={`mob-pl1-${index}`}>c/</span>
{reply.shortCid ? (
+39
View File
@@ -0,0 +1,39 @@
const pluralize = (unit, value) => {
return `${value} ${unit}${value > 1 ? 's' : ''}`;
};
const getFormattedTime = (timestamp) => {
try {
const currentTime = new Date().getTime();
const differenceInMilliseconds = currentTime - (timestamp * 1000);
const years = Math.floor(differenceInMilliseconds / (1000 * 60 * 60 * 24 * 365.25));
const months = Math.floor((differenceInMilliseconds % (1000 * 60 * 60 * 24 * 365.25)) / (1000 * 60 * 60 * 24 * 30));
const days = Math.floor((differenceInMilliseconds % (1000 * 60 * 60 * 24 * 30)) / (1000 * 60 * 60 * 24));
const hours = Math.floor((differenceInMilliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((differenceInMilliseconds % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((differenceInMilliseconds % (1000 * 60)) / 1000);
if (years > 0) {
return months > 0 ? `${pluralize('year', years)} and ${pluralize('month', months)} ago` : `${pluralize('year', years)} ago`;
} else if (months > 0) {
return `${pluralize('month', months)} and ${pluralize('day', days)} ago`;
} else if (days > 0) {
return `${pluralize('day', days)} and ${pluralize('hour', hours)} ago`;
} else if (hours > 0) {
return `${pluralize('hour', hours)} and ${pluralize('minute', minutes)} ago`;
} else if (minutes > 0) {
return `${pluralize('minute', minutes)} and ${pluralize('second', seconds)} ago`;
} else if (seconds > 30) {
return `${pluralize('second', seconds)} ago`;
} else {
return "just now";
}
}
catch (e) {
console.error("Error in getFormattedTime:", e);
return "[error]";
}
};
export default getFormattedTime;
+5 -5
View File
@@ -399,7 +399,7 @@
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
"@babel/plugin-proposal-private-property-in-object@7.21.11":
"@babel/plugin-proposal-private-property-in-object@^7.21.11":
version "7.21.11"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c"
integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==
@@ -12496,10 +12496,10 @@ react-tooltip@5.10.0:
"@floating-ui/dom" "1.2.3"
classnames "^2.3.2"
react-virtuoso@4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.3.2.tgz#91d4926c67f635cf7efc2dea29e7cd6de83575d1"
integrity sha512-n51V4fMk36VM6NapfaMbfs4w/IaVodp5asp+rtzlvz0yurG6uVrqA040ke43gpYtoOL6j6TxeXWo4b6GpO9N0A==
react-virtuoso@4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.5.0.tgz#0bc043b4e3e928e7891aa541dd7e55d5b46db8c8"
integrity sha512-OMP6XrzJMMos1vbJZC16RxGW7utAxUMP7i5PNPi6epBNVH7nz+CF/DlmecNBep5wyjLud51dQ5epjb2A0w9W/Q==
react@18.2.0:
version "18.2.0"