Commit Graph

417 Commits

Author SHA1 Message Date
Chad Curtis 5c89dc8ea0 Organize Other Stuff into Media / Social / Whimsy sections
Add a 'section' field to ExtraKindDef and group content types in both
FeedSettingsForm and ContentSettings with labeled section headers.
2026-02-21 00:19:08 -06:00
Chad Curtis 151ea6ab75 Fix missing Radio icon for streams in feed settings
Both FeedSettingsForm and ContentSettings were missing the 'streams'
entry in their ICONS map, causing it to fall back to a Palette icon
instead of the Radio icon used everywhere else.
2026-02-21 00:15:31 -06:00
Chad Curtis 99e864f815 Hide auth-only UI elements when logged out
Hide bookmarks, profile nav links, profile settings tab, wallet,
and network settings (relays, blossom servers) from logged-out users.
2026-02-21 00:11:40 -06:00
Chad Curtis 4707b37ad7 Fix emoji picker flashing quick select after deeper picker selection
Close the popover via onClose callback when an emoji is selected from
the full picker. Add a 300ms cooldown (justClosedRef) to prevent the
popover from immediately reopening via hover when the picker disappears
and the cursor lands on the trigger button.
2026-02-20 23:49:02 -06:00
Chad Curtis 58d7511545 Apply theme immediately on selection during onboarding 2026-02-20 22:21:02 -06:00
Chad Curtis 1d967b98d0 Integrate signup into onboarding flow, replace SignupDialog
Sign up now triggers the full onboarding overlay instead of a dialog.
The flow starts with keygen -> download key (logs in) -> profile setup
(kind 0) -> then continues with the existing settings questionnaire
(theme, content, safety, follows, outro).

Added OnboardingContext with useOnboarding().startSignup() hook so any
component can trigger the signup flow. Updated LoginArea, Feed,
LeftSidebar, and FloatingComposeButton to use it instead of
SignupDialog. SignupDialog is no longer imported by any component.
2026-02-20 22:18:51 -06:00
Chad Curtis a88a44d59e Preload feed behind outro when user followed a pack
If the user followed at least one pack during onboarding, render the
app tree (invisible) behind the outro overlay so React Query starts
fetching the follows feed in the background. When they tap 'Let's go',
content is already loaded. Users who skipped follows don't preload
since they'll land on the global feed which loads fast enough.
2026-02-20 22:11:43 -06:00
Chad Curtis f64ef2aed7 Fix outro wording: weird -> fun 2026-02-20 22:08:19 -06:00
Chad Curtis d5772de200 Revise outro text to be warmer and more playful 2026-02-20 22:06:50 -06:00
Chad Curtis f279b456c0 Shorten outro text 2026-02-20 22:06:37 -06:00
Chad Curtis c17815ea0b Add follow packs step and sentimental outro to onboarding
After saving settings, onboarding now checks the user's kind 3 follow
list. If empty, it shows suggested follow packs (starting with
naddr1qvzqqqyckypzpyexz3t34l966ngh5xg7u2q788hthdqmj0av3lv8s2tz9t43zt6d)
with member avatars and a Follow All button. Users with an existing
follow list skip this step.

The final step is now a warm outro thanking the user and inviting them
into the app, replacing the old spinner-only done screen.
2026-02-20 22:06:04 -06:00
Chad Curtis 1c640e3202 Use ChestIcon for treasures in onboarding content picker 2026-02-20 21:56:20 -06:00
Chad Curtis 3bcbd53100 Use lucide icons in onboarding and disable follow packs by default
Replace emoji icons with lucide-react components (Clapperboard, BarChart3,
MapPin, Palette, Users, Radio) in the content type picker. Remove follow
packs from the default selection for new users.
2026-02-20 21:53:29 -06:00
Chad Curtis 726af608a0 Add initial sync screen with setup questionnaire for new devices
When a user logs in, show a sync spinner while fetching their settings
from Nostr relays. If existing settings are found (returning user on a
new device), apply them and proceed. If no settings exist (fresh account),
walk through a brief questionnaire for theme, content preferences, and
content safety policy. Uses sessionStorage to avoid re-showing on refresh.
2026-02-20 21:47:25 -06:00
Chad Curtis 190a0dba9b Optimize feed load performance: caching, code splitting, and instant rendering
- Cache follow list and author profiles in localStorage for instant feed on return visits
- Prefetch profile images via <link rel=preload> for instant avatar rendering
- Replace Radix Avatar with lightweight component that renders <img> immediately
- Lazy-load route components (React.lazy) reducing main bundle from 1.7MB to 920KB
- Dynamic import hls.js (1.3MB) only when visiting stream pages
- Remove unused Buffer polyfill
- Add pre-React loading spinner in index.html outside #root for seamless handoff
- Fix 3-5s feed rerender caused by NostrSync relay/settings sync
- Fix Zod 4 strict mode rejecting feedSettings with extra/missing keys from localStorage
- Fix useLocalStorage skip update when value reference unchanged
- Reduce eoseTimeout from default to 600ms
2026-02-20 21:23:07 -06:00
Chad Curtis 60a23aa0b3 Fix reply context overflow breaking sticky nav on mobile
Long unbroken names (raw npubs used as display names) in 'Replying to'
overflowed the container, pushing the page wider than the viewport and
making sticky/fixed nav elements scroll off-screen horizontally.

