diff --git a/.cursor/rules/bookmarks.mdc b/.cursor/rules/bookmarks.mdc new file mode 100644 index 00000000..ef0c29c9 --- /dev/null +++ b/.cursor/rules/bookmarks.mdc @@ -0,0 +1,16 @@ +--- +description: documentation that's useful when dealing with bookmark events (kind:10003 or kind:30003) or anything related to NIP-51 +alwaysApply: false +--- + +Read the nostrbook to understand how bookmarks work: +- https://nostrbook.dev/kinds/10003 +- https://nostrbook.dev/kinds/30003 + +They are defined in NIP-51: +- https://github.com/nostr-protocol/nips/blob/master/51.md + +Also refer to the applesauce bookmark helpers: +- https://github.com/hzrd149/applesauce/blob/17c9dbb0f2c263e2ebd01729ea2fa138eca12bd1/packages/core/src/helpers/bookmarks.ts + +Make sure to always use applesauce, and use it properly. diff --git a/kind-icons.txt b/kind-icons.txt new file mode 100644 index 00000000..04b47a4a --- /dev/null +++ b/kind-icons.txt @@ -0,0 +1,19 @@ +kind:0 = fa-circle-user +kind:1 = fa-feather +kind:6 = fa-retweet +kind:7 = fa-heart +kind:20 = fa-image +kind:21 = fa-video +kind:22 = fa-video +kind:1063 = fa-file +kind:1337 = fa-laptop-code +kind:1617 = fa-code-pull-request +kind:1621 = fa-bug +kind:1984 = fa-exclamation-triangle +kind:9735 = fa-bolt +kind:9321 = fa-cloud-bolt +kind:9802 = fa-highlighter +kind:30023 = fa-newspaper +kind:10000 = fa-eye-slash +kind:10001 = fa-thumbtack +kind:10003 = fa-bookmark diff --git a/src/components/ContentWithResolvedProfiles.tsx b/src/components/ContentWithResolvedProfiles.tsx index 716c1ad3..53becdea 100644 --- a/src/components/ContentWithResolvedProfiles.tsx +++ b/src/components/ContentWithResolvedProfiles.tsx @@ -11,17 +11,19 @@ const ContentWithResolvedProfiles: React.FC = ({ content }) => { const matches = extractNprofilePubkeys(content) const decoded = matches .map((m) => { - try { return decode(m) } catch { return undefined } + try { return decode(m) } catch { return undefined as undefined } }) - .filter(Boolean) + .filter((v): v is ReturnType => Boolean(v)) - const lookups = decoded.map((res) => getPubkeyFromDecodeResult(res as any)).filter(Boolean) as string[] + const lookups = decoded + .map((res) => getPubkeyFromDecodeResult(res)) + .filter((v): v is string => typeof v === 'string') const profiles = lookups.map((pubkey) => ({ pubkey, profile: useEventModel(Models.ProfileModel, [pubkey]) })) let rendered = content matches.forEach((m, i) => { - const pk = getPubkeyFromDecodeResult(decoded[i] as any) + const pk = getPubkeyFromDecodeResult(decoded[i]) const found = profiles.find((p) => p.pubkey === pk) const name = found?.profile?.name || found?.profile?.display_name || found?.profile?.nip05 || `${pk?.slice(0,8)}...` if (name) rendered = rendered.replace(m, `@${name}`) diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx index c7a977c3..e5d3a478 100644 --- a/src/components/IconButton.tsx +++ b/src/components/IconButton.tsx @@ -9,9 +9,6 @@ interface IconButtonProps { ariaLabel?: string variant?: 'primary' | 'success' | 'ghost' size?: number - href?: string - target?: string - rel?: string } const IconButton: React.FC = ({ @@ -20,35 +17,15 @@ const IconButton: React.FC = ({ title, ariaLabel, variant = 'ghost', - size = 44, - href, - target, - rel + size = 44 }) => { - const commonProps = { - className: `icon-button ${variant}`, - title, - 'aria-label': ariaLabel || title, - style: { width: size, height: size } - } as const - - if (href) { - return ( - - - - ) - } - return (