implement changing account address to ENS name

This commit is contained in:
plebeius.eth
2023-07-29 21:40:03 +02:00
parent 628704de59
commit ae5b1612db
2 changed files with 145 additions and 32 deletions
+138 -23
View File
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom"; import { Link, useLocation, useNavigate } from "react-router-dom";
import Modal from "react-modal"; import Modal from "react-modal";
import { deleteCaches, exportAccount, importAccount, setAccount, setActiveAccount, useAccount, useAccounts } from "@plebbit/plebbit-react-hooks"; import { deleteCaches, exportAccount, importAccount, setAccount, setActiveAccount, useAccount, useAccounts, useResolvedAuthorAddress } from "@plebbit/plebbit-react-hooks";
import { StyledModal } from "../styled/modals/SettingsModal.styled"; import { StyledModal } from "../styled/modals/SettingsModal.styled";
import useError from "../../hooks/useError"; import useError from "../../hooks/useError";
import useSuccess from "../../hooks/useSuccess"; import useSuccess from "../../hooks/useSuccess";
@@ -22,6 +22,9 @@ const SettingsModal = ({ isOpen, closeModal }) => {
const location = useLocation(); const location = useLocation();
const [expanded, setExpanded] = useState([]); const [expanded, setExpanded] = useState([]);
const [accountJson, setAccountJson] = useState(null); const [accountJson, setAccountJson] = useState(null);
const [copyStatus, setCopyStatus] = useState(false);
const [ensName, setEnsName] = useState('');
const [checkedENS, setCheckedENS] = useState(false);
const [, setNewErrorMessage] = useError(); const [, setNewErrorMessage] = useError();
const [, setNewSuccessMessage] = useSuccess(); const [, setNewSuccessMessage] = useSuccess();
@@ -37,6 +40,52 @@ const SettingsModal = ({ isOpen, closeModal }) => {
const dataPathRef = useRef(); const dataPathRef = useRef();
const importRef = useRef(); const importRef = useRef();
const nameRef = useRef(); const nameRef = useRef();
const ensRef = useRef();
const author = {...account?.author, address: ensName};
const { resolvedAddress, state } = useResolvedAuthorAddress({ author, cache: false });
useEffect(() => {
if (checkedENS && resolvedAddress && state === 'succeeded') {
setCheckedENS(false);
}
}, [checkedENS, state, resolvedAddress]);
const handleENSChange = () => {
const newEnsName = ensRef.current.value;
setEnsName(newEnsName);
};
const handleENSCheck = () => {
const newEnsName = ensRef.current.value;
setEnsName(newEnsName);
setCheckedENS(true);
};
const handleENSSave = async () => {
if (resolvedAddress === account?.signer?.address) {
try {
await setAccount({
...account,
author: {
...account?.author,
address: ensName,
},
});
setNewSuccessMessage("ENS Name Saved");
} catch (error) {
setNewErrorMessage(error.message);
console.log(error);
}
} else if (resolvedAddress !== account?.signer?.address) {
setNewErrorMessage(`Failed resolving address, ${ensName}`);
}
};
const defaultGatewayUrls = [ const defaultGatewayUrls = [
'https://ipfs.io', 'https://ipfs.io',
@@ -60,6 +109,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
'https://polygon-rpc.com', 'https://polygon-rpc.com',
]; ];
const isValidURL = (url) => { const isValidURL = (url) => {
try { try {
new URL(url); new URL(url);
@@ -70,6 +120,32 @@ const SettingsModal = ({ isOpen, closeModal }) => {
}; };
const handleCopyAddress = async () => {
try {
await navigator.clipboard.writeText(account?.author.address);
setCopyStatus(true);
} catch (err) {
console.error('Failed to copy text: ', err);
}
};
useEffect(() => {
let copyStatusTimeoutId;
let checkedENSTimeoutId;
if (copyStatus) {
copyStatusTimeoutId = setTimeout(() => setCopyStatus(false), 3000);
}
if (checkedENS) {
checkedENSTimeoutId = setTimeout(() => setCheckedENS(false), 5000);
}
return () => {
clearTimeout(copyStatusTimeoutId);
clearTimeout(checkedENSTimeoutId);
};
}, [copyStatus, checkedENS]);
const handleSavePlebbitOptions = async () => { const handleSavePlebbitOptions = async () => {
let gatewayUrls = gatewayRef.current.value.split('\n').filter(url => url.trim()); let gatewayUrls = gatewayRef.current.value.split('\n').filter(url => url.trim());
let ipfsClientsOptions = ipfsRef.current.value.split('\n').filter(url => url.trim()); let ipfsClientsOptions = ipfsRef.current.value.split('\n').filter(url => url.trim());
@@ -151,7 +227,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
await setAccount({ await setAccount({
...account, ...account,
plebbitOptions: { plebbitOptions: {
...account.plebbitOptions, ...account?.plebbitOptions,
chainProviders, chainProviders,
}, },
}); });
@@ -211,7 +287,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
await setAccount({ await setAccount({
...account, ...account,
plebbitOptions: { plebbitOptions: {
...account.plebbitOptions, ...account?.plebbitOptions,
chainProviders, chainProviders,
}, },
}); });
@@ -297,9 +373,9 @@ const SettingsModal = ({ isOpen, closeModal }) => {
try { try {
await setAccount({ await setAccount({
...account, ...account,
name: name || account.name, name: name || account?.name,
author: { author: {
...account.author, ...account?.author,
displayName: name, displayName: name,
}}); }});
setNewSuccessMessage("Account Name Saved"); setNewSuccessMessage("Account Name Saved");
@@ -353,6 +429,11 @@ const SettingsModal = ({ isOpen, closeModal }) => {
<div className="plebbit-options-buttons" <div className="plebbit-options-buttons"
style={{ display: expanded.includes(1) ? 'block' : 'none' }} style={{ display: expanded.includes(1) ? 'block' : 'none' }}
> >
<button className="save-button"
onClick={handleExport}>Export</button>
<button className="reset-button"
onClick={handleImport}
>Import</button>
</div> </div>
</li> </li>
<ul className="settings-cat" style={{ display: expanded.includes(1) ? 'block' : 'none' }}> <ul className="settings-cat" style={{ display: expanded.includes(1) ? 'block' : 'none' }}>
@@ -366,7 +447,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
checked={anonymousMode} checked={anonymousMode}
onChange={() => {setAnonymousMode(!anonymousMode)}} onChange={() => {setAnonymousMode(!anonymousMode)}}
/> />
&nbsp;Anon mode &nbsp;Anon Mode
</label> </label>
</li> </li>
<li className="settings-tip anon-tip"> <li className="settings-tip anon-tip">
@@ -375,13 +456,6 @@ const SettingsModal = ({ isOpen, closeModal }) => {
<li className="settings-option disc"> <li className="settings-option disc">
Account Data Account Data
</li> </li>
<div className="plebbit-options-buttons">
<button className="save-button"
onClick={handleExport}>Export</button>
<button className="reset-button"
onClick={handleImport}
>Import</button>
</div>
<li className="settings-tip"> <li className="settings-tip">
To export, click "Export", then save your account data displayed below in a safe place. To import, paste your account data into the box below, then click "Import". To export, click "Export", then save your account data displayed below in a safe place. To import, paste your account data into the box below, then click "Import".
</li> </li>
@@ -392,7 +466,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
<textarea ref={importRef} /> <textarea ref={importRef} />
)} )}
</div> </div>
<li className="settings-option disc" style={{marginTop: '15px'}}> <li className="settings-option disc">
Account Address: u/{account?.author.shortAddress} Account Address: u/{account?.author.shortAddress}
</li> </li>
<li className="settings-tip"> <li className="settings-tip">
@@ -410,9 +484,49 @@ const SettingsModal = ({ isOpen, closeModal }) => {
</option> </option>
))} ))}
</select> </select>
{account?.author.address.endsWith(".eth") ? null : (
<button style={{marginLeft: '35px'}} className="save-button" id="save-name" onClick={handleCopyAddress}>
{copyStatus ? "Copied!" : "Copy Full Address"}
</button>
)}
</div> </div>
</li> </li>
<li className="settings-option disc" style={{marginTop: '15px'}}> <li className="settings-option disc">
Crypto Address
</li>
<li className="settings-tip">
{account?.author.address.endsWith(".eth") ? "Your account address is already an ENS name." : (
'Change your account address to an ENS name you own: in your ENS name page on ens.domains, click on "Records", "Edit Records", "Add record", add "plebbit-author-address" as record name, add your full address as value (copy it with the button above) and save.'
)}
</li>
<div className="settings-input">
<input
className="settings-input"
style={{marginLeft: '20px'}}
placeholder="address.eth"
ref={ensRef}
value={ensName}
onChange={handleENSChange}
disabled={checkedENS}
/>
<button className="save-button" id="save-name" onClick={handleENSSave}>
Save
</button>
<button className="save-button check-button" id="save-name" onClick={handleENSCheck}>
Check
</button>
</div>
{checkedENS && ensName === account?.signer?.address && (
<li className="settings-tip" style={{marginTop: '10px', color: 'green'}}>
{ensName} has been acquired by you correctly.
</li>
)}
{checkedENS && ensName !== account?.signer?.address && (
<li className="settings-tip" style={{marginTop: '10px', color: 'red'}}>
{ensName} has not been acquired by you yet.
</li>
)}
<li className="settings-option disc">
Account Name Account Name
</li> </li>
<li className="settings-tip"> <li className="settings-tip">
@@ -424,8 +538,9 @@ const SettingsModal = ({ isOpen, closeModal }) => {
type="text" ref={nameRef} defaultValue={account?.author.displayName} type="text" ref={nameRef} defaultValue={account?.author.displayName}
placeholder="Anonymous" placeholder="Anonymous"
/> />
<button className="save-button" id="save-name" <button className="save-button" id="save-name" onClick={handleDisplayName}>
onClick={handleDisplayName}>Save</button> Save
</button>
</div> </div>
</li> </li>
</ul> </ul>
@@ -447,7 +562,7 @@ const SettingsModal = ({ isOpen, closeModal }) => {
onClick={handleResetPlebbitOptions}>Reset</button> onClick={handleResetPlebbitOptions}>Reset</button>
</div> </div>
</li> </li>
<ul className="settings-cat" style={{ display: expanded.includes(2) ? 'block' : 'none' }}> <ul className="settings-cat" style={{ display: expanded.includes(2) ? 'block' : 'none', marginTop: '-10px' }}>
<li className="settings-option disc"> <li className="settings-option disc">
IPFS Gateway URLs IPFS Gateway URLs
</li> </li>
@@ -509,23 +624,23 @@ const SettingsModal = ({ isOpen, closeModal }) => {
<button className="save-button" onClick={handleResetChainProviders}>Reset</button> <button className="save-button" onClick={handleResetChainProviders}>Reset</button>
</div> </div>
</li> </li>
<ul className="settings-cat" style={{ display: expanded.includes(3) ? 'block' : 'none' }}> <ul className="settings-cat" style={{ display: expanded.includes(3) ? 'block' : 'none', marginTop: '-10px'}}>
<li className="settings-option disc">Ethereum RPC</li> <li className="settings-option disc">Ethereum RPC</li>
<li className="settings-tip">Needed for .eth addresses</li> <li className="settings-tip">Needed for .eth addresses.</li>
<div className="settings-input"> <div className="settings-input">
<textarea placeholder="Ethereum RPC URLs" <textarea placeholder="Ethereum RPC URLs"
defaultValue={account?.plebbitOptions?.chainProviders?.['eth']?.urls.join("\n")} defaultValue={account?.plebbitOptions?.chainProviders?.['eth']?.urls.join("\n")}
ref={ethereumRpcRef} ref={ethereumRpcRef}
/> />
</div> </div>
<li className="settings-option disc">Polygon RPC</li> {/* <li className="settings-option disc">Polygon RPC</li>
<li className="settings-tip">Needed for XPLEB NFTs</li> <li className="settings-tip">Needed for XPLEB NFTs.</li>
<div className="settings-input"> <div className="settings-input">
<textarea placeholder="Polygon RPC URLs" <textarea placeholder="Polygon RPC URLs"
defaultValue={account?.plebbitOptions?.chainProviders?.['matic']?.urls.join("\n")} defaultValue={account?.plebbitOptions?.chainProviders?.['matic']?.urls.join("\n")}
ref={polygonRpcRef} ref={polygonRpcRef}
/> />
</div> </div> */}
</ul> </ul>
</ul> </ul>
<div> <div>
@@ -114,6 +114,10 @@ export const StyledModal = styled(Modal)`
position: absolute; position: absolute;
} }
.check-button {
margin-left: 58px !important;
}
.cache-button { .cache-button {
margin: auto; margin: auto;
margin-bottom: 10px; margin-bottom: 10px;
@@ -122,9 +126,10 @@ export const StyledModal = styled(Modal)`
} }
.settings-option { .settings-option {
margin: 5px 0 5px 0; margin: 15px 0 5px 0 !important;
padding-left: 23px; padding-left: 23px;
display: inline-block; display: inline-block;
position: relative;
} }
.settings-tip { .settings-tip {
@@ -145,13 +150,6 @@ export const StyledModal = styled(Modal)`
margin-top: 6px; margin-top: 6px;
} }
.settings-option {
margin: 5px 0 5px 0;
padding-left: 23px;
display: inline-block;
position: relative;
}
.settings-input { .settings-input {
position: relative; position: relative;
padding-left: 23px; padding-left: 23px;
@@ -195,7 +193,7 @@ export const StyledModal = styled(Modal)`
} }
.anon-tip { .anon-tip {
margin-bottom: 10px; margin-bottom: 0px;
} }
.anon-tip::before { .anon-tip::before {