Commit Graph

4447 Commits

Author SHA1 Message Date
Alex Gleason 2ffbf3f430 fix: return null instead of undefined from NIP-85 query functions 2026-02-23 22:46:03 -06:00
Alex Gleason 8b596302a1 Parse OEmbed response with Zod schema in fetchLinkPreview 2026-02-23 22:06:45 -06:00
Alex Gleason b2416fabdb fix: access trends.tags array from TrendingTagsResult in SearchPage 2026-02-23 22:01:03 -06:00
Alex Gleason 3a8903f8e0 Pass labelCreatedAt from useTrendingTags to useTagSparklines to avoid duplicate REQ 2026-02-23 21:51:20 -06:00
Alex Gleason c85225127f Use requestIdleCallback in trends 2026-02-23 21:47:44 -06:00
Alex Gleason b8f8556515 Batch all sparkline filters into a single REQ for speed 2026-02-23 21:41:27 -06:00
Alex Gleason 148034eb26 Make sparkline queries sequential to avoid relay REQ limit 2026-02-23 21:37:49 -06:00
Alex Gleason 50ff3de053 Replace polyline sparkline with smooth cubic-bezier curve
Port the dataToPoints + SparklinesCurve algorithm from react-sparklines
inline, without adding the dependency. Key improvements:
- Smooth cubic bezier (C commands, divisor=0.25) instead of jagged polyline
- Full vertical range utilised: min/max scaling fills the chart height
- Thinner stroke (1.5px vs 2px) for a more delicate look
- Smaller viewBox (50x28) matching the legacy app dimensions
2026-02-23 21:12:29 -06:00
Alex Gleason b977b12f46 Fix sparkline day boundaries and per-tag query filtering
Mirror the server's getTrendingTags logic exactly:
- Use UTC-midnight-aligned calendar day boundaries derived from the
  most-recent label event's created_at, not rolling 24h windows from now
- Filter each per-day query with '#t': [tag] so only label events that
  mention the specific hashtag are returned, rather than any label event
  for that day
2026-02-23 21:04:07 -06:00
Alex Gleason 7285c7a986 Fix trends sidebar: filter by trusted pubkey and show real accounts/uses data
- Add TRENDS_PUBKEY author filter to all kind 1985 queries (useTrendingTags,
  useTrendingPosts, useTagSparklines) to only trust events from the known
  Ditto trends publisher
- Replace synthetic count with real accounts/uses values parsed from t tag
  indices 3 and 4 respectively
- Show '{accounts} people talking' in the Trends widget instead of '{count} posts'
- Sparklines continue to use the 'uses' field from per-day label events
2026-02-23 21:02:16 -06:00
Alex Gleason 439ab94ea3 Merge branch 'main' of gitlab.com:soapbox-pub/ditto-mew 2026-02-23 20:19:22 -06:00
Alex Gleason a76032bd89 Show NIP-05 loading skeleton in NoteCard while verification is pending 2026-02-23 20:17:42 -06:00
Alex Gleason eef20bd57a Show loading skeleton in Nip05Badge while verification is pending 2026-02-23 20:15:03 -06:00
Alex Gleason a9bd59bbc6 Fix Profile nav link in LeftSidebar not updating after NIP-05 verification
navItems useMemo was missing userProfileUrl from its dependency array, so
the Profile link kept the npub URL computed at first render. Adding
userProfileUrl as a dependency causes the nav to recompute once
useNip05Resolve returns and useProfileUrl switches to the NIP-05 URL.
2026-02-23 20:07:10 -06:00
Alex Gleason 263a9d1e76 NIP-05: don't fallback to CORS proxy, shorter timeout 2026-02-23 20:03:26 -06:00
Alex Gleason 929ea87067 Deduplicate NIP-05 hooks: useNip05Verify now delegates to useNip05Resolve
Both hooks were making separate fetches to the same endpoint. Rewrite
useNip05Verify as a thin wrapper that calls useNip05Resolve and compares
the resolved pubkey — they now share the same query key and a single
network request serves both verification and resolution.
2026-02-23 19:49:11 -06:00
Alex Gleason e86034d7da Fix NIP-05 resolution lowercasing the name portion of the identifier
The name portion of a NIP-05 identifier is case-sensitive per the spec.
useNip05Resolve was calling .toLowerCase() on it before building the URL
query param, causing lookups like Hyperhidrosis@shitposter-world.mostr.pub
to request ?name=hyperhidrosis and fail. Preserve the original casing for
both the URL request and the primary key lookup; keep the case-insensitive
fallback but compare both sides lowercased.
2026-02-23 19:46:11 -06:00
Alex Gleason 5cbae842e0 Fix /domain.com routes 404ing for _@domain.com NIP-05 users
isNip05Like in NIP19Page only checked for '@', so bare domain identifiers
like 'fiatjaf.com' fell through to NIP-19 decoding and returned NotFound.
Extend the check to match the same dot-based heuristic already used in
ProfilePage.
2026-02-23 19:43:34 -06:00
Alex Gleason bc9fd431b8 Fix _@domain.com profile URLs linking to npub instead of /domain.com
The _@ prefix denotes the root/default user for a domain. These users
should link to /domain.com (which the profile page resolves as a NIP-05
identifier), not the npub. The domain feed lives at /timeline/domain.com,
not /domain.com.
2026-02-23 19:42:43 -06:00
Alex Gleason 64cf10f381 Fix useProfileUrl to call useNip05Verify directly instead of peeking cache
The cache-peek approach always returned npub because the cache was empty
at render time. Replace it with a proper hook that calls useNip05Verify,
relying on TanStack Query's deduplication to avoid redundant requests.

