Commit Graph

72 Commits

Author SHA1 Message Date
Alex Gleason 6c67b34c60 npm audit fix 2026-03-13 17:08:49 -05:00
Dirk Rost b9c590598d Merge main into feature/development-feed and fix lint issues
Resolve merge conflicts from badges, books, help, and emojis rename.
Fix biome lint: add type="button" to all buttons, use template literals,
format new components with project conventions.
2026-03-13 16:34:36 -05:00
Alex Gleason 77d9375fca Upgrade to Vite 8 with Rolldown and switch to @vitejs/plugin-react v6
Replace Vite 6 (esbuild + Rollup) with Vite 8 (Rolldown), reducing
build times from ~12s to ~3.5s. Switch from the archived
@vitejs/plugin-react-swc to @vitejs/plugin-react v6 which uses Oxc
for React Refresh transforms.
2026-03-13 16:07:51 -05:00
Alex Gleason f4a0f3975a Add optional Plausible analytics via @plausible-analytics/tracker
Dynamically imports and initializes Plausible when the
VITE_PLAUSIBLE_DOMAIN env variable is set at build time.
When unset, the tracker code is never loaded.
2026-03-10 13:27:42 -05:00
Mary Kate Fain 405fcde5ad Add FAQ help tips to settings pages for confusing Nostr concepts
Create a reusable HelpTip component that shows a (?) icon popover with
FAQ content pulled from helpContent.ts, linking to the full Help page.

Place tips in settings where normie users are likely confused:
- Network settings: Relays and Blossom Servers section headers
- Wallet settings: NWC section header and zaps empty state
- Notification settings: next to 'zaps' in push notification description
- Profile settings: next to the Lightning address field
- Relay list manager: next to 'Your Relays' header (also remove NIP-65 jargon)
- Content settings: next to subtitle mentioning Nostr content types
2026-03-07 19:58:29 -06:00
Alex Gleason 57f9aab0a3 Remove welcome step from onboarding dialog 2026-03-07 18:52:05 -06:00
Chad Curtis c7f3211b7d Add user lists, follow packs, home feed tabs, and list-based feed filtering
- Add NIP-51 Follow Sets management (useUserLists, UserListsPage at /lists)
- Add Follow Packs support (useFollowPacks) for curated people lists
- Add FeedEditModal for creating/editing home feed tabs with author scope,
  kind picker, and list/pack author population
- Add AddToListDialog accessible from the note more-menu
- Unify home feed tab resolution with profile tabs via useResolveTabFilter,
  supporting $follows variable expansion
- Wire People filter in Search and FeedEditModal with list/pack picker
- Extract shared ScopeToggle, ListPackPicker, parseSelectedKinds primitives
  into SavedFeedFiltersEditor to eliminate duplication across three call sites
- Cache savedFeeds in AppConfig for instant tab render on load
- Strip orphaned profile-destination entries from encrypted settings on read
2026-03-06 17:23:47 -06:00
Alex Gleason 41eb5a4ef0 Add subdivision support with Wikipedia data, proper names, and thumbnail flags 2026-03-05 23:27:47 -06:00
Chad Curtis af3684fe40 Fix author filter: use profile search dropdown, only commit on selection
- Replace the raw text Input in the author filter with ProfileSearchDropdown
  so users get the same typeahead + avatar dropdown as the main search bar
- Add hideCountry prop to ProfileSearchDropdown to suppress country suggestions
  in contexts where they are irrelevant
- Author filter only writes to URL when a profile is explicitly selected from
  the dropdown (immediate commit) — typing alone never updates the URL, so
  slow per-keystroke relay queries no longer cause the filter to thrash
- Show a chip with the selected author's display name and an X to clear,
  replacing the dropdown while an author is active
- Add commitAuthor / clearAuthor helpers that keep the URL param and the
  display label in sync; resetFilters also clears the display label
2026-03-05 21:14:30 -06:00
Alex Gleason 35bc1a0438 Add configurable homepage route and show all items in mobile sidebar
- Add homePage config field (default: 'feed') that determines which
  sidebar item renders at the '/' route
