add user DB and cache nip-05 verifications #65
@ -36,16 +36,20 @@ export function useIsVerified(nip05, pubkey) {
|
|||||||
)
|
)
|
||||||
const isVerified = isSuccess && data === pubkey
|
const isVerified = isSuccess && data === pubkey
|
||||||
const cantVerify = isSuccess && data !== pubkey
|
const cantVerify = isSuccess && data !== pubkey
|
||||||
return { name, domain: domain?.toLowerCase(), isVerified, couldNotVerify: isError || cantVerify }
|
return { isVerified, couldNotVerify: isError || cantVerify }
|
||||||
}
|
}
|
||||||
|
|
||||||
const Nip05 = ({ name, domain, isVerified, couldNotVerify }) => {
|
const Nip05 = ({ nip05, pubkey, defaultUsername = '' }) => {
|
||||||
|
const [name, domain] = nip05 ? nip05.split('@') : []
|
||||||
const isDefaultUser = name === '_'
|
const isDefaultUser = name === '_'
|
||||||
|
const { isVerified, couldNotVerify } = useIsVerified(nip05, pubkey)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex nip05" onClick={(ev) => ev.stopPropagation()}>
|
<div className="flex nip05" onClick={(ev) => ev.stopPropagation()}>
|
||||||
{!isDefaultUser && <div className="nick">{name}</div>}
|
<div className="nick">
|
||||||
<div className={`domain ${isVerified ? 'text-gradient' : ''}`} data-domain={isVerified ? domain : ''}>
|
{isDefaultUser ? defaultUsername : name}
|
||||||
|
</div>
|
||||||
|
<div className={`domain text-gradient`} data-domain={domain.toLowerCase()}>
|
||||||
{domain}
|
{domain}
|
||||||
</div>
|
</div>
|
||||||
<span className="badge">
|
<span className="badge">
|
||||||
|
@ -9,6 +9,7 @@ import Text from "./Text";
|
|||||||
import { eventLink, hexToBech32 } from "../Util";
|
import { eventLink, hexToBech32 } from "../Util";
|
||||||
import NoteFooter from "./NoteFooter";
|
import NoteFooter from "./NoteFooter";
|
||||||
import NoteTime from "./NoteTime";
|
import NoteTime from "./NoteTime";
|
||||||
|
import Nip05 from "./Nip05";
|
||||||
|
|
||||||
export default function Note(props) {
|
export default function Note(props) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -18,3 +18,13 @@
|
|||||||
.pfp a:hover {
|
.pfp a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pfp .nip05 {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pfp .profile-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { Link, useNavigate } from "react-router-dom";
|
|||||||
import useProfile from "../feed/ProfileFeed";
|
import useProfile from "../feed/ProfileFeed";
|
||||||
import { hexToBech32, profileLink } from "../Util";
|
import { hexToBech32, profileLink } from "../Util";
|
||||||
import LazyImage from "./LazyImage";
|
import LazyImage from "./LazyImage";
|
||||||
|
import Nip05 from "./Nip05";
|
||||||
|
|
||||||
export default function ProfileImage({ pubkey, subHeader, showUsername = true, className, link }) {
|
export default function ProfileImage({ pubkey, subHeader, showUsername = true, className, link }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -26,7 +27,17 @@ export default function ProfileImage({ pubkey, subHeader, showUsername = true, c
|
|||||||
<div className={`pfp ${className}`}>
|
<div className={`pfp ${className}`}>
|
||||||
<LazyImage src={hasImage ? user.picture : Nostrich} onClick={() => navigate(link ?? profileLink(pubkey))} />
|
<LazyImage src={hasImage ? user.picture : Nostrich} onClick={() => navigate(link ?? profileLink(pubkey))} />
|
||||||
{showUsername && (<div className="f-grow">
|
{showUsername && (<div className="f-grow">
|
||||||
<Link key={pubkey} to={link ?? profileLink(pubkey)}>{name}</Link>
|
<div className="profile-name">
|
||||||
|
<Link key={pubkey} to={link ?? profileLink(pubkey)}>
|
||||||
|
{user?.nip05 ? (
|
||||||
|
<Nip05
|
||||||
|
nip05={user.nip05}
|
||||||
|
pubkey={user.pubkey}
|
||||||
|
defaultUsername={user.display_name || user.name}
|
||||||
|
/>
|
||||||
|
): name}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
{subHeader ? <>{subHeader}</> : null}
|
{subHeader ? <>{subHeader}</> : null}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -4,7 +4,7 @@ import { useLiveQuery } from "dexie-react-hooks";
|
|||||||
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import Nip05, { useIsVerified } from "./Nip05";
|
import Nip05 from "./Nip05";
|
||||||
import "@webscopeio/react-textarea-autocomplete/style.css";
|
import "@webscopeio/react-textarea-autocomplete/style.css";
|
||||||
import "./Textarea.css";
|
import "./Textarea.css";
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@ -25,7 +25,6 @@ function searchUsers(query: string, users: User[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }: User) => {
|
const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }: User) => {
|
||||||
const { isVerified, couldNotVerify, name, domain } = useIsVerified(nip05, pubkey)
|
|
||||||
return (
|
return (
|
||||||
<div key={pubkey} className="user-item">
|
<div key={pubkey} className="user-item">
|
||||||
<div className="user-picture">
|
<div className="user-picture">
|
||||||
@ -33,7 +32,7 @@ const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }: User) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="user-details">
|
<div className="user-details">
|
||||||
<strong>{display_name || rest.name}</strong>
|
<strong>{display_name || rest.name}</strong>
|
||||||
<Nip05 name={name} domain={domain} isVerified={isVerified} couldNotVerify={couldNotVerify} />
|
<Nip05 nip05={nip05} pubkey={pubkey} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@ import { extractLnAddress, parseId, hexToBech32 } from "../Util";
|
|||||||
import Timeline from "../element/Timeline";
|
import Timeline from "../element/Timeline";
|
||||||
import Text from '../element/Text'
|
import Text from '../element/Text'
|
||||||
import LNURLTip from "../element/LNURLTip";
|
import LNURLTip from "../element/LNURLTip";
|
||||||
import Nip05, { useIsVerified } from "../element/Nip05";
|
import Nip05 from "../element/Nip05";
|
||||||
import Copy from "../element/Copy";
|
import Copy from "../element/Copy";
|
||||||
import ProfilePreview from "../element/ProfilePreview";
|
import ProfilePreview from "../element/ProfilePreview";
|
||||||
import FollowersList from "../element/FollowersList";
|
import FollowersList from "../element/FollowersList";
|
||||||
@ -37,9 +37,9 @@ export default function ProfilePage() {
|
|||||||
const [showLnQr, setShowLnQr] = useState(false);
|
const [showLnQr, setShowLnQr] = useState(false);
|
||||||
const [tab, setTab] = useState(ProfileTab.Notes);
|
const [tab, setTab] = useState(ProfileTab.Notes);
|
||||||
const about = Text({ content: user?.about })
|
const about = Text({ content: user?.about })
|
||||||
const { name, domain, isVerified, couldNotVerify } = useIsVerified(user?.nip05, user?.pubkey)
|
|
||||||
const avatarUrl = (user?.picture?.length ?? 0) === 0 ? Nostrich : user?.picture
|
const avatarUrl = (user?.picture?.length ?? 0) === 0 ? Nostrich : user?.picture
|
||||||
const backgroundImage = `url(${avatarUrl})`
|
const backgroundImage = `url(${avatarUrl})`
|
||||||
|
const domain = user?.nip05 && user.nip05.split('@')[1]
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTab(ProfileTab.Notes);
|
setTab(ProfileTab.Notes);
|
||||||
@ -50,7 +50,7 @@ export default function ProfilePage() {
|
|||||||
<div className="name">
|
<div className="name">
|
||||||
<h2>{user?.display_name || user?.name || 'Nostrich'}</h2>
|
<h2>{user?.display_name || user?.name || 'Nostrich'}</h2>
|
||||||
<Copy text={params.id} />
|
<Copy text={params.id} />
|
||||||
{user?.nip05 && <Nip05 name={name} domain={domain} isVerified={isVerified} couldNotVerify={couldNotVerify} />}
|
{user?.nip05 && <Nip05 nip05={user.nip05} pubkey={user.pubkey} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ export default function ProfilePage() {
|
|||||||
function avatar() {
|
function avatar() {
|
||||||
return (
|
return (
|
||||||
<div className="avatar-wrapper">
|
<div className="avatar-wrapper">
|
||||||
<div style={{ '--img-url': backgroundImage }} className="avatar" data-domain={isVerified ? domain : ''}>
|
<div style={{ '--img-url': backgroundImage }} className="avatar" data-domain={domain?.toLowerCase()}>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user