feat: nip-89

This commit is contained in:
2024-09-12 22:15:54 +01:00
parent c74af0159c
commit ca4170be4f
15 changed files with 149 additions and 53 deletions

View File

@ -24,6 +24,7 @@ import { NoteProps } from "../EventComponent";
import HiddenNote from "../HiddenNote";
import Poll from "../Poll";
import NoteFooter from "./NoteFooter/NoteFooter";
import NoteAppHandler from "./NoteAppHandler";
const defaultOptions = {
showHeader: true,
@ -169,22 +170,9 @@ function Reaction({ ev }: { ev: TaggedNostrEvent }) {
}
function handleNonTextNote(ev: TaggedNostrEvent) {
const alt = findTag(ev, "alt");
if (alt) {
return (
<div className="note-quote">
<Text id={ev.id} content={alt} tags={[]} creator={ev.pubkey} />
</div>
);
} else if (ev.kind === EventKind.Reaction) {
if (ev.kind === EventKind.Reaction) {
return <Reaction ev={ev} />;
} else {
return (
<div className="card">
<CollapsedSection title={<FormattedMessage {...messages.UnknownEventKind} values={{ kind: ev.kind }} />}>
<pre className="text-xs">{JSON.stringify(ev, undefined, " ")}</pre>
</CollapsedSection>
</div>
);
return <NoteAppHandler ev={ev} />;
}
}

View File

@ -0,0 +1,44 @@
import { mapEventToProfile, NostrLink, TaggedNostrEvent } from "@snort/system";
import { FormattedMessage } from "react-intl";
import Icon from "@/Components/Icons/Icon";
import Avatar from "@/Components/User/Avatar";
import DisplayName from "@/Components/User/DisplayName";
import useAppHandler from "@/Hooks/useAppHandler";
export default function NoteAppHandler({ ev }: { ev: TaggedNostrEvent }) {
const handlers = useAppHandler(ev.kind);
const link = NostrLink.fromEvent(ev);
const profiles = handlers.apps
.map(a => ({ profile: mapEventToProfile(a), event: a }))
.filter(a => a.profile)
.slice(0, 5);
return (
<div className="card flex flex-col gap-2">
<small>
<FormattedMessage defaultMessage="Sorry, we dont understand this event kind, please try one of the following apps instead!" />
</small>
{profiles.map(a => (
<div className="flex justify-between items-center" key={a.event.id}>
<div className="flex items-center gap-2">
<Avatar size={40} pubkey={a.event.pubkey} user={a.profile} />
<div>
<DisplayName pubkey={a.event.pubkey} user={a.profile} />
</div>
</div>
<Icon
name="link"
onClick={() => {
const webHandler = a.event.tags.find(a => a[0] === "web" && a[2] === "nevent")?.[1];
if (webHandler) {
window.open(webHandler.replace("<bech32>", link.encode()), "_blank");
}
}}
/>
</div>
))}
</div>
);
}

View File

@ -12,9 +12,9 @@ interface DisplayNameProps {
user?: UserMetadata | undefined;
}
const DisplayName = ({ pubkey }: DisplayNameProps) => {
const profile = useUserProfile(pubkey);
const [name, isPlaceHolder] = useMemo(() => getDisplayNameOrPlaceHolder(profile, pubkey), [profile, pubkey]);
const DisplayName = ({ pubkey, user }: DisplayNameProps) => {
const profile = useUserProfile(user ? undefined : pubkey);
const [name, isPlaceHolder] = useMemo(() => getDisplayNameOrPlaceHolder(profile ?? user, pubkey), [profile, pubkey]);
return <span className={classNames({ placeholder: isPlaceHolder })}>{name}</span>;
};