- Any sidebar item can be set as the homepage via Feed settings
- The feed is always accessible at /feed when not configured as home
- Normalize sidebar item IDs: every item follows path === '/' + id
  (feed path changed from '/' to '/feed', emoji-packs renamed to emojis)
- Remove BOTTOM_NAV_ITEMS filter from MobileDrawer so all sidebar
  items are visible on mobile (feed, notifications, search included)
- Mobile bottom nav dynamically reflects the configured homepage icon
- Homepage setting syncs across devices via encrypted settings
- Add emoji-packs -> emojis migration for existing sidebar orders
2026-03-05 15:23:43 -06:00
Mary Kate Fain 706816478c Add Clear Sky Vibes theme preset with magenta primary and cyan text 2026-03-04 19:40:23 -06:00
Mary Kate Fain 8f140c4eaa Add bundled fonts and background images for all 8 new theme presets
Install Cinzel, Nunito, Quicksand, Courier Prime, and Comic Neue as
bundled fonts and register them in the font registry. Add Unsplash
background images to every new preset (Gothic, Cottage, Candy Heart,
Midnight, Hologram, Floret, Win 95, Plush).
2026-03-04 19:34:24 -06:00
Alex Gleason f5bc5fdbe4 Upgrade Nostrify (to fix NIP-05 signer issue) 2026-03-04 15:55:57 -06:00
Chad Curtis 8db2abe23b npm audit + npm dedupe + npx depcheck missing packages 2026-03-04 02:58:10 -06:00
Alex Gleason f1191299e8 Add Sentry integration with lazy loading and user-configurable DSN
Sentry SDK is loaded via dynamic import() only when a DSN is configured
and error reporting is enabled, keeping it out of the initial bundle.
Users can control error reporting via a toggle and DSN field in
Advanced Settings, with the DSN synced across devices via encrypted
NIP-78 settings. The ErrorBoundary now reports fatal crashes to Sentry
with component stack context, and a beforeSend hook censors nsec
private keys before any data leaves the browser.
2026-03-03 17:25:14 -06:00
Alex Gleason 80eac87a15 Upgrade @nostrify/nostrify to 0.50.3 and @nostrify/react to 0.2.28
Fixes race condition where NBrowserSigner would throw 'Browser extension
not available' when app code accessed signer.nip44 before the extension's
content script had injected window.nostr on page reload.
2026-03-03 17:14:10 -06:00
Chad Curtis 7aaa3e2587 Add interactive profile editor with live card, image crop, and onboarding integration 2026-03-03 07:31:06 -06:00
Chad Curtis 485e7cd1c9 refactor(photos): DRY up PhotosFeedPage by extending Lightbox instead of custom overlay
Replace the bespoke PhotoSlide / PhotoCard / PhotoDetailOverlay stack (~250 lines) with a
thin extension of the existing Lightbox component. Lightbox gains bottomBar, onNextEvent,
and onPrevEvent props; ImageGallery forwards them through. PhotosFeedPage now opens a plain
Lightbox with author info + reactions injected via bottomBar, and cross-event swipe/keyboard
navigation wired through onNextEvent/onPrevEvent. Page shrinks from 626 → ~300 lines.
2026-03-02 17:30:46 -06:00
Alex Gleason 53757a3886 Increase eoseTimeout to 300ms 2026-03-02 10:12:08 -06:00
Derek Ross addbece173 Add NIP-30 custom emoji picker support (kind 10030)
Integrate custom emojis from the user's kind 10030 emoji list into
the emoji picker, compose flow, reactions, and DMs:

Hook:
- useCustomEmojis: query kind 10030, extract emoji shortcode/url pairs

EmojiPicker:
- Accept customEmojis prop, render as dedicated 'Custom' tab via
  emoji-mart's custom categories feature
- Changed onSelect from string to EmojiSelection union type
  (native unicode | custom shortcode+url)

ComposeBox:
- Pass custom emojis to picker, insert :shortcode: on selection
- Scan content on publish for :shortcode: patterns, cross-reference
  against user's emoji list, add ['emoji', name, url] tags (NIP-30)

QuickReactMenu:
- Custom emoji reactions: content=':shortcode:', with emoji tag
- Optimistic cache update includes custom emoji URL/name

