diff --git a/package.json b/package.json index 3b661da1..ebe49ab3 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@babel/plugin-transform-react-jsx": "7.21.0", "@capacitor/android": "3.6.0", "@capacitor/core": "3.6.0", - "@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#5c5521672fac68ab00c83b96614445f7ccfd5b04", + "@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#e741b0dad5bba65cf1f0896053f25cd91ed55cf1", "@testing-library/dom": "9.0.1", "@testing-library/jest-dom": "5.14.1", "@testing-library/react": "14.0.0", diff --git a/src/components/BoardStats.jsx b/src/components/BoardStats.jsx new file mode 100644 index 00000000..5f1adc98 --- /dev/null +++ b/src/components/BoardStats.jsx @@ -0,0 +1,38 @@ +import React from "react"; +import { useSubplebbitStats } from "@plebbit/plebbit-react-hooks/dist"; +import { BoardStatsContainer } from "./styled/BoardStats.styled"; +import { Break } from "./styled/views/Board.styled"; +import useGeneralStore from '../hooks/stores/useGeneralStore'; + + +const BoardStats = ({ subplebbitAddress }) => { + const { selectedStyle } = useGeneralStore(state => state); + const stats = useSubplebbitStats({subplebbitAddress}); + + return ( + + + + + + + + + + + + + + + + + + + + +
In the past hour: {stats.hourActiveUserCount} users, {stats.hourPostCount} posts.  Past day: {stats.dayActiveUserCount} users, {stats.dayPostCount} posts.
Past week: {stats.weekActiveUserCount} users, {stats.weekPostCount} posts.  Past month: {stats.monthActiveUserCount} users, {stats.monthPostCount} posts.
Since inception: {stats.allActiveUserCount} users browsed; {stats.allPostCount} posts made.
+
+ ); +}; + +export default BoardStats; \ No newline at end of file diff --git a/src/components/ForwardRefLink.jsx b/src/components/ForwardRefLink.jsx index 2e579e72..d66c9b51 100644 --- a/src/components/ForwardRefLink.jsx +++ b/src/components/ForwardRefLink.jsx @@ -3,7 +3,16 @@ import { Link } from "react-router-dom"; const ForwardRefLink = React.forwardRef((props, ref) => { const { children, setRefAndCid, onMouseOver, onMouseLeave, onClick, ...otherProps } = props; - + + const handleClick = (event) => { + if (otherProps.to === "#void") { + event.preventDefault(); + } + if (onClick) { + onClick(event); + } + }; + useEffect(() => { if (ref.current && typeof setRefAndCid === 'function') { setRefAndCid(ref.current); @@ -16,7 +25,7 @@ const ForwardRefLink = React.forwardRef((props, ref) => { {...otherProps} onMouseOver={onMouseOver} onMouseLeave={onMouseLeave} - onClick={onClick} + onClick={handleClick} > {children} diff --git a/src/components/Post.jsx b/src/components/Post.jsx index 4d94e10c..16d3d6bd 100644 --- a/src/components/Post.jsx +++ b/src/components/Post.jsx @@ -74,7 +74,7 @@ const Post = ({ content, postQuoteOnClick, postQuoteOnOver, postQuoteOnLeave, po const linkTarget = matchedText.startsWith('u/') ? "_blank" : "_self"; if (matchedText.startsWith('u/')) { - linkTo = () => {}; + linkTo = "#void"; } else if (matchedText.startsWith('p/') || matchedText.startsWith('p/')) { linkTo = `/${matchedText}`; } diff --git a/src/components/StateLabel.jsx b/src/components/StateLabel.jsx index 57e436f7..e3d55c36 100644 --- a/src/components/StateLabel.jsx +++ b/src/components/StateLabel.jsx @@ -6,11 +6,11 @@ const StateLabel = ({ commentIndex, className }) => { const comment = useAccountComment({commentIndex: commentIndex}); const stateString = useStateString(comment); - if (comment.updatedAt !== undefined) { + if (comment.updatedAt !== undefined || comment.index === undefined) { return null; } - if (comment.state === "failed") { + if (comment.state === "failed" || comment.state === "succeeded") { return null; } diff --git a/src/components/modals/SettingsModal.jsx b/src/components/modals/SettingsModal.jsx index 9aee5831..892aa118 100755 --- a/src/components/modals/SettingsModal.jsx +++ b/src/components/modals/SettingsModal.jsx @@ -1,7 +1,7 @@ -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useMemo, useRef } from "react"; import { Link, useLocation, useNavigate } from "react-router-dom"; import Modal from "react-modal"; -import { deleteAccount, deleteCaches, exportAccount, importAccount, setAccount, setActiveAccount, useAccount, useAccounts, useResolvedAuthorAddress } from "@plebbit/plebbit-react-hooks"; +import { deleteAccount, deleteCaches, importAccount, setAccount, setActiveAccount, useAccount, useAccounts, useResolvedAuthorAddress } from "@plebbit/plebbit-react-hooks"; import stringify from "json-stringify-pretty-compact" import { StyledModal } from "../styled/modals/SettingsModal.styled"; import useError from "../../hooks/useError"; @@ -13,16 +13,12 @@ const {version} = packageJson; const SettingsModal = ({ isOpen, closeModal }) => { - const { - selectedStyle, - } = useGeneralStore(state => state); - + const { selectedStyle } = useGeneralStore(state => state); const { anonymousMode, setAnonymousMode } = useAnonModeStore(); - const navigate = useNavigate(); const location = useLocation(); + const [expanded, setExpanded] = useState([]); - const [accountJson, setAccountJson] = useState(""); const [copyStatus, setCopyStatus] = useState(false); const [ensName, setEnsName] = useState(''); const [checkedENS, setCheckedENS] = useState(false); @@ -32,6 +28,9 @@ const SettingsModal = ({ isOpen, closeModal }) => { const account = useAccount(); const { accounts } = useAccounts(); + const accountJson = useMemo(() => stringify({...account}), [account]) + const [editedAccountJson, setEditedAccountJson] = useState(accountJson); + useEffect(() => { setEditedAccountJson(accountJson)}, [accountJson]) const gatewayRef = useRef(); const ipfsRef = useRef(); @@ -47,7 +46,6 @@ const SettingsModal = ({ isOpen, closeModal }) => { const author = {...account?.author, address: ensName}; const { resolvedAddress, state } = useResolvedAuthorAddress({ author, cache: false }); - const defaultGatewayUrls = isElectron ? undefined : [ 'https://ipfs.io', 'https://ipfsgateway.xyz', @@ -71,36 +69,6 @@ const SettingsModal = ({ isOpen, closeModal }) => { ]; - useEffect(() => { - if (account) { - const fetchAccountData = async () => { - const data = await exportAccount(); - try { - const parsedData = JSON.parse(data); - setAccountJson(stringify(parsedData)); - } catch (error) { - console.error("Failed to pretty-print the JSON:", error); - setAccountJson(data); - } - }; - fetchAccountData(); - } - }, [account]); - - - - const handleAccountJsonChange = (e) => { - try { - const parsedData = JSON.parse(e.target.value); - setAccountJson(stringify(parsedData)); - } catch (error) { - console.error("Failed to pretty-print the JSON:", error); - setAccountJson(e.target.value); - } - }; - - - useEffect(() => { if (checkedENS && resolvedAddress && state === 'succeeded') { setCheckedENS(false); @@ -130,7 +98,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { address: ensName, }, }); - setNewSuccessMessage("ENS Name Saved"); + setNewSuccessMessage("ENS name saved successfully."); } catch (error) { setNewErrorMessage(error.message); @@ -214,7 +182,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { try { await setAccount({ ...account, plebbitOptions }); - localStorage.setItem("successToast", "Settings Saved"); + localStorage.setItem("successToast", "Settings saved successfully."); window.location.reload(); } catch (error) { setNewErrorMessage(error.message); console.log(error); @@ -263,7 +231,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { chainProviders, }, }); - localStorage.setItem("successToast", "Blockchain Options Saved"); + localStorage.setItem("successToast", "Blockchain options saved successfully."); window.location.reload(); } catch (error) { setNewErrorMessage(error.message); console.log(error); @@ -289,7 +257,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { pubsubHttpClientsOptions: defaultPubsubHttpClientsOptions, }, }); - localStorage.setItem("successToast", "Settings Reset"); + localStorage.setItem("successToast", "Settings reset successfully."); window.location.reload(); } catch (error) { setNewErrorMessage(error.message); console.log(error); @@ -323,7 +291,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { chainProviders, }, }); - localStorage.setItem("successToast", "Blockchain Options Reset"); + localStorage.setItem("successToast", "Blockchain options reset successfully."); window.location.reload(); } catch (error) { setNewErrorMessage(error.message); console.log(error); @@ -367,7 +335,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { useEffect(() => { if (localStorage.getItem("cacheCleared") === "true") { - setNewSuccessMessage("Cache Cleared"); + setNewSuccessMessage("Cache cleared successfully."); localStorage.removeItem("cacheCleared"); } }, [setNewSuccessMessage]); @@ -375,9 +343,9 @@ const SettingsModal = ({ isOpen, closeModal }) => { const handleSaveAccount = async () => { try { - const parsedJson = JSON.parse(accountJson); + const parsedJson = JSON.parse(editedAccountJson); await setAccount(parsedJson); - setNewSuccessMessage("Account Data Saved Successfully"); + setNewSuccessMessage("Account data saved successfully."); } catch (error) { setNewErrorMessage("Error saving account data: " + error.message); console.error(error); @@ -385,25 +353,14 @@ const SettingsModal = ({ isOpen, closeModal }) => { }; - const handleResetAccount = async () => { - try { - const data = await exportAccount(); - setAccountJson(data); - } catch (error) { - setNewErrorMessage("Error resetting account data: " + error.message); - console.error(error); - } - }; - - const handleImportAccount = async () => { - const accountJson = importRef.current.value; + const data = importRef.current.value; try { - const parsedJson = JSON.parse(accountJson); - await importAccount(accountJson); + const parsedJson = JSON.parse(data); + await importAccount(data); setActiveAccount(parsedJson.account?.name); - setNewSuccessMessage("Account Imported"); + setNewSuccessMessage("Account imported successfully."); } catch (error) { setNewErrorMessage(error.message); console.log(error); @@ -415,7 +372,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { if (window.confirm("Are you sure you want to delete this account?")) { try { await deleteAccount(account?.name); - localStorage.setItem("successToast", "Account Deleted Successfully"); + localStorage.setItem("successToast", "Account deleted successfully."); window.location.reload(); } catch (error) { setNewErrorMessage("Error deleting account: " + error.message); @@ -440,7 +397,7 @@ const SettingsModal = ({ isOpen, closeModal }) => { ...account?.author, displayName: name, }}); - setNewSuccessMessage("Account Name Saved"); + setNewSuccessMessage("Account name saved successfully."); } catch (error) { setNewErrorMessage(error.message); console.log(error); } @@ -514,9 +471,9 @@ const SettingsModal = ({ isOpen, closeModal }) => {