mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
+2
-2
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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";
|
||||
|
||||
@@ -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>)
|
||||
|
||||
<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>
|
||||
|
||||
<span key={`pn-${index}`} className="post-number post-number-desktop">
|
||||
<span key={`pl1-${index}`}>c/</span>
|
||||
@@ -1179,7 +1183,10 @@ const All = () => {
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<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>
|
||||
|
||||
<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)}
|
||||
|
||||
<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)}
|
||||
<span key={`mob-pl1-${index}`}>c/</span>
|
||||
{reply.shortCid ? (
|
||||
|
||||
@@ -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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
</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>
|
||||
|
||||
</div>
|
||||
<blockquote className="post-message-mobile">
|
||||
@@ -1075,7 +1085,10 @@ const Board = () => {
|
||||
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||
>## Board Admins</span>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
</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>
|
||||
|
||||
</div>
|
||||
<blockquote className="post-message-mobile">
|
||||
@@ -1222,7 +1238,10 @@ const Board = () => {
|
||||
onClick={() => {setIsAdminListOpen(!isAdminListOpen)}}
|
||||
>## Board Admins</span>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
</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>
|
||||
|
||||
</div>
|
||||
{subplebbit.suggested?.avatarUrl ? (
|
||||
@@ -1510,7 +1532,12 @@ const Board = () => {
|
||||
<VerifiedAuthor commentCid={thread.cid}>{({ shortAuthorAddress }) => (shortAuthorAddress)}</VerifiedAuthor>
|
||||
</span>)
|
||||
|
||||
<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>
|
||||
|
||||
<span key={`pn-${index}`} className="post-number post-number-desktop">
|
||||
<span key={`pl1-${index}`}>c/</span>
|
||||
@@ -1853,7 +1880,10 @@ const Board = () => {
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<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>
|
||||
|
||||
<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)}
|
||||
|
||||
<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)}
|
||||
<span key={`mob-pl1-${index}`}>c/</span>
|
||||
{reply.shortCid ? (
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
<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"}}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
<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"}}
|
||||
|
||||
@@ -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>)
|
||||
|
||||
<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>
|
||||
|
||||
<span key={`pn-${index}`} className="post-number post-number-desktop">
|
||||
<span key={`pl1-${index}`}>c/</span>
|
||||
@@ -1190,7 +1194,10 @@ const Subscriptions = () => {
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<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>
|
||||
|
||||
<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)}
|
||||
|
||||
<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)}
|
||||
<span key={`mob-pl1-${index}`}>c/</span>
|
||||
{reply.shortCid ? (
|
||||
|
||||
@@ -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>
|
||||
|
||||
<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>
|
||||
|
||||
<span className="post-number post-number-desktop">
|
||||
<span>c/</span>
|
||||
@@ -1292,7 +1301,10 @@ const Thread = () => {
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<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)}
|
||||
<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)}
|
||||
|
||||
<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)}
|
||||
<span key={`mob-pl1-${index}`}>c/</span>
|
||||
{reply.shortCid ? (
|
||||
|
||||
@@ -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;
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user