Compare commits
4 Commits
e6ca368134
...
18f60681bd
Author | SHA1 | Date | |
---|---|---|---|
18f60681bd
|
|||
3d778f7ec7
|
|||
992d7f19be
|
|||
1820e7426d
|
39
packages/app/src/Components/Event/Application.tsx
Normal file
39
packages/app/src/Components/Event/Application.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { mapEventToProfile, TaggedNostrEvent } from "@snort/system";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import KindName from "../kind-name";
|
||||
import Avatar from "../User/Avatar";
|
||||
import DisplayName from "../User/DisplayName";
|
||||
import ProfileImage from "../User/ProfileImage";
|
||||
|
||||
export function ApplicationHandler({ ev }: { ev: TaggedNostrEvent }) {
|
||||
const profile = mapEventToProfile(ev);
|
||||
const kinds = ev.tags
|
||||
.filter(a => a[0] === "k")
|
||||
.map(a => Number(a[1]))
|
||||
.sort((a, b) => a - b);
|
||||
return (
|
||||
<div className="p flex gap-2 flex-col">
|
||||
<div className="flex items-center gap-2 text-xl">
|
||||
<Avatar user={profile} pubkey={""} size={120} />
|
||||
<div className="flex flex-col gap-2">
|
||||
<DisplayName user={profile} pubkey={""} />
|
||||
<div className="text-sm flex items-center gap-2">
|
||||
<div className="text-gray-light">
|
||||
<FormattedMessage defaultMessage="Published by" />
|
||||
</div>
|
||||
<ProfileImage className="inline" pubkey={ev.pubkey} size={30} link="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FormattedMessage defaultMessage="Supported Kinds:" />
|
||||
<div className="flex flex-wrap">
|
||||
{kinds.map(a => (
|
||||
<div key={a} className="pill">
|
||||
<KindName kind={a} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -6,15 +6,15 @@ import { memo, ReactNode } from "react";
|
||||
import PubkeyList from "@/Components/Embed/PubkeyList";
|
||||
import ZapstrEmbed from "@/Components/Embed/ZapstrEmbed";
|
||||
import ErrorBoundary from "@/Components/ErrorBoundary";
|
||||
import { ApplicationHandler } from "@/Components/Event/Application";
|
||||
import { LongFormText } from "@/Components/Event/LongFormText";
|
||||
import { NostrFileElement } from "@/Components/Event/NostrFileHeader";
|
||||
import { Note } from "@/Components/Event/Note/Note";
|
||||
import NoteReaction from "@/Components/Event/NoteReaction";
|
||||
import { ZapGoal } from "@/Components/Event/ZapGoal";
|
||||
import { LiveEvent } from "@/Components/LiveStream/LiveEvent";
|
||||
import ProfilePreview from "@/Components/User/ProfilePreview";
|
||||
|
||||
import { LongFormText } from "./LongFormText";
|
||||
import { Note } from "./Note/Note";
|
||||
|
||||
export interface NotePropsOptions {
|
||||
isRoot?: boolean;
|
||||
showHeader?: boolean;
|
||||
@ -75,6 +75,10 @@ export default memo(function EventComponent(props: NoteProps) {
|
||||
case 9041: // Assuming 9041 is a valid EventKind
|
||||
content = <ZapGoal ev={ev} />;
|
||||
break;
|
||||
case EventKind.ApplicationHandler: {
|
||||
content = <ApplicationHandler ev={ev} />;
|
||||
break;
|
||||
}
|
||||
case EventKind.Photo:
|
||||
case EventKind.Video:
|
||||
case EventKind.ShortVideo: {
|
||||
|
@ -5,7 +5,7 @@ import { Link } from "react-router-dom";
|
||||
export function ClientTag({ ev }: { ev: TaggedNostrEvent }) {
|
||||
const tag = ev.tags.find(a => a[0] === "client");
|
||||
if (!tag) return;
|
||||
const link = tag[2] ? NostrLink.fromTag(["a", tag[2]]) : undefined;
|
||||
const link = tag[2] && tag[2].includes(":") ? NostrLink.tryFromTag(["a", tag[2]]) : undefined;
|
||||
return (
|
||||
<span className="text-xs text-gray-light">
|
||||
{" "}
|
||||
|
@ -1,5 +1,10 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
// Take the markdown kinds table and find-replace with following regex:
|
||||
// FIND: ^\|\s+`([`\d\-]+)`\s+\| ([\w \-\(\)\/]+)[\s]*\|.*$
|
||||
// REPLACE: case $1:\n\treturn <FormattedMessage defaultMessage="$2" />;
|
||||
|
||||
export default function KindName({ kind }: { kind: number }) {
|
||||
switch (kind) {
|
||||
case 0:
|
||||
@ -21,21 +26,37 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
case 8:
|
||||
return <FormattedMessage defaultMessage="Badge Award" />;
|
||||
case 9:
|
||||
return <FormattedMessage defaultMessage="Group Chat Message" />;
|
||||
return <FormattedMessage defaultMessage="Chat Message" />;
|
||||
case 10:
|
||||
return <FormattedMessage defaultMessage="Group Chat Threaded Reply" />;
|
||||
case 11:
|
||||
return <FormattedMessage defaultMessage="Group Thread" />;
|
||||
return <FormattedMessage defaultMessage="Thread" />;
|
||||
case 12:
|
||||
return <FormattedMessage defaultMessage="Group Thread Reply" />;
|
||||
case 13:
|
||||
return <FormattedMessage defaultMessage="Seal" />;
|
||||
case 14:
|
||||
return <FormattedMessage defaultMessage="Direct Message" />;
|
||||
case 15:
|
||||
return <FormattedMessage defaultMessage="File Message" />;
|
||||
case 16:
|
||||
return <FormattedMessage defaultMessage="Generic Repost" />;
|
||||
case 17:
|
||||
return <FormattedMessage defaultMessage="Reaction to a website" />;
|
||||
case 20:
|
||||
return <FormattedMessage defaultMessage="Picture" />;
|
||||
case 21:
|
||||
return <FormattedMessage defaultMessage="Video Event" />;
|
||||
case 22:
|
||||
return <FormattedMessage defaultMessage="Short-form Portrait Video Event" />;
|
||||
case 30:
|
||||
return <FormattedMessage defaultMessage="internal reference" />;
|
||||
case 31:
|
||||
return <FormattedMessage defaultMessage="external web reference" />;
|
||||
case 32:
|
||||
return <FormattedMessage defaultMessage="hardcopy reference" />;
|
||||
case 33:
|
||||
return <FormattedMessage defaultMessage="prompt reference" />;
|
||||
case 40:
|
||||
return <FormattedMessage defaultMessage="Channel Creation" />;
|
||||
case 41:
|
||||
@ -46,10 +67,14 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="Channel Hide Message" />;
|
||||
case 44:
|
||||
return <FormattedMessage defaultMessage="Channel Mute User" />;
|
||||
case 62:
|
||||
return <FormattedMessage defaultMessage="Request to Vanish" />;
|
||||
case 64:
|
||||
return <FormattedMessage defaultMessage="Chess (PGN)" />;
|
||||
case 818:
|
||||
return <FormattedMessage defaultMessage="Merge Requests" />;
|
||||
case 1018:
|
||||
return <FormattedMessage defaultMessage="Poll Response" />;
|
||||
case 1021:
|
||||
return <FormattedMessage defaultMessage="Bid" />;
|
||||
case 1022:
|
||||
@ -60,14 +85,20 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="Gift Wrap" />;
|
||||
case 1063:
|
||||
return <FormattedMessage defaultMessage="File Metadata" />;
|
||||
case 1068:
|
||||
return <FormattedMessage defaultMessage="Poll" />;
|
||||
case 1111:
|
||||
return <FormattedMessage defaultMessage="Comment" />;
|
||||
case 1311:
|
||||
return <FormattedMessage defaultMessage="Live Chat Message" />;
|
||||
case 1337:
|
||||
return <FormattedMessage defaultMessage="Code Snippet" />;
|
||||
case 1617:
|
||||
return <FormattedMessage defaultMessage="Patches" />;
|
||||
case 1621:
|
||||
return <FormattedMessage defaultMessage="Issues" />;
|
||||
case 1622:
|
||||
return <FormattedMessage defaultMessage="Replies" />;
|
||||
return <FormattedMessage defaultMessage="Git Replies (deprecated)" />;
|
||||
case 1971:
|
||||
return <FormattedMessage defaultMessage="Problem Tracker" />;
|
||||
case 1984:
|
||||
@ -88,8 +119,16 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="Community Post Approval" />;
|
||||
case 7000:
|
||||
return <FormattedMessage defaultMessage="Job Feedback" />;
|
||||
case 7374:
|
||||
return <FormattedMessage defaultMessage="Reserved Cashu Wallet Tokens" />;
|
||||
case 7375:
|
||||
return <FormattedMessage defaultMessage="Cashu Wallet Tokens" />;
|
||||
case 7376:
|
||||
return <FormattedMessage defaultMessage="Cashu Wallet History" />;
|
||||
case 9041:
|
||||
return <FormattedMessage defaultMessage="Zap Goal" />;
|
||||
case 9321:
|
||||
return <FormattedMessage defaultMessage="Nutzap" />;
|
||||
case 9467:
|
||||
return <FormattedMessage defaultMessage="Tidal login" />;
|
||||
case 9734:
|
||||
@ -116,8 +155,12 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="Search relays list" />;
|
||||
case 10009:
|
||||
return <FormattedMessage defaultMessage="User groups" />;
|
||||
case 10013:
|
||||
return <FormattedMessage defaultMessage="Private event relay list" />;
|
||||
case 10015:
|
||||
return <FormattedMessage defaultMessage="Interests list" />;
|
||||
case 10019:
|
||||
return <FormattedMessage defaultMessage="Nutzap Mint Recommendation" />;
|
||||
case 10030:
|
||||
return <FormattedMessage defaultMessage="User emoji list" />;
|
||||
case 10050:
|
||||
@ -126,8 +169,12 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="User server list" />;
|
||||
case 10096:
|
||||
return <FormattedMessage defaultMessage="File storage server list" />;
|
||||
case 10166:
|
||||
return <FormattedMessage defaultMessage="Relay Monitor Announcement" />;
|
||||
case 13194:
|
||||
return <FormattedMessage defaultMessage="Wallet Info" />;
|
||||
case 17375:
|
||||
return <FormattedMessage defaultMessage="Cashu Wallet Event" />;
|
||||
case 21000:
|
||||
return <FormattedMessage defaultMessage="Lightning Pub RPC" />;
|
||||
case 22242:
|
||||
@ -177,17 +224,23 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
case 30030:
|
||||
return <FormattedMessage defaultMessage="Emoji sets" />;
|
||||
case 30040:
|
||||
return <FormattedMessage defaultMessage="Modular Article Header" />;
|
||||
return <FormattedMessage defaultMessage="Curated Publication Index" />;
|
||||
case 30041:
|
||||
return <FormattedMessage defaultMessage="Modular Article Content" />;
|
||||
return <FormattedMessage defaultMessage="Curated Publication Content" />;
|
||||
case 30063:
|
||||
return <FormattedMessage defaultMessage="Release artifact sets" />;
|
||||
case 30078:
|
||||
return <FormattedMessage defaultMessage="Application-specific Data" />;
|
||||
case 30166:
|
||||
return <FormattedMessage defaultMessage="Relay Discovery" />;
|
||||
case 30267:
|
||||
return <FormattedMessage defaultMessage="App curation sets" />;
|
||||
case 30311:
|
||||
return <FormattedMessage defaultMessage="Live Event" />;
|
||||
case 30315:
|
||||
return <FormattedMessage defaultMessage="User Statuses" />;
|
||||
case 30388:
|
||||
return <FormattedMessage defaultMessage="Slide Set" />;
|
||||
case 30402:
|
||||
return <FormattedMessage defaultMessage="Classified Listing" />;
|
||||
case 30403:
|
||||
@ -200,6 +253,10 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="Wiki article" />;
|
||||
case 30819:
|
||||
return <FormattedMessage defaultMessage="Redirects" />;
|
||||
case 31234:
|
||||
return <FormattedMessage defaultMessage="Draft Event" />;
|
||||
case 31388:
|
||||
return <FormattedMessage defaultMessage="Link Set" />;
|
||||
case 31890:
|
||||
return <FormattedMessage defaultMessage="Feed" />;
|
||||
case 31922:
|
||||
@ -214,13 +271,15 @@ export default function KindName({ kind }: { kind: number }) {
|
||||
return <FormattedMessage defaultMessage="Handler recommendation" />;
|
||||
case 31990:
|
||||
return <FormattedMessage defaultMessage="Handler information" />;
|
||||
case 34235:
|
||||
return <FormattedMessage defaultMessage="Video Event" />;
|
||||
case 34236:
|
||||
return <FormattedMessage defaultMessage="Short-form Portrait Video Event" />;
|
||||
case 34237:
|
||||
return <FormattedMessage defaultMessage="Video View Event" />;
|
||||
case 32267:
|
||||
return <FormattedMessage defaultMessage="Software Application" />;
|
||||
case 34550:
|
||||
return <FormattedMessage defaultMessage="Community Definition" />;
|
||||
case 38383:
|
||||
return <FormattedMessage defaultMessage="Peer-to-peer Order events" />;
|
||||
case 39701:
|
||||
return <FormattedMessage defaultMessage="Web bookmarks" />;
|
||||
default:
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,11 @@ export function Header() {
|
||||
</>
|
||||
);
|
||||
} else if (nostrLink) {
|
||||
if (nostrLink.type === NostrPrefix.Event || nostrLink.type === NostrPrefix.Note) {
|
||||
if (
|
||||
nostrLink.type === NostrPrefix.Event ||
|
||||
nostrLink.type === NostrPrefix.Note ||
|
||||
nostrLink.type === NostrPrefix.Address
|
||||
) {
|
||||
title = <NoteTitle link={nostrLink} />;
|
||||
} else if (nostrLink.type === NostrPrefix.PublicKey || nostrLink.type === NostrPrefix.Profile) {
|
||||
try {
|
||||
|
@ -270,6 +270,9 @@
|
||||
"4emo2p": {
|
||||
"defaultMessage": "Missing Relays"
|
||||
},
|
||||
"4oPRxH": {
|
||||
"defaultMessage": "Supported Kinds:"
|
||||
},
|
||||
"4rYCjn": {
|
||||
"defaultMessage": "Note to Self"
|
||||
},
|
||||
@ -1148,6 +1151,9 @@
|
||||
"QWhotP": {
|
||||
"defaultMessage": "Zap Pool only works if you use one of the supported wallet connections (WebLN, LNC, LNDHub or Nostr Wallet Connect)"
|
||||
},
|
||||
"QaGyuN": {
|
||||
"defaultMessage": "Zapstr Track"
|
||||
},
|
||||
"QpaLA3": {
|
||||
"defaultMessage": "Channel Message"
|
||||
},
|
||||
@ -1302,6 +1308,9 @@
|
||||
"ULXFfP": {
|
||||
"defaultMessage": "Receive"
|
||||
},
|
||||
"ULsJTk": {
|
||||
"defaultMessage": "Published by"
|
||||
},
|
||||
"UNjfWJ": {
|
||||
"defaultMessage": "Check all event signatures received from relays"
|
||||
},
|
||||
|
@ -89,6 +89,7 @@
|
||||
"4Vmpt4": "Nostr Plebs is one of the first NIP-05 providers in the space and offers a good collection of domains at reasonable prices",
|
||||
"4Z3t5i": "Use imgproxy to compress images",
|
||||
"4emo2p": "Missing Relays",
|
||||
"4oPRxH": "Supported Kinds:",
|
||||
"4rYCjn": "Note to Self",
|
||||
"4wgYpI": "Recommended Application Handlers",
|
||||
"5BVs2e": "zap",
|
||||
@ -380,6 +381,7 @@
|
||||
"QDFTjG": "{n} Relays",
|
||||
"QJfhKt": "The private key is like a password, but it cannot be reset. Guard it carefully and never show it to anyone. Once someone has your private key, they will have access to your account forever.",
|
||||
"QWhotP": "Zap Pool only works if you use one of the supported wallet connections (WebLN, LNC, LNDHub or Nostr Wallet Connect)",
|
||||
"QaGyuN": "Zapstr Track",
|
||||
"QpaLA3": "Channel Message",
|
||||
"Qxv0B2": "You currently have {number} sats in your zap pool.",
|
||||
"Qy6/Ft": "Private Direct Messages",
|
||||
@ -431,6 +433,7 @@
|
||||
"U30H69": "Community Definition",
|
||||
"UJTWqI": "Remove from my relays",
|
||||
"ULXFfP": "Receive",
|
||||
"ULsJTk": "Published by",
|
||||
"UNjfWJ": "Check all event signatures received from relays",
|
||||
"UT7Nkj": "New Chat",
|
||||
"UUPFlt": "Users must accept the content warning to show the content of your note.",
|
||||
|
@ -55,6 +55,7 @@ const enum EventKind {
|
||||
LiveEvent = 30311, // NIP-102
|
||||
UserStatus = 30315, // NIP-38
|
||||
ZapstrTrack = 31337,
|
||||
ApplicationHandler = 31_990,
|
||||
SimpleChatMetadata = 39_000, // NIP-29
|
||||
ZapRequest = 9734, // NIP 57
|
||||
ZapReceipt = 9735, // NIP 57
|
||||
|
@ -235,16 +235,30 @@ export class NostrLink implements ToNostrEventTag {
|
||||
}
|
||||
case "A": {
|
||||
const [kind, author, dTag] = tag[1].split(":");
|
||||
if (!isHex(author)) {
|
||||
throw new Error(`Invalid author in A tag: ${tag[1]}`);
|
||||
}
|
||||
return new NostrLink(NostrPrefix.Address, dTag, Number(kind), author, relays, "root");
|
||||
}
|
||||
case "a": {
|
||||
const [kind, author, dTag] = tag[1].split(":");
|
||||
if (!isHex(author)) {
|
||||
throw new Error(`Invalid author in a tag: ${tag[1]}`);
|
||||
}
|
||||
return new NostrLink(NostrPrefix.Address, dTag, Number(kind), author, relays, tag[3]);
|
||||
}
|
||||
}
|
||||
throw new Error("Unknown tag!");
|
||||
}
|
||||
|
||||
static tryFromTag(tag: Array<string>, author?: string, kind?: number) {
|
||||
try {
|
||||
return NostrLink.fromTag(tag, author, kind);
|
||||
} catch (e) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
static fromTags(tags: ReadonlyArray<Array<string>>) {
|
||||
return removeUndefined(
|
||||
tags.map(a => {
|
||||
|
Reference in New Issue
Block a user