The trending endpoint returned massive payloads with no field filtering support.
The search API with sort=readinglog and fields parameter returns slim responses
in under a second while still showing genuinely popular books.
- Add /books page displaying popular books fetched from OpenLibrary's trending API
- Add Books entry to sidebar registry so users can add it from the More menu
- Add /books route to AppRouter
- Show book title instead of raw 'isbn:...' in comment context by fetching book info via useBookInfo hook
Country suggestion only appears at the top of search results when
the query is an exact match on name or code. For prefix matches
(e.g. 'angol' -> Angola), the country appears below profile results.
If there are no profile results, the country is shown at the top.
Typing a country name in the search bar now shows matching countries
with their flag emoji, navigating to /i/iso3166:<CODE> on click.
Works on both desktop (ProfileSearchDropdown) and mobile
(MobileSearchSheet) with full keyboard navigation support.
Browse all countries in a searchable grid. Clicking a flag navigates
to the existing /i/iso3166:<CODE> external content page. The World
item is also registered in the sidebar so users can add it via the
More menu.
- Remove CustomEmojiPicker.tsx and useUserEmojiPacks.ts (replaced by
Derek's useCustomEmojis + emoji-mart custom categories)
- Update EmojiPackContent to use local kind 10030 query
- Update EmojiShortcodeAutocomplete to use useCustomEmojis
- Fix quick reaction buttons to render custom emojis as images
- Fix quick reaction buttons to include emoji tag when reacting
- Filter stale custom emojis from quick reaction row
- Add emoji tags to compose box mock event for preview rendering
Two fixes:
1. useCustomEmojis now resolves ['a', '30030:...'] references in the
user's kind 10030 emoji list, fetching the referenced kind 30030
emoji pack events and merging their emoji tags. Previously only
inline emoji tags were extracted, missing subscribed packs.
2. EmojiPicker theme detection now reads the --background CSS variable
lightness instead of checking for .dark class on <html>. Custom
themes set class='custom' (not 'dark'), so the dark class check
always returned false. Now works for all theme modes: light, dark,
system, custom, and profile themes.
Add collapseAfter prop to AncestorThread. When set, ancestors beyond that
depth are hidden behind a 'Show earlier posts' button with a dotted thread
indicator. Reactions pass collapseAfter=1 so only the reacted-to post is
immediately visible.
The parentEventId was only computed for text notes (isTextNote), so kind 7
reactions never resolved their e-tag parent. Include isReaction in the
condition so the AncestorThread renders the reacted-to post above.
Add min-h-10 and flex items-center on the content side so the text line
vertically centers against the size-10 emoji bubble. Bump inline avatar
from size-5 to size-6 for better visual balance.
Replace the standalone emoji bubble with the user's normal avatar plus a
small reaction emoji badge at the bottom-right corner. This keeps the
avatar column aligned with other threaded posts while still making the
reaction visually distinct.
ThemeBuilderPage only tracked colors in local state, so importing,
editing, previewing, saving, and publishing a theme all dropped the
font and background properties. Now all code paths pass the full
ThemeConfig (colors + font + background) through applyCustomTheme
and into publishTheme/setActiveTheme.
Reaction events now display with a prominent emoji bubble, small inline
avatar, author name, and 'reacted' label — making them visually distinct
from regular posts in both thread ancestors and standalone detail views.
Kind 10030 is a replaceable event that may only exist on relays the
user published to. The default pool (user's NIP-65 relays) may not
have it. Now queries both the default pool AND a broader set of
well-known relays (purplepag.es, relay.nostr.band, etc.) in parallel,
picking the most recent event across both sources.