2024-01-12 15:02:36 +00:00
|
|
|
import { LNURL } from "@snort/shared";
|
|
|
|
import { CachedMetadata, encodeTLVEntries, NostrPrefix, TLVEntryType } from "@snort/system";
|
|
|
|
import React, { useMemo, useState } from "react";
|
2024-01-20 11:00:30 +00:00
|
|
|
import { FormattedMessage, useIntl } from "react-intl";
|
2024-01-12 15:02:36 +00:00
|
|
|
import { Link, useNavigate } from "react-router-dom";
|
|
|
|
|
|
|
|
import IconButton from "@/Components/Button/IconButton";
|
|
|
|
import Copy from "@/Components/Copy/Copy";
|
|
|
|
import Modal from "@/Components/Modal/Modal";
|
|
|
|
import QrCode from "@/Components/QrCode";
|
|
|
|
import { SpotlightMediaModal } from "@/Components/Spotlight/SpotlightMedia";
|
|
|
|
import Avatar from "@/Components/User/Avatar";
|
|
|
|
import FollowButton from "@/Components/User/FollowButton";
|
|
|
|
import ProfileImage from "@/Components/User/ProfileImage";
|
|
|
|
import ZapModal from "@/Components/ZapModal/ZapModal";
|
|
|
|
import { hexToBech32 } from "@/Utils";
|
2024-01-20 11:00:30 +00:00
|
|
|
import { LoginSessionType, LoginStore } from "@/Utils/Login";
|
2024-03-12 22:21:04 +00:00
|
|
|
import { ZapTarget } from "@/Utils/Zapper";
|
2024-01-12 15:02:36 +00:00
|
|
|
|
|
|
|
const AvatarSection = ({
|
|
|
|
user,
|
|
|
|
id,
|
|
|
|
loginPubKey,
|
|
|
|
readonly,
|
|
|
|
lnurl,
|
|
|
|
}: {
|
|
|
|
user?: CachedMetadata;
|
|
|
|
id?: string;
|
|
|
|
loginPubKey?: string;
|
|
|
|
lnurl?: LNURL;
|
|
|
|
readonly?: boolean;
|
|
|
|
}) => {
|
|
|
|
const [showProfileQr, setShowProfileQr] = useState<boolean>(false);
|
|
|
|
const [modalImage, setModalImage] = useState<string>("");
|
|
|
|
const [showLnQr, setShowLnQr] = useState<boolean>(false);
|
|
|
|
const profileId = useMemo(() => hexToBech32(CONFIG.profileLinkPrefix, id), [id]);
|
|
|
|
const navigate = useNavigate();
|
|
|
|
const isMe = loginPubKey === id;
|
2024-01-20 11:00:30 +00:00
|
|
|
const canWrite = !!loginPubKey && !readonly;
|
|
|
|
const intl = useIntl();
|
2024-01-12 15:02:36 +00:00
|
|
|
|
|
|
|
const renderButtons = () => {
|
|
|
|
if (!id) return null;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<IconButton onClick={() => setShowProfileQr(true)} icon={{ name: "qr", size: 16 }} />
|
|
|
|
{showProfileQr && (
|
|
|
|
<Modal id="profile-qr" className="qr-modal" onClose={() => setShowProfileQr(false)}>
|
|
|
|
<ProfileImage pubkey={id} />
|
|
|
|
<div className="flex flex-col items-center">
|
|
|
|
<QrCode data={`nostr:${profileId}`} className="m10" />
|
|
|
|
<Copy text={profileId} className="py-3" />
|
|
|
|
</div>
|
|
|
|
</Modal>
|
|
|
|
)}
|
|
|
|
{isMe ? (
|
|
|
|
<>
|
|
|
|
<Link className="md:hidden" to="/settings">
|
|
|
|
<button>
|
|
|
|
<FormattedMessage defaultMessage="Settings" id="D3idYv" />
|
|
|
|
</button>
|
|
|
|
</Link>
|
|
|
|
<Link className="hidden md:inline" to="/settings/profile">
|
|
|
|
<button>
|
|
|
|
<FormattedMessage defaultMessage="Edit" id="wEQDC6" />
|
|
|
|
</button>
|
|
|
|
</Link>
|
|
|
|
</>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
{lnurl && <IconButton onClick={() => setShowLnQr(true)} icon={{ name: "zap", size: 16 }} />}
|
2024-01-20 11:00:30 +00:00
|
|
|
{canWrite && (
|
2024-01-12 15:02:36 +00:00
|
|
|
<IconButton
|
|
|
|
onClick={() =>
|
|
|
|
navigate(
|
|
|
|
`/messages/${encodeTLVEntries("chat4" as NostrPrefix, {
|
|
|
|
type: TLVEntryType.Author,
|
|
|
|
length: 32,
|
|
|
|
value: id,
|
|
|
|
})}`,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
icon={{ name: "envelope", size: 16 }}
|
|
|
|
/>
|
|
|
|
)}
|
2024-01-20 11:00:30 +00:00
|
|
|
{!canWrite && !isMe && (
|
|
|
|
<IconButton
|
|
|
|
onClick={() => {
|
|
|
|
if (confirm(intl.formatMessage({ defaultMessage: "View as user?", id: "LBAnc7" }))) {
|
|
|
|
LoginStore.loginWithPubkey(id, LoginSessionType.PublicKey);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
icon={{ name: "openeye", size: 16, className: "translate-y-0.5" }}
|
|
|
|
/>
|
|
|
|
)}
|
2024-01-12 15:02:36 +00:00
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2024-03-12 22:21:04 +00:00
|
|
|
<div className="flex justify-between w-full">
|
2024-03-19 12:04:21 +00:00
|
|
|
<Avatar
|
|
|
|
pubkey={id ?? ""}
|
|
|
|
user={user}
|
|
|
|
onClick={() => setModalImage(user?.picture || "")}
|
|
|
|
className="pointer"
|
|
|
|
size={100}
|
|
|
|
/>
|
2024-01-12 15:02:36 +00:00
|
|
|
<div className="profile-actions">
|
|
|
|
{renderButtons()}
|
|
|
|
{!isMe && id && <FollowButton pubkey={id} />}
|
|
|
|
</div>
|
|
|
|
{modalImage && <SpotlightMediaModal onClose={() => setModalImage("")} media={[modalImage]} idx={0} />}
|
|
|
|
<ZapModal
|
|
|
|
targets={
|
|
|
|
lnurl?.lnurl && id
|
|
|
|
? [
|
2024-03-19 12:04:21 +00:00
|
|
|
{
|
|
|
|
type: "lnurl",
|
|
|
|
value: lnurl.lnurl,
|
|
|
|
weight: 1,
|
|
|
|
name: user?.display_name || user?.name,
|
|
|
|
zap: { pubkey: id, anon: false },
|
|
|
|
} as ZapTarget,
|
|
|
|
]
|
2024-01-12 15:02:36 +00:00
|
|
|
: undefined
|
|
|
|
}
|
|
|
|
show={showLnQr}
|
|
|
|
onClose={() => setShowLnQr(false)}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default AvatarSection;
|