feat: qrcode
This commit is contained in:
@@ -30,7 +30,7 @@ export default function ShortTextNoteCard({
|
||||
}}
|
||||
>
|
||||
<Card
|
||||
className={`hover:bg-muted/50 text-left cursor-pointer ${size === 'normal' ? 'p-4' : 'p-2'}`}
|
||||
className={`hover:bg-muted/50 text-left cursor-pointer ${size === 'normal' ? 'p-4' : 'p-3'}`}
|
||||
>
|
||||
<Note
|
||||
size={size}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { embeddedNpubRenderer } from '@renderer/embedded/EmbeddedNpub'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
export default function ProfileAbout({ about }: { about?: string }) {
|
||||
export default function ProfileAbout({ about, className }: { about?: string; className?: string }) {
|
||||
const nodes = useMemo(() => {
|
||||
return about
|
||||
? embedded(about, [
|
||||
@@ -19,5 +19,5 @@ export default function ProfileAbout({ about }: { about?: string }) {
|
||||
: null
|
||||
}, [about])
|
||||
|
||||
return <>{nodes}</>
|
||||
return <div className={className}>{nodes}</div>
|
||||
}
|
||||
|
||||
27
src/renderer/src/pages/secondary/ProfilePage/PubkeyCopy.tsx
Normal file
27
src/renderer/src/pages/secondary/ProfilePage/PubkeyCopy.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { formatNpub } from '@renderer/lib/pubkey'
|
||||
import { Check, Copy } from 'lucide-react'
|
||||
import { nip19 } from 'nostr-tools'
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
export default function PubkeyCopy({ pubkey }: { pubkey: string }) {
|
||||
const npub = useMemo(() => (pubkey ? nip19.npubEncode(pubkey) : ''), [pubkey])
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const copyNpub = () => {
|
||||
if (!npub) return
|
||||
|
||||
navigator.clipboard.writeText(npub)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex gap-2 text-sm text-muted-foreground items-center bg-muted w-fit px-2 rounded-full hover:text-foreground cursor-pointer"
|
||||
onClick={() => copyNpub()}
|
||||
>
|
||||
<div>{formatNpub(npub, 24)}</div>
|
||||
{copied ? <Check size={14} /> : <Copy size={14} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@renderer/components/ui/popover'
|
||||
import { QrCode } from 'lucide-react'
|
||||
import { nip19 } from 'nostr-tools'
|
||||
import { useMemo } from 'react'
|
||||
import { QRCodeSVG } from 'qrcode.react'
|
||||
|
||||
export default function QrCodePopover({ pubkey }: { pubkey: string }) {
|
||||
const npub = useMemo(() => (pubkey ? nip19.npubEncode(pubkey) : ''), [pubkey])
|
||||
if (!npub) return null
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<div className="bg-muted rounded-full h-5 w-5 flex flex-col items-center justify-center text-muted-foreground hover:text-foreground">
|
||||
<QrCode size={14} />
|
||||
</div>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-fit h-fit">
|
||||
<QRCodeSVG value={`nostr:${npub}`} />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
@@ -9,33 +9,25 @@ import { useFetchFollowings, useFetchProfile } from '@renderer/hooks'
|
||||
import { useFetchRelayList } from '@renderer/hooks/useFetchRelayList'
|
||||
import SecondaryPageLayout from '@renderer/layouts/SecondaryPageLayout'
|
||||
import { toFollowingList } from '@renderer/lib/link'
|
||||
import { formatNpub, generateImageByPubkey } from '@renderer/lib/pubkey'
|
||||
import { generateImageByPubkey } from '@renderer/lib/pubkey'
|
||||
import { SecondaryPageLink } from '@renderer/PageManager'
|
||||
import { useNostr } from '@renderer/providers/NostrProvider'
|
||||
import { Copy } from 'lucide-react'
|
||||
import { nip19 } from 'nostr-tools'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import PubkeyCopy from './PubkeyCopy'
|
||||
import QrCodePopover from './QrCodePopover'
|
||||
|
||||
export default function ProfilePage({ pubkey }: { pubkey?: string }) {
|
||||
const { banner, username, nip05, about, avatar } = useFetchProfile(pubkey)
|
||||
const relayList = useFetchRelayList(pubkey)
|
||||
const [copied, setCopied] = useState(false)
|
||||
const { pubkey: accountPubkey } = useNostr()
|
||||
const { followings } = useFetchFollowings(pubkey)
|
||||
const isFollowingYou = useMemo(
|
||||
() => !!accountPubkey && accountPubkey !== pubkey && followings.includes(accountPubkey),
|
||||
[followings, pubkey]
|
||||
)
|
||||
const npub = useMemo(() => (pubkey ? nip19.npubEncode(pubkey) : undefined), [pubkey])
|
||||
const defaultImage = useMemo(() => (pubkey ? generateImageByPubkey(pubkey) : ''), [pubkey])
|
||||
|
||||
if (!pubkey || !npub) return null
|
||||
|
||||
const copyNpub = () => {
|
||||
navigator.clipboard.writeText(npub)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
}
|
||||
if (!pubkey) return null
|
||||
|
||||
return (
|
||||
<SecondaryPageLayout titlebarContent={username}>
|
||||
@@ -63,22 +55,11 @@ export default function ProfilePage({ pubkey }: { pubkey?: string }) {
|
||||
<div className="pt-2">
|
||||
<div className="text-xl font-semibold">{username}</div>
|
||||
{nip05 && <Nip05 nip05={nip05} pubkey={pubkey} />}
|
||||
<div
|
||||
className="mt-1 flex gap-2 text-sm text-muted-foreground items-center bg-muted w-fit px-2 rounded-full hover:text-foreground cursor-pointer"
|
||||
onClick={() => copyNpub()}
|
||||
>
|
||||
{copied ? (
|
||||
<div>copied!</div>
|
||||
) : (
|
||||
<>
|
||||
<div>{formatNpub(npub, 24)}</div>
|
||||
<Copy size={14} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-wrap break-words whitespace-pre-wrap mt-2">
|
||||
<ProfileAbout about={about} />
|
||||
<div className="flex gap-1 mt-1">
|
||||
<PubkeyCopy pubkey={pubkey} />
|
||||
<QrCodePopover pubkey={pubkey} />
|
||||
</div>
|
||||
<ProfileAbout about={about} className="text-wrap break-words whitespace-pre-wrap mt-2" />
|
||||
<SecondaryPageLink
|
||||
to={toFollowingList(pubkey)}
|
||||
className="mt-2 flex gap-1 hover:underline text-sm"
|
||||
|
||||
Reference in New Issue
Block a user