Truncate author names at 200px, add overflow-hidden on the container,
and shrink-0 on static text to prevent wrapping issues.
2026-02-20 17:59:06 -06:00
Chad Curtis afa7ede1c9 Respect content warning policy in profile media grid
CW media squares show a blurred placeholder with a shield icon instead
of loading the actual image/video. When policy is 'hide', CW media is
excluded from the grid entirely.
2026-02-20 17:01:26 -06:00
Chad Curtis 9b0313f83f Match CW settings layout to other settings rows: label left, radio right 2026-02-20 16:57:42 -06:00
Chad Curtis 469dd406d7 Contain blur within rounded box, don't let it bleed outside 2026-02-20 16:55:18 -06:00
Chad Curtis e41ce2e10b Fix content warning overlay: move overlay outside overflow-hidden container and check NIP-32 l tags for CW reason 2026-02-20 16:54:09 -06:00
Chad Curtis eb483469bb Add NIP-36 content warning support with blur/hide/show settings
Respect content-warning tags on events. Users can choose how to handle
them in Settings > Content > Sensitive Content:

- Blur (default): Shows a grey placeholder overlay with the warning
  reason in quotes. Media is not loaded until the user clicks reveal.
- Hide: Removes content-warned posts from the feed entirely.
- Show: Ignores content warnings and displays everything normally.

The setting syncs across devices via encrypted NIP-78 settings.
2026-02-20 16:45:33 -06:00
Chad Curtis 3314f01b5e Fix failing tests and ESLint config
- Update NoteContent tests to use inline URLs (mid-sentence) instead of
  end-of-line URLs that render as LinkPreview cards without accessible links
- Update mention styling assertion from text-gray-500 to text-muted-foreground
  to match the actual NostrMention component classes
- Add android/ to ESLint ignores to prevent linting build output artifacts
2026-02-20 15:20:18 -06:00
Chad Curtis 5bbbc5022a Fix mobile live stream layout: viewport-locked chat above bottom nav
Lock main element to viewport height on mobile with body scroll disabled,
collapsible description with author under details, zap button inline with
title, and chat input sitting directly above the bottom nav with no gaps.
2026-02-20 15:14:05 -06:00
Chad Curtis 4882a90403 Add NIP-53 live stream support with HLS player and live chat
Implement kind 30311 live streaming events: HLS video player (hls.js),
kind 1311 live chat with real-time subscriptions, stream detail page with
collapsible description on mobile, desktop sidebar chat, streams feed page,
and full extra-kinds integration with sidebar nav and settings.
2026-02-20 14:52:48 -06:00
Alex Gleason ee9a1e34c3 Always route search queries to relay.ditto.pub (for now) 2026-02-20 00:11:03 -06:00
Alex Gleason 77ff88c2f6 Render NIP-30 custom emoji in all remaining display name locations
Apply EmojifiedText to mentions inside embedded/quote posts,
embedded note author names, and all other secondary UI locations
where display names were still rendered as plain text.
2026-02-19 21:43:56 -06:00
Alex Gleason 6180bbf0c3 Fix 30 ESLint errors: remove unused imports/variables, replace any types, use const 2026-02-19 20:14:01 -06:00
Alex Gleason be7cfbab67 Render NIP-30 custom emoji in display names, post text, and bios
Add emojify/EmojifiedText utilities that replace :shortcode: patterns with
inline images using emoji tags from kind 0 and kind 1 events. Applied to
display names across NoteCard, PostDetailPage, ProfilePage, ProfileHoverCard,
InteractionsModal, NotificationsPage, and NoteContent @mentions. Also
emojifies about/bio text in ProfilePage and ProfileHoverCard.