DMChatArea:
- Pass custom emojis to picker, insert :shortcode: text

Settings:
- Registered as 'Custom Emojis' in Other Stuff > Whimsy section
- showCustomEmojis toggle (default true) gates all custom emoji
  features — when disabled, no kind 10030 queries are made
- Fix pre-existing Bot icon missing import in sidebarItems
2026-03-01 20:28:08 -05:00
Alex Gleason 477257325c mew -> ditto 2026-03-01 17:50:50 -06:00
Chad Curtis 708dd23fc4 Add follows feed reply filter and fix feedSettings deep-merge for new keys 2026-02-28 20:27:03 -06:00
Alex Gleason fcd32f1bd4 Replace Twitter widgets.js with direct iframe embed, remove CSP exception 2026-02-28 18:46:25 -06:00
Mary Kate Fain 6598a0363a Fix lint errors: remove unused useEffect import, prefix unused schema
- ThemeSelector.tsx: remove unused useEffect import
- useBookInfo.ts: prefix OpenLibraryBookSchema with _ (only used for type inference)
2026-02-28 18:30:47 -06:00
Alex Gleason 7afe8efa21 Add profile preview at top of comment threads on person profiles
When viewing a kind 1111 comment thread where the root is a person
(kind 0 profile), show a compact profile preview card with avatar,
name, and NIP-05 at the top of the page, similar to how external
content previews are shown for URLs/books/countries.
2026-02-28 18:14:28 -06:00
Chad Curtis da1533bccf Unify sidebar icon/label sources of truth and rename items
- Create extraKindIcons.ts as single source of truth for extra-kind icons
- BUILTIN_ICON_COMPONENTS in SidebarNavItem covers system items only
- sidebarItemIcon() merges both maps; all pages/routes use it
- EXTRA_KINDS is now source of truth for labels and kind numbers in AppRouter, page titles, and onboarding (CONTENT_KINDS derived from EXTRA_KINDS)
- Remove themes from BUILTIN_SIDEBAR_ITEMS (it lives in EXTRA_KINDS)
- Delete dead SIDEBAR_ITEM_ICONS export
- Rename 'Theme' → 'Vibe', 'Colors' → 'Color Moments'
- Articles icon: FileText → BookOpen; Settings icon: Settings → Scroll
- Hide Vibe settings back button on non-mobile (md:hidden)
- Settings and Bookmarks page headers aligned to same structure
- Codex of Configuration opacity 40% → 60%
2026-02-28 03:12:51 -06:00
Alex Gleason 874c374434 Make flag emojis in post content clickable, linking to /i/iso3166:<CODE> pages 2026-02-28 00:19:36 -06:00
Chad Curtis f8acb1b630 Sync sidebar order, feed tabs, and advanced URLs to encrypted settings; remove sidebar column from content settings 2026-02-28 00:12:37 -06:00
Alex Gleason 1302f5933c Replace regex manifest.toml parsing with smol-toml for correct TOML handling 2026-02-27 19:27:56 -06:00
Mary Kate Fain adceba5a54 Add 7 Y2K aesthetic theme presets with bundled display fonts
Add Skater, Kawaii, Grunge, MS Paint, Retro Pop, Bubblegum, and Gamer
theme presets derived from the ditto-1 aesthetic designs. Each preset
includes tailored CoreThemeColors, a display font, and a Blossom-hosted
background image.

Install and register 7 new fontsource display fonts (Permanent Marker,
Cherry Bomb One, Creepster, Silkscreen, Bungee Shade, Luckiest Guy,
Press Start 2P) in the bundled font registry so they appear in the
FontPicker for custom theme building as well.
2026-02-27 15:55:40 -06:00
Alex Gleason 658c7d1dc1 Refactor Webxdc page to use standard Feed with tag filters
Replace the custom WebxdcFeedPage with KindFeedPage, powered by
a new tagFilters option on useFeed/Feed/KindFeedPage. The webxdc
page now uses the same follows/global tabs, pull-to-refresh, and
NoteCard rendering as every other feed.