Also fix the dot separator in NoteCard to hide when NIP-05 is unverified,
and refactor ProfileSearchDropdown to pass the verified URL through
onClick rather than recomputing it in an event handler.
2026-02-23 19:39:13 -06:00
Alex Gleason d3d44689d6 Verify NIP-05 identifiers before displaying them
Add useNip05Verify hook that uses Nostrify's NIP05.lookup() to verify
that a claimed NIP-05 identifier resolves to the correct pubkey via
.well-known/nostr.json. Update Nip05Badge and all raw nip05 display
sites to suppress display when verification fails or is pending.
2026-02-23 19:14:34 -06:00
Alex Gleason 2edbdf06cf Merge branch 'fix/repost-link-overflow' into 'main'
Fix horizontal overflow on posts with unrenderable links when reposting

Closes #5

See merge request soapbox-pub/ditto-mew!12
2026-02-24 01:04:02 +00:00
Alex Gleason f260b6192f fix: remove invalidateQueries after settings write to prevent theme revert
After updating encrypted settings, the onSuccess handler was calling
invalidateQueries which triggered a relay refetch. The relay would often
return the old event (before the new one propagated), causing NostrSync
to see a new lastSync timestamp and overwrite the locally-set theme
with the old value from Nostr.

The setQueryData call already keeps the cache up to date in-place,
so the invalidateQueries was purely counterproductive.
2026-02-23 18:04:27 -06:00
Alex Gleason 5a816369d0 Don't embed target event into kind 6 reposts 2026-02-23 17:55:18 -06:00
Alex Gleason 308deb3281 Restore nip85StatsPubkey as a configurable setting
The pubkey was incorrectly hardcoded in the previous commit. Restore it
to AppConfig, the Zod schema, defaultConfig objects, all three
useNip85Stats hooks, and the Stats Source section in AdvancedSettings.
The NIP-85 Only Mode toggle (and its nip85OnlyMode config field) remains
removed — NIP-85 is always used.
2026-02-23 17:14:19 -06:00
Alex Gleason 6e36097142 Remove NIP-85 toggle — NIP-85 stats are now always used
Remove nip85StatsPubkey and nip85OnlyMode from AppConfig, AppProvider
schema, and all defaultConfig objects. The stats pubkey is now a
hardcoded constant in useNip85Stats. Remove the Stats Source section
from AdvancedSettings (UI toggle and pubkey input). Simplify
useEventStats to use NIP-85 exclusively — delete the direct-query
fallback, computeStats, extractZapAmount, and parseBolt11Amount.
Simplify useComments to remove the NIP-85-driven limit heuristic and
the nip85Stats return value.
2026-02-23 16:59:29 -06:00
Alex Gleason cc25fee53d Restore useRepostStatus and decouple useEventInteractions from NIP-85
useRepostStatus is the correct pattern (matching useUserReaction) for
tracking the current user's own repost status via a targeted relay query
with optimistic cache support. useEventInteractions now only fetches raw
interaction events for the InteractionsModal — NIP-85 involvement and the
hasNip85Stats query-key trick are removed entirely.
2026-02-23 16:51:37 -06:00
Mary Kate Fain 379282ecea Fix horizontal overflow on posts with links when reposting
- Add overflow-hidden to NoteCard article elements in both normal and
  threaded layouts to clip content that exceeds card width
- Add overflow-hidden to NoteContent root div to prevent link preview
  cards and embedded content from pushing beyond container bounds
- Strip .xdc URLs in EmbeddedNote content preview (was missing from
  the media URL regex, causing raw long URLs to render in quote embeds)
- Add overflow-hidden to EmbedContentPreview paragraph for defense
  against long unbreakable strings
- Use disableEmbeds on NoteContent inside ReplyComposeModal's embedded
  post preview so URLs render as plain links instead of full preview
  cards that overflow the clamped container
- Add attachment indicator chips to EmbeddedNote (images, videos, apps,
  links) so stripped media URLs still have a visible presence
2026-02-23 16:46:49 -06:00
Alex Gleason 17c23e2d78 Merge branch 'unrepost' into 'main'
Add ability to unrepost a post

