From e6ca368134e74eb77066d93b66a96c3eede57547 Mon Sep 17 00:00:00 2001 From: Kieran Date: Wed, 30 Apr 2025 11:14:02 +0100 Subject: [PATCH] feat: client tags --- .../src/Components/Event/EventComponent.css | 16 +------------- .../src/Components/Event/Note/ClientTag.tsx | 21 +++++++++++++++++++ .../src/Components/Event/Note/ReplyTag.tsx | 11 ++++++---- packages/app/src/index.css | 4 ++++ packages/app/src/lang.json | 4 ++++ packages/app/src/translations/en.json | 1 + packages/shared/src/utils.ts | 10 ++++----- packages/system/src/nostr-link.ts | 6 +++++- packages/system/src/user-state.ts | 20 +++++++++++------- yarn.lock | 1 - 10 files changed, 61 insertions(+), 33 deletions(-) create mode 100644 packages/app/src/Components/Event/Note/ClientTag.tsx diff --git a/packages/app/src/Components/Event/EventComponent.css b/packages/app/src/Components/Event/EventComponent.css index e977f763..09133170 100644 --- a/packages/app/src/Components/Event/EventComponent.css +++ b/packages/app/src/Components/Event/EventComponent.css @@ -1,16 +1,3 @@ -.note > .header .reply { - font-size: 13px; - color: var(--font-secondary-color); -} - -.note > .header .reply a { - color: var(--highlight); -} - -.note > .header .reply a:hover { - text-decoration-color: var(--highlight); -} - .note .header .info { font-size: var(--font-size); margin-left: 4px; @@ -57,8 +44,7 @@ margin-top: 16px; } -.note > .header img:hover, -.note > .header .name > .reply:hover { +.note > .header img:hover { cursor: pointer; } diff --git a/packages/app/src/Components/Event/Note/ClientTag.tsx b/packages/app/src/Components/Event/Note/ClientTag.tsx new file mode 100644 index 00000000..296dc953 --- /dev/null +++ b/packages/app/src/Components/Event/Note/ClientTag.tsx @@ -0,0 +1,21 @@ +import { NostrLink, TaggedNostrEvent } from "@snort/system"; +import { FormattedMessage } from "react-intl"; +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; + return ( + + {" "} + {tag[1]} : tag[1], + }} + /> + + ); +} diff --git a/packages/app/src/Components/Event/Note/ReplyTag.tsx b/packages/app/src/Components/Event/Note/ReplyTag.tsx index bf9bdd16..45832f22 100644 --- a/packages/app/src/Components/Event/Note/ReplyTag.tsx +++ b/packages/app/src/Components/Event/Note/ReplyTag.tsx @@ -9,11 +9,13 @@ import DisplayName from "@/Components/User/DisplayName"; import { ProfileLink } from "@/Components/User/ProfileLink"; import { hexToBech32 } from "@/Utils"; +import { ClientTag } from "./ClientTag"; + export default function ReplyTag({ ev }: { ev: TaggedNostrEvent }) { const { formatMessage } = useIntl(); const thread = EventExt.extractThread(ev); if (thread === undefined) { - return undefined; + return ; } const maxMentions = 2; @@ -33,7 +35,7 @@ export default function ReplyTag({ ev }: { ev: TaggedNostrEvent }) { name: u?.name ?? shortNpub, link: ( - {" "} + ), }); @@ -53,7 +55,7 @@ export default function ReplyTag({ ev }: { ev: TaggedNostrEvent }) { const others = mentions.length > maxMentions ? formatMessage(messages.Others, { n: othersLength }) : ""; const link = replyLink?.encode(CONFIG.eventLinkPrefix); return ( -
+ re:  {(mentions?.length ?? 0) > 0 ? ( <> @@ -62,6 +64,7 @@ export default function ReplyTag({ ev }: { ev: TaggedNostrEvent }) { ) : ( replyLink && {link?.substring(0, 12)} )} -
+ + ); } diff --git a/packages/app/src/index.css b/packages/app/src/index.css index d52e1f75..929c9118 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -179,6 +179,10 @@ a.ext { -webkit-text-stroke: 1px black; } +.text-highlight { + color: var(--highlight); +} + .br { border-radius: 16px; } diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index e21a266c..93041fac 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -773,6 +773,10 @@ "GspYR7": { "defaultMessage": "{n} Dislike" }, + "GtIxzZ": { + "defaultMessage": "via {client}", + "description": "via {client name} tag" + }, "Gxcr08": { "defaultMessage": "Broadcast Event" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 279aaedf..2132910e 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -256,6 +256,7 @@ "GpkNYn": "Torrent", "GqQeu/": "Invalid Lightning Address", "GspYR7": "{n} Dislike", + "GtIxzZ": "via {client}", "Gxcr08": "Broadcast Event", "H+vHiz": "Hex Key..", "H/oroO": "Dealing with Unknown Events", diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index cdac8d4d..858b7c1d 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -226,7 +226,7 @@ export function normalizeReaction(content: string) { } } -export class OfflineError extends Error { } +export class OfflineError extends Error {} export function throwIfOffline() { if (isOffline()) { @@ -243,8 +243,8 @@ export function isHex(s?: string) { // 48-57 = 0-9 // 65-90 = A-Z // 97-122 = a-z - return s.length % 2 == 0 && - [...s] - .map(v => v.charCodeAt(0)) - .every(v => (v >= 48 && v <= 57) || (v >= 65 && v <= 90) || v >= 97 || v <= 122); + return ( + s.length % 2 == 0 && + [...s].map(v => v.charCodeAt(0)).every(v => (v >= 48 && v <= 57) || (v >= 65 && v <= 90) || v >= 97 || v <= 122) + ); } diff --git a/packages/system/src/nostr-link.ts b/packages/system/src/nostr-link.ts index 955e884d..e4e22089 100644 --- a/packages/system/src/nostr-link.ts +++ b/packages/system/src/nostr-link.ts @@ -150,7 +150,11 @@ export class NostrLink implements ToNostrEventTag { const ifSetCheck = (a: T | undefined, b: T) => { return !Boolean(a) || a === b; }; - return (EventExt.isReplaceable(ev.kind) || ifSetCheck(this.id, ev.id)) && ifSetCheck(this.author, ev.pubkey) && ifSetCheck(this.kind, ev.kind); + return ( + (EventExt.isReplaceable(ev.kind) || ifSetCheck(this.id, ev.id)) && + ifSetCheck(this.author, ev.pubkey) && + ifSetCheck(this.kind, ev.kind) + ); } return false; diff --git a/packages/system/src/user-state.ts b/packages/system/src/user-state.ts index 3695bb1f..9463c3c1 100644 --- a/packages/system/src/user-state.ts +++ b/packages/system/src/user-state.ts @@ -74,13 +74,19 @@ export class UserState extends EventEmitter { this.#stateObj = stateObj; this.#standardLists = pubkey ? new Map() : undefined; - this.#profile = pubkey ? new JsonEventSync( - undefined, - new NostrLink(NostrPrefix.Event, pubkey, EventKind.SetMetadata, pubkey), - false, - ) : undefined; - this.#contacts = pubkey ? new DiffSyncTags(new NostrLink(NostrPrefix.Event, pubkey, EventKind.ContactList, pubkey), false) : undefined; - this.#relays = pubkey ? new DiffSyncTags(new NostrLink(NostrPrefix.Event, pubkey, EventKind.Relays, pubkey), false) : undefined; + this.#profile = pubkey + ? new JsonEventSync( + undefined, + new NostrLink(NostrPrefix.Event, pubkey, EventKind.SetMetadata, pubkey), + false, + ) + : undefined; + this.#contacts = pubkey + ? new DiffSyncTags(new NostrLink(NostrPrefix.Event, pubkey, EventKind.ContactList, pubkey), false) + : undefined; + this.#relays = pubkey + ? new DiffSyncTags(new NostrLink(NostrPrefix.Event, pubkey, EventKind.Relays, pubkey), false) + : undefined; if (options?.appdataId && options.initAppdata) { const link = new NostrLink(NostrPrefix.Address, options.appdataId, EventKind.AppData, pubkey); this.#appdata = new JsonEventSync(options.initAppdata, link, options.encryptAppdata ?? false); diff --git a/yarn.lock b/yarn.lock index c7a6298c..8a8d16b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13433,7 +13433,6 @@ __metadata: prettier: "npm:^3.0.3" typedoc: "npm:^0.25.7" typescript: "npm:^5.2.2" - vite-plugin-version-mark: "npm:^0.1.4" languageName: unknown linkType: soft