- useFeed: accept optional tagFilters (e.g. { '#m': [...] })
- Feed/KindFeedPage: pass tagFilters through
- FloatingComposeButton: accept onFabClick callback override
- LayoutOptions: add onFabClick for custom FAB behavior
- Remove useWebxdcFeed (no longer needed)
2026-02-27 11:21:58 -06:00
Chad Curtis 4d83a6c934 Improve reply threading: show first sub-reply as hint, use text color for connector line 2026-02-26 19:44:05 -06:00
Alex Gleason cd6d5f7a7c Replace Comic Neue with Comic Relief in bundled fonts 2026-02-26 16:15:09 -06:00
Alex Gleason 3b15044919 Implement ThemeConfig type system with bundled fonts and NIP.md-compliant event parsing
- Add ThemeConfig wrapper type (colors + fonts + background) replacing bare CoreThemeColors
- Sync theme event parsing/building with NIP.md spec: colors in c tags (hex), fonts in f tags, background in bg tags (imeta-style), empty content field
- Legacy backward compat: parse old JSON-in-content format and bare CoreThemeColors in localStorage/encrypted settings
- Bundle 10 curated fonts via fontsource (Inter, DM Sans, Outfit, Montserrat, Lora, Merriweather, Playfair Display, JetBrains Mono, Comfortaa, Comic Neue) with lazy dynamic imports
- Create font loader (src/lib/fontLoader.ts) for @font-face injection from remote URLs and CSS override application for title/body roles
- Rewrite FontPicker as dual title/body picker using bundled fonts instead of Google Fonts CDN
- Remove Google Fonts integration (useGoogleFont.ts, GoogleFontLoader.tsx)
- Resolve bundled font family names to CDN URLs when publishing to Nostr
- Apply profile theme fonts when visiting other users' profiles
- Update all consumers: AppProvider, useTheme, usePublishTheme, useEncryptedSettings, ThemeSelector, ThemeBuilderPage, ProfilePage, EditProfileForm, InitialSyncGate, NostrSync
2026-02-26 14:46:30 -06:00
Chad Curtis 8e5b59c44e feat: use planet icon for feed nav item 2026-02-26 05:37:19 -06:00
Alex Gleason 808d44aeff Reconcile theme settings changes and add share toggle
Merge upstream changes with the theme settings refactor. Adds a
'Display my theme to others' toggle that publishes a kind 11667
active profile theme event when enabled and issues a kind 5 deletion
when disabled. Split /settings/appearance into /settings/theme and
/settings/content. Move theme builder to /settings/theme/edit.
2026-02-26 04:10:23 -06:00
Chad Curtis c4723ccd41 Reconcile upstream changes with mobile nav refactor 2026-02-26 03:53:15 -06:00
Alex Gleason 69875bd57a Split /settings/appearance into /settings/theme and /settings/content
Replace the tabbed Appearance settings page with two separate pages:
- /settings/theme for theme selection
- /settings/content for feed and content preferences

Move the theme builder from /settings/theme to /settings/theme/edit to
avoid the route conflict. Update all navigation links across the codebase.
2026-02-26 03:11:04 -06:00
Alex Gleason 29a9a0f36c Merge branch 'add-custom-theme-editor-ui' 2026-02-26 02:28:23 -06:00
Alex Gleason 8d03d32b0d Simplify theme system to 4 core colors (background, text, primary, secondary)
Replace the 19-token ThemeTokens interface with a 4-field CoreThemeColors
for config storage, Nostr events, and encrypted settings. All other
Tailwind CSS tokens (card, muted, border, etc.) are now derived
automatically via deriveTokensFromCore().

- Add CoreThemeColors interface: { background, text, primary, secondary }
- Keep ThemeTokens as internal type for CSS variable injection
- Update builtinThemes and themePresets to store CoreThemeColors
- Add backward-compatible parsing for legacy 19-token format in Nostr
  events, encrypted settings, and localStorage
- Simplify ThemeBuilderPage: remove Surface/UI color sections, just 4
  color pickers with auto-derivation always on
- Update all consumers: ThemeSelector, ScopedTheme, ThemeUpdateCard,
  MobileDrawer, LeftSidebar, ProfilePage, InitialSyncGate, etc.