Remove string-level truncation from getDisplayName to avoid breaking
shortcodes mid-pattern (CSS truncate handles visual overflow). Use
em-relative sizing and align-text-bottom for proper inline alignment.
2026-02-19 19:06:14 -06:00
Alex Gleason 7e3f104ace Fix NIP-30 custom emoji reactions rendering as raw :shortcode: text
Custom emoji reactions from kind 7 events with emoji tags were displaying
the raw shortcode text (e.g., ':soapbox:') instead of rendering the image.
Add custom emoji resolution throughout the reaction pipeline: data hooks
now extract emoji URLs from event tags, and all rendering locations
(ReactionButton, PostDetailPage stats, InteractionsModal, Notifications)
now display custom emojis as inline images.
2026-02-19 18:39:43 -06:00
Chad Curtis 8fe07e65cc Add Nostr identifier detection in search and profile search, improve DomainFeedPage header
Detect NIP-19 and NIP-05 identifiers in the search bar and profile
search dropdown, navigating directly to the appropriate route instead
of performing a text search. Refactor DomainFeedPage header to use
back navigation, show user count inline, and match border styling.
2026-02-19 18:13:17 -06:00
Chad Curtis 3e7ba143f9 Add user-configurable settings for Blossom servers, zap comment, favicon provider, CORS proxy, and NIP-46 relays
- Add blossomServers (array), defaultZapComment, faviconProvider, corsProxy to AppConfig
- Blossom servers: multi-server support with add/remove UI matching relay list pattern
- Default zap comment changed from 'Zapped with MKStack!' to 'Zapped with Mew!'
- NIP-46 nostrconnect now uses the user's write relay list instead of hardcoded relay
- CORS proxy and favicon provider use {href} URI template pattern
- New 'System' section in Advanced Settings for zap comment, favicon provider, CORS proxy
- Fix ghost button hover text color on light/pink themes across settings panels
- Fix pre-existing TSC errors: appRelays array typing, muteHelpers dead code, ProfilePage FeedItem type, EditProfileForm useFieldArray, FeedSettingsForm/ContentSettings feedKey narrowing, LeftSidebar icon type
2026-02-19 17:51:51 -06:00
Chad Curtis 325e1b9be1 Remove verified badge, use brain icon for difficulty, put terrain next to difficulty 2026-02-19 17:11:38 -06:00
Chad Curtis a8b8243868 Use NoteContent for rich text rendering in polls and fix word-break overflow 2026-02-19 17:10:23 -06:00
Chad Curtis 54b27e4c09 Include extra kinds in profile media grid, extract vine URLs from imeta tags 2026-02-19 17:05:05 -06:00
Chad Curtis 09d722ddd2 Add object-cover to VideoPlayer to fill container without borders 2026-02-19 17:00:36 -06:00
Chad Curtis 95c3a5accc Fix desktop compose to open modal, cache right sidebar data, render vine videos on detail page 2026-02-19 16:54:16 -06:00
Chad Curtis f125abeef8 Restore avatar in compact ComposeBox feed view 2026-02-19 16:42:25 -06:00
Chad Curtis 9f6022e5e9 Render link previews for end-of-line URLs, skeleton load notifications, use ImageGallery, match mobile tab heights
- Show link preview cards for URLs that end a line, not just standalone
  URLs; only suppress previews for URLs followed by more text on the
  same line
- Show skeleton placeholders on notifications page until the query has
  completed at least once instead of flashing 'No notifications yet'
- Add skeleton loading for author rows in notification cards while
  profile data loads
- Replace inline image <a> tags with ImageGallery component so clicking
  images opens the lightbox with navigation
- Match notification tab height/weight to feed tabs on mobile while
  preserving original desktop styling
2026-02-19 16:39:13 -06:00
Chad Curtis a484c8b95c Delay stats invalidation after publish to preserve optimistic updates
The relay needs time to index newly published events. Immediate
invalidation caused a refetch that returned stale counts, overwriting
the optimistic +1 and making the count briefly appear then vanish.
2026-02-19 16:21:14 -06:00
Chad Curtis 35422ec6bb Fix optimistic updates, show user reaction emoji, compact embeds, and unify repost menu
- Add true optimistic updates for reactions and reposts via setQueryData
  instead of only invalidating queries after publish