See merge request soapbox-pub/ditto-mew!10
2026-02-23 22:44:20 +00:00
Alex Gleason 6087c1a821 Derive repost status from useEventInteractions instead of a dedicated hook
Remove useRepostStatus (which made a separate relay query per post) and
instead look up the current user's pubkey in the reposts list already
fetched by useEventInteractions. Add eventId to RepostEntry so the
deletion event ID is available without an extra query.
2026-02-23 16:44:09 -06:00
Alex Gleason 3a9fc4d499 Merge branch 'follow-button-hover-card' into 'main'
Add follow button to profile hover card

See merge request soapbox-pub/ditto-mew!11
2026-02-23 22:34:55 +00:00
Alex Gleason 5986a13639 Simplify client tag (no fake names) 2026-02-23 16:21:57 -06:00
Mary Kate Fain 49daa1faad Add follow button to profile hover card
Create a reusable FollowButton component and add it to the
ProfileHoverCard, positioned over the banner image. The button
uses the existing useFollowActions hook for safe kind 3 mutations
and automatically hides for the user's own profile or when logged out.
2026-02-23 16:19:40 -06:00
Mary Kate Fain 7a8ee981bd Add ability to unrepost a post
Query the user's own kind 6 events to detect existing reposts, then
show an 'Undo repost' option in the popover menu and highlight the
repost button green when active. Unreposting publishes a kind 5
deletion event (NIP-09) with optimistic UI updates.
2026-02-23 15:55:44 -06:00
Alex Gleason d4bac9f255 Merge branch 'orient' into 'main'
Align 'Vibed with Shakespeare' footer text to the left

See merge request soapbox-pub/ditto-mew!6
2026-02-23 21:33:56 +00:00
Alex Gleason af643cbad3 Merge branch 'trends-infinite-scroll' into 'main'
Home page use Hot feed

See merge request soapbox-pub/ditto-mew!8
2026-02-23 21:33:36 +00:00
Alex Gleason 053e1888d0 Merge branch 'add-copy-npub-button' into 'main'
Add copy three dots menu to your own profile

See merge request soapbox-pub/ditto-mew!4
2026-02-23 21:32:51 +00:00
Mary Kate Fain efab0a4dee Rename 'Ditto' theme to 'Dark' and use Palette icon 2026-02-23 14:50:04 -06:00
Mary Kate Fain dc2724ccc9 Show hot sorted feed instead of global feed for logged-out users 2026-02-23 14:26:44 -06:00
Mary Kate Fain fe58061e28 Add infinite scroll pagination to trends feeds (hot, rising, controversial) 2026-02-23 14:23:39 -06:00
Mary Kate Fain 5a569c3ddd Remove floating Join button on mobile when logged out
The FloatingComposeButton now returns null for logged-out users,
removing the floating Join CTA from mobile. The topbar Join and
other login CTAs are unchanged.
2026-02-23 14:16:52 -06:00
Mary Kate Fain 2bcc695134 Align 'Vibed with Shakespeare' footer text to the left 2026-02-23 14:10:32 -06:00
Alex Gleason 319783d636 Refetch author profile on post detail, profile page, and hover card mount 2026-02-23 14:10:10 -06:00
Alex Gleason a87b6c3c02 Show skeleton loading states for avatars and names while profile is fetching
Replace the '?' avatar fallback and 'Anonymous' name placeholder with skeleton
loaders in ComposeBox and LeftSidebar during initial profile load. Expose
isLoading from useCurrentUser and useLoggedInAccounts to support this.
2026-02-23 13:37:44 -06:00
Alex Gleason cc74443010 Render DittoLogo using CSS mask with primary color 2026-02-23 13:10:47 -06:00
Mary Kate Fain b5dcd7085e Fix emoji picker crash caused by HTMLElement illegal constructor
Bypass @emoji-mart/react wrapper which creates new Picker() in useEffect,
causing 'Failed to construct HTMLElement: Illegal constructor' when React
remounts the component (e.g. opening popover in reply or compose box).
Instead, manage the emoji-mart Picker Web Component imperatively via refs.
2026-02-23 12:42:59 -06:00
Mary Kate Fain d64f29e52d Show three-dot menu on own profile for copy npub access, hide mute/report for self 2026-02-23 12:32:57 -06:00
Mary Kate Fain 8a00c4dd33 Add copy npub button to profile header for all profiles 2026-02-23 12:30:03 -06:00
Mary Kate Fain f735b0fde7 Add emoji shortcode autocomplete in compose box
Type a colon followed by at least 2 characters (e.g. :fi) to trigger
an inline emoji autocomplete dropdown. Navigate with arrow keys, select
with Enter/Tab, or dismiss with Escape. Uses the existing emoji-mart
data for search by shortcode, name, and keywords.
2026-02-23 12:20:00 -06:00
Alex Gleason 97ce94cc2f Merge branch 'full-emoji-picker' into 'main'
Replace hardcoded emoji picker with emoji-mart for full emoji support

See merge request soapbox-pub/ditto-mew!2
2026-02-23 18:13:47 +00:00