2026-02-25 22:46:27 -06:00
Chad Curtis a2f0397c0c Scale down adaptive icon foreground to 70% for proper safe-zone fit 2026-02-25 21:28:01 -06:00
Mary Kate Fain b8d7d8a730 Redesign sidebar navigation with section grouping, customization, and mobile consistency
- Desktop: Remove redundant Home/Search nav items (logo serves as Home, inline
  search covers both quick lookup and full search page navigation)
- Add visual section grouping with labeled separators (Explore, You, Settings)
- Replace ugly dashed 'Add' button with subtle 'More...' inline link
- Add edit mode with drag-and-drop reordering (@dnd-kit) and remove buttons
  for content-type items in the Explore section
- Hover-to-remove on desktop content-type items outside edit mode
- Mobile: Replace avatar menu trigger with standard hamburger icon
- Mobile: Add search icon to top bar right side
- Mobile: Redesign bottom nav as 4-tab layout (Home, Explore, Notifications, You)
- Mobile: Explore tab opens bottom sheet with content type links (vaul Drawer)
- Mobile drawer: Replace profile header with logo, restructure to match desktop
  sections, add 'Manage...' link for settings, remove redundant Profile link
- Add sidebarOrder to AppConfig for persisting custom item order
- Extend useFeedSettings hook with orderedRoutes, addToSidebar, removeFromSidebar
2026-02-25 08:54:37 -06:00
Alex Gleason 7a85ec73ed Refactor theme system: separate builtin themes from custom presets
Restructure the theme architecture so 'light', 'dark', and 'system' are
builtin themes with build-time colors (customizable by self-hosters),
while 'black', 'pink', and future themes become presets that apply to a
single 'custom' theme slot.

Key changes:
- Theme type is now 'light' | 'dark' | 'system' | 'custom'
- builtinThemes (light/dark) and themePresets (black/pink/etc.) are
  separate maps in themes.ts
- AppConfig gains optional customTheme (ThemeTokens) field
- useTheme exposes applyCustomTheme(tokens) for applying presets
- Custom theme tokens sync across devices via encrypted settings
- Backward compat: legacy 'black'/'pink' values in localStorage and
  encrypted settings auto-migrate to custom + preset tokens
- All UI surfaces updated: ThemeSelector, LeftSidebar dropdown,
  MobileDrawer cycle, and onboarding ThemeStep
2026-02-24 21:46:28 -06:00
Chad Curtis 42a9535761 fix: remove lazy loading to prevent endless spinner on direct event load
The endless spinner issue was caused by lazy loading pages without a Suspense
fallback. When users navigated to nevent URLs or other NIP-19 identifiers, the
Suspense boundary had no fallback, causing a blank screen or stuck preloader.

Changes:
- Removed all lazy() imports from AppRouter
- Removed Suspense boundary (no longer needed without lazy loading)
- All pages now load eagerly for instant rendering
- Kept the HexIdentifierPage loading skeleton fix from previous commit

This ensures users see immediate visual feedback when loading any page,
especially when navigating directly to event URLs via nevent identifiers.
2026-02-24 23:48:09 +00:00
Chad Curtis b02b2a9e56 Rebrand Android app icons to Ditto logo with purple background 2026-02-24 01:03:53 -06:00
Alex Gleason 8febb405e5 Use imeta dim/blurhash for media placeholders before load
- Parse NIP-94 dim and blurhash fields in parseImetaMap (NoteCard + PostDetailPage)
- ImageGallery/GridImage: use dim for correct aspect-ratio skeleton sizing; render Blurhash canvas placeholder when available
- VideoPlayer: set aspect-ratio container from dim; show Blurhash canvas before first frame/poster loads
- Install react-blurhash (+ blurhash) for canvas rendering
2026-02-23 22:58:56 -06:00
Alex Gleason 5986a13639 Simplify client tag (no fake names) 2026-02-23 16:21:57 -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
Alex Gleason cc74443010 Render DittoLogo using CSS mask with primary color 2026-02-23 13:10:47 -06:00
Mary Kate Fain c046e33f6b Replace hardcoded emoji picker with emoji-mart for full emoji support 2026-02-23 12:05:21 -06:00