- Track user's own reaction per event and display their emoji in place of
  the Heart icon across feed, post details, and notifications
- Strip whitespace around block embeds and skipped media URLs to eliminate
  blank lines caused by whitespace-pre-wrap
- Only render link preview cards for standalone URLs; inline URLs in
  sentences render as plain clickable links
- Remove border-b separators and use fixed-height object-cover on preview
  images to eliminate gaps
- Tighten padding on EmbeddedNote and EmbeddedNaddr cards
- Use fixed-height object-cover for ImageGallery grid images
- Unify RepostMenu to use Popover on all screen sizes instead of Drawer
  on mobile
2026-02-19 16:19:19 -06:00
Chad Curtis 7aad043734 Replace Repeat2 with custom RepostIcon, style repost/treasure action headers 2026-02-19 16:04:16 -06:00
Chad Curtis ec8e71cb70 Fix action header height — use w-11 instead of size-11 for icon container 2026-02-19 15:48:29 -06:00
Chad Curtis b0ac1180dd Align repost/treasure action text with username column, icon in avatar column 2026-02-19 15:46:57 -06:00
Chad Curtis aa231797af Add NIP-05 domain feeds, profile hover cards, gallery lightbox, and NIP-05 profile URLs
- Domain feed page at /timeline/:domain fetches .well-known/nostr.json and queries events from domain users
- NIP-05 domains are clickable in usernames throughout the app (Nip05Badge, NoteCard, PostDetailPage, etc.)
- @_@domain.com renders as @domain.com (underscore prefix hidden)
- Profile hover cards on avatars, usernames, and mentions across all components
- Clicking avatar/banner on profile page opens image in gallery lightbox with safe-area support
- NIP-05 verified users get clean profile URLs (e.g. /user@domain.com) instead of /npub1...
- NIP19Page unified dispatcher handles NIP-19, NIP-05, and profile routing at /:param
- Removed /u/:npub and /d/:domain routes in favor of root-level routing
- CORS proxy fallback for NIP-05 resolution on non-CORS-compliant servers
- Mobile top bar logo links to home
- Safe area fixes for gallery lightbox, mobile drawer, and sheet close button
2026-02-19 15:37:53 -06:00
Chad Curtis 64726d2cf7 Add local WebSocket notification polling and Mew splash/notification icons
- Implement Signal-like local-only notifications via direct WebSocket relay polling
- Poll every 60s foreground, 15min background, no external push server
- Resolve NIP-05 display names for notification body (e.g. 'alice@nostr.com reacted to your post')
- Add Capacitor LocalNotifications plugin with POST_NOTIFICATIONS permission
- Replace default Capacitor splash with Mew logo PNG on dark background using Android 12 Theme.SplashScreen
- Add ic_stat_mew vector drawable for notification small icon
- Regenerate splash PNGs with #14161f background
2026-02-19 10:40:38 -06:00
Chad Curtis 7ccac3d311 Fix NIP-85 default key overflow in advanced settings
- Add break-all utility to default pubkey text
- Prevents long hex string from overflowing on mobile screens
2026-02-19 07:55:22 -06:00
Chad Curtis 49c493d2fa Fix safe area padding in mobile drawer
- Add safe area top padding to Sheet close button (X icon)
- Add safe area bottom padding to theme toggle section
- Ensures UI elements don't overlap with device notches/navigation bars
2026-02-19 07:54:34 -06:00
Chad Curtis 8fc7dff792 Fix mobile APK issues: sticky headers and video playback
- Make headers sticky on all screen sizes (not just desktop)
- Add sticky positioning to settings tabs
- Add webkit-playsinline and x-webkit-airplay attributes for better mobile video support
2026-02-19 07:52:59 -06:00
shakespeare.diy 77993c4f74 Add safe area padding to mobile drawer menu
- Added safe-area-top to user profile header in mobile drawer
- Prevents content from being clipped behind status bar in APK
- Only applies to logged-in state header

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-19 07:47:07 -06:00
shakespeare.diy 725894b590 Fix sticky tabs going behind mobile top bar in APK
- Created top-mobile-bar utility class for sticky elements below mobile top bar
- Accounts for 48px bar height + safe-area-inset-top
- Updated Feed component tabs to use top-mobile-bar on mobile
- Updated NotificationsPage tabs to use top-mobile-bar on mobile
- Tabs now stick below the top bar instead of behind it

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-19 07:46:27 -06:00