import "./ProfilePage.css"; import { useEffect, useMemo, useState } from "react"; import { useSelector } from "react-redux"; import { useNavigate, useParams } from "react-router-dom"; import { formatShort } from "Number"; import { Tab, TabElement } from "Element/Tabs"; import Link from "Icons/Link"; import Qr from "Icons/Qr"; import Zap from "Icons/Zap"; import Envelope from "Icons/Envelope"; import { useUserProfile } from "Feed/ProfileFeed"; import useZapsFeed from "Feed/ZapsFeed"; import { default as ZapElement, parseZap } from "Element/Zap"; import FollowButton from "Element/FollowButton"; import { extractLnAddress, parseId, hexToBech32 } from "Util"; import Avatar from "Element/Avatar"; import LogoutButton from "Element/LogoutButton"; import Timeline from "Element/Timeline"; import Text from 'Element/Text' import LNURLTip from "Element/LNURLTip"; import Nip05 from "Element/Nip05"; import Copy from "Element/Copy"; import ProfilePreview from "Element/ProfilePreview"; import ProfileImage from "Element/ProfileImage"; import FollowersList from "Element/FollowersList"; import BlockList from "Element/BlockList"; import MutedList from "Element/MutedList"; import FollowsList from "Element/FollowsList"; import IconButton from "Element/IconButton"; import { RootState } from "State/Store"; import { HexKey } from "Nostr"; import FollowsYou from "Element/FollowsYou" import QrCode from "Element/QrCode"; import Modal from "Element/Modal"; import { ProxyImg } from "Element/ProxyImg" const ProfileTab = { Notes: { text: "Notes", value: 0 }, Reactions: { text: "Reactions", value: 1 }, Followers: { text: "Followers", value: 2 }, Follows: { text: "Follows", value: 3 }, Zaps: { text: "Zaps", value: 4 }, Muted: { text: "Muted", value: 5 }, Blocked: { text: "Blocked", value: 6 }, } export default function ProfilePage() { const params = useParams(); const navigate = useNavigate(); const id = useMemo(() => parseId(params.id!), [params]); const user = useUserProfile(id); const loggedOut = useSelector(s => s.login.loggedOut); const loginPubKey = useSelector(s => s.login.publicKey); const follows = useSelector(s => s.login.follows); const isMe = loginPubKey === id; const [showLnQr, setShowLnQr] = useState(false); const [tab, setTab] = useState(ProfileTab.Notes); const [showProfileQr, setShowProfileQr] = useState(false); const aboutText = user?.about || '' const about = Text({ content: aboutText, tags: [], users: new Map(), creator: "" }) const lnurl = extractLnAddress(user?.lud16 || user?.lud06 || ""); const website_url = (user?.website && !user.website.startsWith("http")) ? "https://" + user.website : user?.website || ""; const zapFeed = useZapsFeed(id) const zaps = useMemo(() => { const profileZaps = zapFeed.store.notes.map(parseZap).filter(z => z.valid && z.p === id && !z.e && z.zapper !== id) profileZaps.sort((a, b) => b.amount - a.amount) return profileZaps }, [zapFeed.store, id]) const zapsTotal = zaps.reduce((acc, z) => acc + z.amount, 0) useEffect(() => { setTab(ProfileTab.Notes); }, [params]); function username() { return (

{user?.display_name || user?.name || 'Nostrich'}

{user?.nip05 && } {links()}
) } function links() { return (
{user?.website && ( )} {lnurl && (
setShowLnQr(true)}> {lnurl}
)} setShowLnQr(false)} author={id} />
) } function bio() { return aboutText.length > 0 && ( <>
{about}
) } function tabContent() { switch (tab) { case ProfileTab.Notes: return ; case ProfileTab.Zaps: { return (

{formatShort(zapsTotal)} sats

{zaps.map(z => )}
) } case ProfileTab.Follows: { if (isMe) { return (

Following {follows.length}

{follows.map(a => )}
); } else { return ; } } case ProfileTab.Followers: { return } case ProfileTab.Muted: { return isMe ? : } case ProfileTab.Blocked: { return isMe ? : null } } } function avatar() { return (
) } function renderIcons() { return (
setShowProfileQr(true)}> {showProfileQr && ( setShowProfileQr(false)}> )} {isMe ? ( <> ) : ( <> {lnurl && ( setShowLnQr(true)}> )} {!loggedOut && ( <> navigate(`/messages/${hexToBech32("npub", id)}`)}> )} )}
) } function userDetails() { return (
{username()}
{renderIcons()} {!isMe && }
{bio()}
) } function renderTab(v: Tab) { return } const w = window.document.querySelector(".page")?.clientWidth; return ( <>
{user?.banner && }
{avatar()} {userDetails()}
{[ProfileTab.Notes, ProfileTab.Followers, ProfileTab.Follows, ProfileTab.Zaps, ProfileTab.Muted].map(renderTab)} {isMe && renderTab(ProfileTab.Blocked)}
{tabContent()} ) }