diff --git a/package.json b/package.json
index 36ba650f..3ea58a1b 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"react-dom": "^18.2.0",
"react-intersection-observer": "^9.4.1",
"react-markdown": "^8.0.4",
+ "react-query": "^3.39.2",
"react-redux": "^8.0.5",
"react-router-dom": "^6.5.0",
"react-scripts": "5.0.1",
diff --git a/src/element/Nip05.js b/src/element/Nip05.js
index 94f2bb95..3804c696 100644
--- a/src/element/Nip05.js
+++ b/src/element/Nip05.js
@@ -1,36 +1,41 @@
-import { useState, useEffect } from "react";
+import { useQuery } from "react-query";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faSpinner, faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
import './Nip05.css'
-export function useIsVerified(nip05, pubkey) {
- const [isVerified, setIsVerified] = useState(false)
- const [couldNotVerify, setCouldNotVerify] = useState(false)
- const [name, domain] = nip05 ? nip05.split('@') : []
-
- useEffect(() => {
- if (!nip05 || !pubkey) {
- return
- }
- setCouldNotVerify(false)
- setIsVerified(false)
-
- fetch(`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(name)}`)
+function fetchNip05Pubkey(name, domain) {
+ if (!name || !domain) {
+ return Promise.resolve(null)
+ }
+ return fetch(`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(name)}`)
.then((res) => res.json())
.then(({ names }) => {
if (names && names[name]) {
- setIsVerified(names[name] === pubkey)
+ return names[name]
}
})
- .catch((err) => {
- setCouldNotVerify(true)
- console.error("Couldn't verifiy nip05")
- })
- }, [nip05, pubkey])
+}
- return { name, domain: domain?.toLowerCase(), isVerified, couldNotVerify }
+const VERIFICATION_CACHE_TIME = 24 * 60 * 60 * 1000
+const VERIFICATION_STALE_TIMEOUT = 10 * 60 * 1000
+
+export function useIsVerified(nip05, pubkey) {
+ const [name, domain] = nip05 ? nip05.split('@') : []
+ const address = domain && `${name}@${domain.toLowerCase()}`
+ const { isLoading, isError, isSuccess, isIdle, data } = useQuery(
+ ['nip05', nip05],
+ () => fetchNip05Pubkey(name, domain),
+ {
+ retry: false,
+ cacheTime: VERIFICATION_CACHE_TIME,
+ staleTime: VERIFICATION_STALE_TIMEOUT
+ },
+ )
+ const isVerified = isSuccess && data === pubkey
+ const cantVerify = isSuccess && data !== pubkey
+ return { name, domain: domain?.toLowerCase(), isVerified, couldNotVerify: isError || cantVerify }
}
const Nip05 = ({ name, domain, isVerified, couldNotVerify }) => {
diff --git a/src/element/Textarea.tsx b/src/element/Textarea.tsx
index 2538058b..94738a9d 100644
--- a/src/element/Textarea.tsx
+++ b/src/element/Textarea.tsx
@@ -43,9 +43,10 @@ function normalizeUser({ pubkey, about, nip05, name, display_name }: User) {
return { pubkey, about, nip05, name, display_name }
}
-const Textarea = ({ onChange, ...rest }: any) => {
- // @ts-expect-error
- const { users } = useSelector(s => s.users)
+const Textarea = ({ users, onChange, ...rest }: any) => {
+ const normalizedUsers = Object.keys(users).reduce((acc, pk) => {
+ return {...acc, [pk]: normalizeUser(users[pk]) }
+ }, {})
const dbUsers = useLiveQuery(
() => db.users.toArray().then(usrs => {
return usrs.reduce((acc, usr) => {
@@ -53,8 +54,7 @@ const Textarea = ({ onChange, ...rest }: any) => {
}, {})
})
)
- const cachedUsers = dbUsers ? dbUsers : {}
- const allUsers: User[] = Object.values({...cachedUsers, ...users})
+ const allUsers: User[] = Object.values({...normalizedUsers, ...dbUsers})
return (
,
@@ -81,7 +87,9 @@ const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
-
+
+
+
);
diff --git a/src/pages/ProfilePage.js b/src/pages/ProfilePage.js
index 3d46a706..3e801bf5 100644
--- a/src/pages/ProfilePage.js
+++ b/src/pages/ProfilePage.js
@@ -59,7 +59,7 @@ export default function ProfilePage() {
const lnurl = extractLnAddress(user?.lud16 || user?.lud06 || "");
return (
-
{about}
+
{about}
{user?.website && (
diff --git a/yarn.lock b/yarn.lock
index 4a279293..eb869882 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1024,7 +1024,7 @@
"@babel/helper-validator-option" "^7.18.6"
"@babel/plugin-transform-typescript" "^7.18.6"
-"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
@@ -2868,6 +2868,11 @@ bfj@^7.0.2:
hoopy "^0.1.4"
tryer "^1.0.1"
+big-integer@^1.6.16:
+ version "1.6.51"
+ resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686"
+ integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==
+
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@@ -2943,6 +2948,20 @@ braces@^3.0.2, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
+broadcast-channel@^3.4.1:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937"
+ integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==
+ dependencies:
+ "@babel/runtime" "^7.7.2"
+ detect-node "^2.1.0"
+ js-sha3 "0.8.0"
+ microseconds "0.2.0"
+ nano-time "1.0.0"
+ oblivious-set "1.0.0"
+ rimraf "3.0.2"
+ unload "2.2.0"
+
browser-process-hrtime@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
@@ -3682,7 +3701,7 @@ detect-newline@^3.0.0:
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
-detect-node@^2.0.4:
+detect-node@^2.0.4, detect-node@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
@@ -5984,6 +6003,11 @@ js-sdsl@^4.1.4:
resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0"
integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==
+js-sha3@0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
+ integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -6298,6 +6322,14 @@ makeerror@1.0.12:
dependencies:
tmpl "1.0.5"
+match-sorter@^6.0.2:
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.1.tgz#98cc37fda756093424ddf3cbc62bfe9c75b92bda"
+ integrity sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+ remove-accents "0.4.2"
+
mdast-util-definitions@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz#2c1d684b28e53f84938bb06317944bee8efa79db"
@@ -6590,6 +6622,11 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2"
picomatch "^2.3.1"
+microseconds@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39"
+ integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==
+
mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
@@ -6678,6 +6715,13 @@ multicast-dns@^7.2.5:
dns-packet "^5.2.2"
thunky "^1.0.2"
+nano-time@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef"
+ integrity sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==
+ dependencies:
+ big-integer "^1.6.16"
+
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
@@ -6850,6 +6894,11 @@ object.values@^1.1.0, object.values@^1.1.6:
define-properties "^1.1.4"
es-abstract "^1.20.4"
+oblivious-set@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566"
+ integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==
+
obuf@^1.0.0, obuf@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
@@ -7903,6 +7952,15 @@ react-markdown@^8.0.4:
unist-util-visit "^4.0.0"
vfile "^5.0.0"
+react-query@^3.39.2:
+ version "3.39.2"
+ resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.39.2.tgz#9224140f0296f01e9664b78ed6e4f69a0cc9216f"
+ integrity sha512-F6hYDKyNgDQfQOuR1Rsp3VRzJnWHx6aRnnIZHMNGGgbL3SBgpZTDg8MQwmxOgpCAoqZJA+JSNCydF1xGJqKOCA==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ broadcast-channel "^3.4.1"
+ match-sorter "^6.0.2"
+
react-redux@^8.0.5:
version "8.0.5"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd"
@@ -8150,6 +8208,11 @@ remark-rehype@^10.0.0:
mdast-util-to-hast "^12.1.0"
unified "^10.0.0"
+remove-accents@0.4.2:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5"
+ integrity sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==
+
renderkid@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a"
@@ -8242,7 +8305,7 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-rimraf@^3.0.0, rimraf@^3.0.2:
+rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
@@ -9226,6 +9289,14 @@ universalify@^2.0.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
+unload@2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7"
+ integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==
+ dependencies:
+ "@babel/runtime" "^7.6.2"
+ detect-node "^2.0.4"
+
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"