CONFIG.eventLinkPrefix
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Martti Malmi 2023-10-17 12:59:25 +03:00
parent ca18cf25e3
commit d9bd198e8d
23 changed files with 53 additions and 39 deletions

View File

@ -13,5 +13,6 @@
"subscriptions": true, "subscriptions": true,
"deck": true, "deck": true,
"zapPool": true "zapPool": true
} },
"eventLinkPrefix": "nevent"
} }

View File

@ -13,5 +13,6 @@
"subscriptions": false, "subscriptions": false,
"deck": true, "deck": true,
"zapPool": true "zapPool": true
} },
"eventLinkPrefix": "note"
} }

View File

@ -52,4 +52,5 @@ declare const CONFIG: {
deck: boolean; deck: boolean;
zapPool: boolean; zapPool: boolean;
}; };
eventLinkPrefix: NostrPrefix;
}; };

View File

@ -1,4 +1,4 @@
import { NostrPrefix, NostrEvent, NostrLink } from "@snort/system"; import { NostrEvent, NostrLink } from "@snort/system";
import useEventPublisher from "Hooks/useEventPublisher"; import useEventPublisher from "Hooks/useEventPublisher";
import Icon from "Icons/Icon"; import Icon from "Icons/Icon";
import Spinner from "Icons/Spinner"; import Spinner from "Icons/Spinner";
@ -36,7 +36,7 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
if (file) { if (file) {
const rx = await uploader.upload(file, file.name); const rx = await uploader.upload(file, file.name);
if (rx.header) { if (rx.header) {
const link = `nostr:${new NostrLink(NostrPrefix.Event, rx.header.id, rx.header.kind).encode()}`; const link = `nostr:${new NostrLink(CONFIG.eventLinkPrefix, rx.header.id, rx.header.kind).encode()}`;
setMsg(`${msg ? `${msg}\n` : ""}${link}`); setMsg(`${msg ? `${msg}\n` : ""}${link}`);
setOtherEvents([...otherEvents, rx.header]); setOtherEvents([...otherEvents, rx.header]);
} else if (rx.url) { } else if (rx.url) {

View File

@ -9,7 +9,10 @@ import { DeckContext } from "Pages/DeckLayout";
export default function Articles() { export default function Articles() {
const data = useArticles(); const data = useArticles();
const deck = useContext(DeckContext); const deck = useContext(DeckContext);
const related = useReactions("articles:reactions", data.data?.map(v => NostrLink.fromEvent(v)) ?? []); const related = useReactions(
"articles:reactions",
data.data?.map(v => NostrLink.fromEvent(v, CONFIG.eventLinkPrefix)) ?? [],
);
return ( return (
<> <>

View File

@ -12,7 +12,7 @@ export default function ZapstrEmbed({ ev }: { ev: NostrEvent }) {
const subject = ev.tags.find(a => a[0] === "subject"); const subject = ev.tags.find(a => a[0] === "subject");
const refPersons = ev.tags.filter(a => a[0] === "p"); const refPersons = ev.tags.filter(a => a[0] === "p");
const link = NostrLink.fromEvent(ev).encode(); const link = NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix).encode();
return ( return (
<> <>
<div className="flex zapstr mb10 card"> <div className="flex zapstr mb10 card">

View File

@ -168,7 +168,7 @@ export function NoteCreator() {
const rx = await uploader.upload(file, file.name); const rx = await uploader.upload(file, file.name);
note.update(v => { note.update(v => {
if (rx.header) { if (rx.header) {
const link = `nostr:${new NostrLink(NostrPrefix.Event, rx.header.id, rx.header.kind).encode()}`; const link = `nostr:${new NostrLink(CONFIG.eventLinkPrefix, rx.header.id, rx.header.kind).encode()}`;
v.note = `${v.note ? `${v.note}\n` : ""}${link}`; v.note = `${v.note ? `${v.note}\n` : ""}${link}`;
v.otherEvents = [...(v.otherEvents ?? []), rx.header]; v.otherEvents = [...(v.otherEvents ?? []), rx.header];
} else if (rx.url) { } else if (rx.url) {

View File

@ -123,7 +123,7 @@ export default function NoteFooter(props: NoteFooterProps) {
name: getDisplayName(author, ev.pubkey), name: getDisplayName(author, ev.pubkey),
zap: { zap: {
pubkey: ev.pubkey, pubkey: ev.pubkey,
event: NostrLink.fromEvent(ev), event: NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix),
}, },
} as ZapTarget, } as ZapTarget,
]; ];

View File

@ -151,7 +151,7 @@ export function NoteInner(props: NoteProps) {
return; return;
} }
const link = NostrLink.fromEvent(eTarget); const link = NostrLink.fromEvent(eTarget, CONFIG.eventLinkPrefix);
// detect cmd key and open in new tab // detect cmd key and open in new tab
if (e.metaKey) { if (e.metaKey) {
window.open(`/${link.encode()}`, "_blank"); window.open(`/${link.encode()}`, "_blank");

View File

@ -58,8 +58,13 @@ export default function Poll(props: PollProps) {
setVoting(opt); setVoting(opt);
const r = Object.keys(relays.item); const r = Object.keys(relays.item);
const zap = await publisher.zap(amount * 1000, props.ev.pubkey, r, NostrLink.fromEvent(props.ev), undefined, eb => const zap = await publisher.zap(
eb.tag(["poll_option", opt.toString()]), amount * 1000,
props.ev.pubkey,
r,
NostrLink.fromEvent(props.ev, CONFIG.eventLinkPrefix),
undefined,
eb => eb.tag(["poll_option", opt.toString()]),
); );
const lnurl = props.ev.tags.find(a => a[0] === "zap")?.[1] || pollerProfile?.lud16 || pollerProfile?.lud06; const lnurl = props.ev.tags.find(a => a[0] === "zap")?.[1] || pollerProfile?.lud16 || pollerProfile?.lud06;

View File

@ -283,7 +283,7 @@ export function Thread(props: { onBack?: () => void; disableSpotlight?: boolean
notes={replies} notes={replies}
related={getAllLinkReactions( related={getAllLinkReactions(
thread.reactions, thread.reactions,
replies.map(a => NostrLink.fromEvent(a)), replies.map(a => NostrLink.fromEvent(a, CONFIG.eventLinkPrefix)),
)} )}
chains={thread.chains} chains={thread.chains}
onNavigate={navigateThread} onNavigate={navigateThread}

View File

@ -12,7 +12,7 @@ import { FormattedNumber } from "react-intl";
export function ZapGoal({ ev }: { ev: NostrEvent }) { export function ZapGoal({ ev }: { ev: NostrEvent }) {
const [zap, setZap] = useState(false); const [zap, setZap] = useState(false);
const zaps = useZapsFeed(NostrLink.fromEvent(ev)); const zaps = useZapsFeed(NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix));
const target = Number(findTag(ev, "amount")); const target = Number(findTag(ev, "amount"));
const amount = zaps.reduce((acc, v) => (acc += v.amount * 1000), 0); const amount = zaps.reduce((acc, v) => (acc += v.amount * 1000), 0);
const progress = amount / target; const progress = amount / target;

View File

@ -44,7 +44,7 @@ export function LiveEvent({ ev }: { ev: NostrEvent }) {
} }
function cta() { function cta() {
const link = `https://zap.stream/${NostrLink.fromEvent(ev).encode()}`; const link = `https://zap.stream/${NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix).encode()}`;
switch (status) { switch (status) {
case "live": { case "live": {
return ( return (

View File

@ -36,7 +36,7 @@ export function ProfileLink({
const [username] = user.nip05.split("@"); const [username] = user.nip05.split("@");
return `/${username}`; return `/${username}`;
} }
return `/p/${new NostrLink( return `/${new NostrLink(
NostrPrefix.Profile, NostrPrefix.Profile,
pubkey, pubkey,
undefined, undefined,
@ -45,7 +45,7 @@ export function ProfileLink({
).encode()}`; ).encode()}`;
} }
if (link && (link.type === NostrPrefix.Profile || link.type === NostrPrefix.PublicKey)) { if (link && (link.type === NostrPrefix.Profile || link.type === NostrPrefix.PublicKey)) {
return `/p/${link.encode()}`; return `/${link.encode()}`;
} }
return "#"; return "#";
} }

View File

@ -39,7 +39,7 @@ export default function useThreadFeed(link: NostrLink) {
const links = store.data const links = store.data
.map(a => [ .map(a => [
NostrLink.fromEvent(a), NostrLink.fromEvent(a),
...a.tags.filter(a => a[0] === "e" || a[0] === "a").map(v => NostrLink.fromTag(v)), ...a.tags.filter(a => a[0] === "e" || a[0] === "a").map(v => NostrLink.fromTag(v, CONFIG.eventLinkPrefix)),
]) ])
.flat(); .flat();
setAllEvents(links); setAllEvents(links);
@ -51,12 +51,15 @@ export default function useThreadFeed(link: NostrLink) {
const rootOrReplyAsRoot = t?.root ?? t?.replyTo; const rootOrReplyAsRoot = t?.root ?? t?.replyTo;
if (rootOrReplyAsRoot) { if (rootOrReplyAsRoot) {
setRoot( setRoot(
NostrLink.fromTag([ NostrLink.fromTag(
rootOrReplyAsRoot.key, [
rootOrReplyAsRoot.value ?? "", rootOrReplyAsRoot.key,
rootOrReplyAsRoot.relay ?? "", rootOrReplyAsRoot.value ?? "",
...(rootOrReplyAsRoot.marker ?? []), rootOrReplyAsRoot.relay ?? "",
]), ...(rootOrReplyAsRoot.marker ?? []),
],
CONFIG.eventLinkPrefix,
),
); );
} }
} }

View File

@ -46,7 +46,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
); );
if (subject.relay) { if (subject.relay) {
f.relay(subject.relay); subject.relay.forEach(r => f.relay(r));
} }
switch (subject.type) { switch (subject.type) {
case "pubkey": { case "pubkey": {

View File

@ -185,7 +185,7 @@ function MediaCol({ setThread }: { setThread: (e: NostrLink) => void }) {
"--img": `url(${proxy(images[0].content)})`, "--img": `url(${proxy(images[0].content)})`,
} as CSSProperties } as CSSProperties
} }
onClick={() => setThread(NostrLink.fromEvent(e))}></div> onClick={() => setThread(NostrLink.fromEvent(e, CONFIG.eventLinkPrefix))}></div>
); );
}} }}
/> />

View File

@ -3,7 +3,7 @@ import "./MessagesPage.css";
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { NostrLink, NostrPrefix, TLVEntryType, UserMetadata, decodeTLV } from "@snort/system"; import { NostrLink, TLVEntryType, UserMetadata, decodeTLV } from "@snort/system";
import { useUserProfile, useUserSearch } from "@snort/system-react"; import { useUserProfile, useUserSearch } from "@snort/system-react";
import UnreadCount from "Element/UnreadCount"; import UnreadCount from "Element/UnreadCount";
@ -285,7 +285,7 @@ function NewChatWindow() {
} }
export function Nip28ChatProfile({ id, onClick }: { id: string; onClick: (id: string) => void }) { export function Nip28ChatProfile({ id, onClick }: { id: string; onClick: (id: string) => void }) {
const channel = useEventFeed(new NostrLink(NostrPrefix.Event, id, 40)); const channel = useEventFeed(new NostrLink(CONFIG.eventLinkPrefix, id, 40));
if (channel?.data) { if (channel?.data) {
const meta = JSON.parse(channel.data.content) as UserMetadata; const meta = JSON.parse(channel.data.content) as UserMetadata;
return ( return (

View File

@ -36,7 +36,7 @@ function notificationContext(ev: TaggedNostrEvent) {
} }
const eTag = findTag(ev, "e"); const eTag = findTag(ev, "e");
if (eTag) { if (eTag) {
return new NostrLink(NostrPrefix.Event, eTag); return new NostrLink(CONFIG.eventLinkPrefix, eTag);
} }
const pTag = ev.tags.filter(a => a[0] === "p").slice(-1)?.[0]; const pTag = ev.tags.filter(a => a[0] === "p").slice(-1)?.[0];
if (pTag) { if (pTag) {
@ -49,7 +49,7 @@ function notificationContext(ev: TaggedNostrEvent) {
const thread = EventExt.extractThread(ev); const thread = EventExt.extractThread(ev);
const tag = unwrap(thread?.replyTo ?? thread?.root ?? { value: ev.id, key: "e" }); const tag = unwrap(thread?.replyTo ?? thread?.root ?? { value: ev.id, key: "e" });
if (tag.key === "e") { if (tag.key === "e") {
return new NostrLink(NostrPrefix.Event, unwrap(tag.value)); return new NostrLink(CONFIG.eventLinkPrefix, unwrap(tag.value));
} else if (tag.key === "a") { } else if (tag.key === "a") {
const [kind, author, d] = unwrap(tag.value).split(":"); const [kind, author, d] = unwrap(tag.value).split(":");
return new NostrLink(NostrPrefix.Address, d, Number(kind), author); return new NostrLink(NostrPrefix.Address, d, Number(kind), author);

View File

@ -238,7 +238,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
<Note <Note
key={`pinned-${n.id}`} key={`pinned-${n.id}`}
data={n} data={n}
related={getLinkReactions(pinned, NostrLink.fromEvent(n))} related={getLinkReactions(pinned, NostrLink.fromEvent(n, CONFIG.eventLinkPrefix))}
options={{ showTime: false, showPinned: true, canUnpin: id === loginPubKey }} options={{ showTime: false, showPinned: true, canUnpin: id === loginPubKey }}
/> />
); );

View File

@ -148,7 +148,7 @@ export const NotesTab = () => {
noteOnClick={ noteOnClick={
deckContext deckContext
? ev => { ? ev => {
deckContext.setThread(NostrLink.fromEvent(ev)); deckContext.setThread(NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix));
} }
: undefined : undefined
} }

View File

@ -56,7 +56,7 @@ export class Zapper {
weight: Number(v[3] ?? 0), weight: Number(v[3] ?? 0),
zap: { zap: {
pubkey: v[1], pubkey: v[1],
event: NostrLink.fromEvent(ev), event: NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix),
}, },
} as ZapTarget; } as ZapTarget;
} else { } else {
@ -67,7 +67,7 @@ export class Zapper {
weight: 1, weight: 1,
zap: { zap: {
pubkey: ev.pubkey, pubkey: ev.pubkey,
event: NostrLink.fromEvent(ev), event: NostrLink.fromEvent(ev, CONFIG.eventLinkPrefix),
}, },
} as ZapTarget; } as ZapTarget;
} }

View File

@ -128,12 +128,12 @@ export class NostrLink {
} }
} }
static fromThreadTag(tag: Tag) { static fromThreadTag(tag: Tag, eventLinkPrefix = NostrPrefix.Event) {
const relay = tag.relay ? [tag.relay] : undefined; const relay = tag.relay ? [tag.relay] : undefined;
switch (tag.key) { switch (tag.key) {
case "e": { case "e": {
return new NostrLink(NostrPrefix.Event, unwrap(tag.value), undefined, undefined, relay); return new NostrLink(eventLinkPrefix, unwrap(tag.value), undefined, undefined, relay);
} }
case "p": { case "p": {
return new NostrLink(NostrPrefix.Profile, unwrap(tag.value), undefined, undefined, relay); return new NostrLink(NostrPrefix.Profile, unwrap(tag.value), undefined, undefined, relay);
@ -146,11 +146,11 @@ export class NostrLink {
throw new Error(`Unknown tag kind ${tag.key}`); throw new Error(`Unknown tag kind ${tag.key}`);
} }
static fromTag(tag: Array<string>) { static fromTag(tag: Array<string>, eventLinkPrefix = NostrPrefix.Event) {
const relays = tag.length > 2 ? [tag[2]] : undefined; const relays = tag.length > 2 ? [tag[2]] : undefined;
switch (tag[0]) { switch (tag[0]) {
case "e": { case "e": {
return new NostrLink(NostrPrefix.Event, tag[1], undefined, undefined, relays); return new NostrLink(eventLinkPrefix, tag[1], undefined, undefined, relays);
} }
case "p": { case "p": {
return new NostrLink(NostrPrefix.Profile, tag[1], undefined, undefined, relays); return new NostrLink(NostrPrefix.Profile, tag[1], undefined, undefined, relays);
@ -163,14 +163,14 @@ export class NostrLink {
throw new Error(`Unknown tag kind ${tag[0]}`); throw new Error(`Unknown tag kind ${tag[0]}`);
} }
static fromEvent(ev: TaggedNostrEvent | NostrEvent) { static fromEvent(ev: TaggedNostrEvent | NostrEvent, prefixHint = NostrPrefix.Event) {
const relays = "relays" in ev ? ev.relays : undefined; const relays = "relays" in ev ? ev.relays : undefined;
if (ev.kind >= 30_000 && ev.kind < 40_000) { if (ev.kind >= 30_000 && ev.kind < 40_000) {
const dTag = unwrap(findTag(ev, "d")); const dTag = unwrap(findTag(ev, "d"));
return new NostrLink(NostrPrefix.Address, dTag, ev.kind, ev.pubkey, relays); return new NostrLink(NostrPrefix.Address, dTag, ev.kind, ev.pubkey, relays);
} }
return new NostrLink(NostrPrefix.Event, ev.id, ev.kind, ev.pubkey, relays); return new NostrLink(prefixHint, ev.id, ev.kind, ev.pubkey, relays);
} }
} }