From 085e12a699dd6ddbd8039668b32438b23cfd417e Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 30 Aug 2024 09:17:32 -0500 Subject: [PATCH] Display NIP-89 client tags on events --- .changeset/beige-falcons-shake.md | 5 +++ dockerfile | 1 + src/components/note/note-published-using.tsx | 13 ++++++++ src/components/note/timeline-note/index.tsx | 2 ++ src/const.ts | 9 +++++ src/providers/global/publish-provider.tsx | 11 ++++++ src/services/local-settings.ts | 7 ++-- src/views/settings/post/index.tsx | 25 ++++++++++++++ src/views/thread/components/thread-post.tsx | 35 +++++++++++--------- 9 files changed, 91 insertions(+), 17 deletions(-) create mode 100644 .changeset/beige-falcons-shake.md create mode 100644 src/components/note/note-published-using.tsx diff --git a/.changeset/beige-falcons-shake.md b/.changeset/beige-falcons-shake.md new file mode 100644 index 000000000..397840e74 --- /dev/null +++ b/.changeset/beige-falcons-shake.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +Display NIP-89 client tags on events diff --git a/dockerfile b/dockerfile index 87cc75385..c6220fdd2 100644 --- a/dockerfile +++ b/dockerfile @@ -13,6 +13,7 @@ COPY . . ENV VITE_COMMIT_HASH="" ENV VITE_APP_VERSION="custom" +ENV ENABLE_CLIENT_TAG="false" RUN yarn build FROM nginx:stable-alpine-slim AS main diff --git a/src/components/note/note-published-using.tsx b/src/components/note/note-published-using.tsx new file mode 100644 index 000000000..52af54374 --- /dev/null +++ b/src/components/note/note-published-using.tsx @@ -0,0 +1,13 @@ +import { Text } from "@chakra-ui/react"; +import { NostrEvent } from "nostr-tools"; + +export default function NotePublishedUsing({ event }: { event: NostrEvent }) { + const clientTag = event.tags.find((t) => t[0] === "client"); + if (!clientTag) return; + + return ( + + using {clientTag[1]} + + ); +} diff --git a/src/components/note/timeline-note/index.tsx b/src/components/note/timeline-note/index.tsx index 2388085f9..b66428560 100644 --- a/src/components/note/timeline-note/index.tsx +++ b/src/components/note/timeline-note/index.tsx @@ -47,6 +47,7 @@ import ZapBubbles from "./components/zap-bubbles"; import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref"; import relayHintService from "../../../services/event-relay-hint"; import localSettings from "../../../services/local-settings"; +import NotePublishedUsing from "../note-published-using"; export type TimelineNoteProps = Omit & { event: NostrEvent; @@ -108,6 +109,7 @@ export function TimelineNote({ + {showSignatureVerification && } {!hideDrawerButton && ( diff --git a/src/const.ts b/src/const.ts index 7025c4084..820dc35cb 100644 --- a/src/const.ts +++ b/src/const.ts @@ -1,3 +1,4 @@ +import { kinds } from "nostr-tools"; import { safeRelayUrl, safeRelayUrls } from "./helpers/relay"; export const DEFAULT_SEARCH_RELAYS = safeRelayUrls([ @@ -45,3 +46,11 @@ export const NOSTR_CONNECT_PERMISSIONS = [ "sign_event:6", "sign_event:7", ]; + +export const NEVER_ATTACH_CLIENT_TAG = [kinds.EncryptedDirectMessage]; +export const ENABLE_CLIENT_TAG = import.meta.env.VITE_ENABLE_CLIENT_TAG !== "false"; +export const NIP_89_CLIENT_TAG = [ + "client", + "noStrudel", + "31990:266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5:1686066542546", +]; diff --git a/src/providers/global/publish-provider.tsx b/src/providers/global/publish-provider.tsx index 262293804..16f677c83 100644 --- a/src/providers/global/publish-provider.tsx +++ b/src/providers/global/publish-provider.tsx @@ -13,6 +13,8 @@ import eventReactionsService from "../../services/event-reactions"; import { localRelay } from "../../services/local-relay"; import deleteEventService from "../../services/delete-events"; import userMailboxesService from "../../services/user-mailboxes"; +import localSettings from "../../services/local-settings"; +import { NEVER_ATTACH_CLIENT_TAG, NIP_89_CLIENT_TAG } from "../../const"; type PublishContextType = { log: PublishAction[]; @@ -78,7 +80,16 @@ export default function PublishProvider({ children }: PropsWithChildren) { let signed: NostrEvent; if (!Object.hasOwn(event, "sig")) { let draft: EventTemplate = event as EventTemplate; + + // add pubkey relay hints draft = userMailboxesService.addPubkeyRelayHints(draft); + + // add client tag + if (localSettings.addClientTag.value && !NEVER_ATTACH_CLIENT_TAG.includes(event.kind)) { + draft.tags = [...draft.tags.filter((t) => t[0] !== "client"), NIP_89_CLIENT_TAG]; + } + + // request signature signed = await requestSignature(draft); } else signed = event as NostrEvent; diff --git a/src/services/local-settings.ts b/src/services/local-settings.ts index 29d07791b..ce616148c 100644 --- a/src/services/local-settings.ts +++ b/src/services/local-settings.ts @@ -1,8 +1,7 @@ import { generateSecretKey } from "nostr-tools"; import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; -import { PersistentSubject } from "../classes/subject"; -import { DEFAULT_SIGNAL_RELAYS } from "../const"; +import { ENABLE_CLIENT_TAG, DEFAULT_SIGNAL_RELAYS } from "../const"; import { BooleanLocalStorageEntry, NullableNumberLocalStorageEntry, @@ -45,6 +44,9 @@ const webRtcRecentConnections = new LocalStorageEntry( (value) => value.join(","), ); +// posting +const addClientTag = new BooleanLocalStorageEntry("add-client-tag", ENABLE_CLIENT_TAG); + const localSettings = { idbMaxEvents, wasmPersistForDays, @@ -53,6 +55,7 @@ const localSettings = { webRtcLocalIdentity, webRtcSignalingRelays, webRtcRecentConnections, + addClientTag, }; if (import.meta.env.DEV) { diff --git a/src/views/settings/post/index.tsx b/src/views/settings/post/index.tsx index 9d664bd85..cb568b070 100644 --- a/src/views/settings/post/index.tsx +++ b/src/views/settings/post/index.tsx @@ -19,6 +19,7 @@ import { AlertTitle, AlertDescription, Heading, + Switch, } from "@chakra-ui/react"; import { matchSorter } from "match-sorter"; @@ -28,6 +29,8 @@ import useUsersMediaServers from "../../../hooks/use-user-media-servers"; import useCurrentAccount from "../../../hooks/use-current-account"; import useSettingsForm from "../use-settings-form"; import VerticalPageLayout from "../../../components/vertical-page-layout"; +import localSettings from "../../../services/local-settings"; +import useSubject from "../../../hooks/use-subject"; export default function PostSettings() { const account = useCurrentAccount(); @@ -64,6 +67,8 @@ export default function PostSettings() { ); }; + const addClientTag = useSubject(localSettings.addClientTag); + return ( Post Settings @@ -158,6 +163,26 @@ export default function PostSettings() { How much Proof of work to mine when writing notes. setting this to 0 will disable it + + + + + Add client tag + + localSettings.addClientTag.next(!localSettings.addClientTag.value)} + /> + + + Enabled: Attach the{" "} + + NIP-89 + {" "} + client tag to events + + - ) : ( - : } - aria-label={expanded.isOpen ? "Collapse" : "Expand"} - title={expanded.isOpen ? "Collapse" : "Expand"} - /> - )} + + + + {!isFocused && + (replies.length > 0 ? ( + + ) : ( + : } + aria-label={expanded.isOpen ? "Collapse" : "Expand"} + title={expanded.isOpen ? "Collapse" : "Expand"} + /> + ))} ); @@ -153,7 +158,7 @@ function ThreadPost({ post, initShowReplies, focusId, level = -1 }: ThreadItemPr )} {replyForm.isOpen && } - {level === -1 ? ( + {isFocused ? ( ) : ( expanded.isOpen &&