feat: add avatar borders with color gradients to partner nip05 providers #52

Merged
verbiricha merged 6 commits from nip05-styles into main 2023-01-13 17:47:16 +00:00
6 changed files with 96 additions and 31 deletions

View File

@ -7,13 +7,47 @@
.nip05 .nick {
color: var(--gray-light);
font-weight: bold;
margin-right: .2em;
}
.nip05 .domain {
color: var(--gray-superlight);
font-weight: bold;
}
.nip05 .text-gradient {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
v0l commented 2023-01-13 17:23:18 +00:00 (Migrated from github.com)
Review

Can you add the repeated styles to a common class?

Can you add the repeated styles to a common class?
verbiricha commented 2023-01-13 17:40:09 +00:00 (Migrated from github.com)
Review
[f1cd244](https://github.com/v0l/snort/pull/52/commits/f1cd244cb7aaaef72a512ea066a18491638d5f72)
background-color: var(--gray-superlight);
}
.nip05 .domain[data-domain="snort.social"] {
background-image: var(--snort-gradient);
}
.nip05 .domain[data-domain="nostrplebs.com"] {
background-image: var(--nostrplebs-gradient);
}
.nip05 .domain[data-domain="nostrpurple.com"] {
background-image: var(--nostrplebs-gradient);
}
.nip05 .domain[data-domain="nostr.fan"] {
background-image: var(--nostrplebs-gradient);
}
.nip05 .domain[data-domain="nostrich.zone"] {
background-image: var(--nostrplebs-gradient);
}
.nip05 .domain[data-domain="nostriches.net"] {
background-image: var(--nostrplebs-gradient);
}
.nip05 .badge {
margin-left: .2em;
margin-top: .1em;
margin: .1em .2em;
}

View File

@ -5,33 +5,41 @@ import { faCheck, faSpinner, faTriangleExclamation } from "@fortawesome/free-sol
import './Nip05.css'
const Nip05 = ({ nip05, pubkey }) => {
const [nip05pubkey, setNip05pubkey] = useState()
const [couldNotVerify, setCouldNotVerify] = useState(false)
const isVerified = nip05pubkey === pubkey
const [name, domain] = nip05.split('@')
const isDefaultUser = name === '_'
export function useIsVerified(nip05, pubkey) {
const [isVerified, setIsVerified] = useState(false)
const [couldNotVerify, setCouldNotVerify] = useState(false)
const [name, domain] = nip05 ? nip05.split('@') : []
useEffect(() => {
setCouldNotVerify(false)
fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)
.then((res) => res.json())
.then(({ names }) => {
if (names && names[name]) {
setNip05pubkey(names[name])
}
})
.catch((err) => {
setCouldNotVerify(true)
console.error("Couldn't verifiy nip05")
})
}, [nip05, name, domain])
useEffect(() => {
if (!nip05 || !pubkey) {
return
}
setCouldNotVerify(false)
setIsVerified(false)
fetch(`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(name)}`)
.then((res) => res.json())
.then(({ names }) => {
if (names && names[name]) {
setIsVerified(names[name] === pubkey)
}
})
.catch((err) => {
setCouldNotVerify(true)
console.error("Couldn't verifiy nip05")
})
}, [nip05, pubkey])
return { name, domain: domain?.toLowerCase(), isVerified, couldNotVerify }
}
const Nip05 = ({ name, domain, isVerified, couldNotVerify }) => {
const isDefaultUser = name === '_'
return (
<div className="flex nip05" onClick={(ev) => ev.stopPropagation()}>
{!isDefaultUser && <div className="nick">{name}</div>}
<div className="domain">
{!isDefaultUser && '@'}
<div className={`domain ${isVerified ? 'text-gradient' : ''}`} data-domain={isVerified ? domain : ''}>
{domain}
</div>
<span className="badge">

View File

@ -39,7 +39,7 @@ export default function NoteReaction(props) {
function tagLine() {
switch (ev.Kind) {
case EventKind.Reaction: return <small>Reacted with {mapReaction(ev.Content)}</small>;
case EventKind.Repost: return <small>Reposted</small>
case EventKind.Repost: return <small> Reposted</small>
}
}

View File

@ -10,16 +10,23 @@
--gray: #333;
--gray-secondary: #222;
--gray-tertiary: #444;
--highlight: #A9E000;
--highlight-light: #E8FF52;
--highlight: #CCFF00;
--highlight-dark: #709900;
--error: #FF6053;
--success: #2AD544;
--gray-gradient: linear-gradient(to bottom right, var(--gray-superlight), var(--gray), var(--gray-light));
--snort-gradient: linear-gradient(to bottom right, var(--highlight-light), var(--highlight), var(--highlight-dark));
--nostrplebs-gradient: linear-gradient(to bottom right, #ff3cac, #2b86c5);
}
@media (prefers-color-scheme: light) {
:root {
--font-color: #000;
--bg-color: #FFF;
--highlight-light: #FFC852;
--highlight: #FF9B00;
--highlight-dark: #944F05;
--modal-bg-color: rgba(240, 240, 240, 0.8);
--gray: #CCC;
--gray-secondary: #DDD;

View File

@ -23,10 +23,23 @@
}
.profile .avatar {
width: 256px;
border-radius: 50%;
height: 256px;
width: 256px;
background-image: var(--img-url), var(--gray-gradient);
border: 4px solid transparent;
background-origin: border-box;
background-clip: content-box, border-box;
background-size: cover;
border-radius: 100%;
box-sizing: border-box;
}
.profile .avatar[data-domain="snort.social"] {
background-image: var(--img-url), var(--snort-gradient);
}
.profile .avatar[data-domain="nostrplebs.com"] {
background-image: var(--img-url), var(--nostrplebs-gradient);
}
.profile .details {

View File

@ -13,7 +13,7 @@ import { extractLnAddress, parseId } from "../Util";
import Timeline from "../element/Timeline";
import { extractLinks, extractHashtags } from '../Text'
import LNURLTip from "../element/LNURLTip";
import Nip05 from "../element/Nip05";
import Nip05, { useIsVerified } from "../element/Nip05";
import Copy from "../element/Copy";
import ProfilePreview from "../element/ProfilePreview";
import FollowersList from "../element/FollowersList";
@ -37,6 +37,9 @@ export default function ProfilePage() {
const [showLnQr, setShowLnQr] = useState(false);
const [tab, setTab] = useState(ProfileTab.Notes);
const about = extractHashtags(extractLinks([user?.about]))
const { name, domain, isVerified, couldNotVerify } = useIsVerified(user?.nip05, user?.pubkey)
const avatarUrl = (user?.picture?.length ?? 0) === 0 ? Nostrich : user?.picture
const backgroundImage = `url(${avatarUrl})`
useEffect(() => {
setTab(ProfileTab.Notes);
@ -50,7 +53,7 @@ export default function ProfilePage() {
<div className="f-grow">
<h2>{user?.display_name || user?.name}</h2>
<Copy text={params.id} />
{user?.nip05 && <Nip05 nip05={user.nip05} pubkey={user.pubkey} />}
{user?.nip05 && <Nip05 name={name} domain={domain} isVerified={isVerified} couldNotVerify={couldNotVerify} />}
</div>
<div>
{isMe ? (
@ -106,7 +109,7 @@ export default function ProfilePage() {
<>
<div className="profile flex">
<div className="avatar-wrapper">
<div style={{ backgroundImage: `url(${(user?.picture?.length ?? 0) === 0 ? Nostrich : user?.picture})` }} className="avatar">
<div style={{ '--img-url': backgroundImage }} className="avatar" data-domain={isVerified ? domain : ''}>
</div>
</div>
<div className="f-grow details">