Commit Graph

53 Commits

Author SHA1 Message Date
sam a56860a6ce logo/copy changes 2026-04-17 12:15:51 +05:45
Alex Gleason 22f13c1505 Replace __DITTO_CONFIG__ global with import.meta.env.DITTO_CONFIG and remove ThemeSchemaCompat
Move build-time ditto.json injection from a Vite define global to
import.meta.env.DITTO_CONFIG (a JSON string parsed and validated at
runtime via DittoConfigSchema). Remove the global type declaration
from vite-env.d.ts.

Drop ThemeSchemaCompat and its legacy "black"/"pink" migration code
from AppProvider and NostrSync — invalid theme values now simply fail
Zod validation.

Fix a latent bug where a partial feedSettings from ditto.json would
replace the full hardcoded defaults; defaultConfig now deep-merges
feedSettings.
2026-04-01 23:16:33 -05:00
Alex Gleason ddb8c45a70 Fix custom title fonts not loading on app startup
The useApplyFonts hook in AppProvider only loaded body fonts
(activeConfig.font) but never loaded title fonts (activeConfig.titleFont).
The loadAndApplyTitleFont function and CSS variable --title-font-family
existed but were never called on startup/theme change, so components
referencing the variable always fell back to inherit.
2026-03-25 20:29:40 -05:00
Chad Curtis f200359059 Implement BUD-03 kind 10063 Blossom server list management
Blossom servers now work exactly like relays:
- App default servers (APP_BLOSSOM_SERVERS) can be toggled on/off
- User's kind 10063 server list is fetched and synced from Nostr
- NostrSync fetches kind 10063 on login and applies it to config
- useInitialSync fetches kind 10063 in parallel on first login
- BlossomSettings UI mirrors RelayListManager with two sections:
  App Blossom Servers (with enable toggle) + Your Blossom Servers
- User changes publish a kind 10063 replaceable event to Nostr
- getEffectiveBlossomServers() merges app + user servers like getEffectiveRelays()
- Migration from old blossomServers[] to blossomServerMetadata handled in AppProvider
2026-03-14 12:34:59 -05: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 a25700126f Dynamically recolor favicon to match the active theme's primary color 2026-02-27 17:49:53 -06:00
Alex Gleason 3eb92f472c Support build-time ditto.json config file
Read an optional ditto.json (or CONFIG_FILE env) at build time, validate
it with Zod, and inject the result via Vite's define. At runtime the
build-time values are merged between the hardcoded defaults and user
localStorage, giving precedence: user > build-time > hardcoded.

Extract canonical Zod schemas into config/schema.ts (no path aliases)
so they can be imported from both vite.config.ts and runtime code.
Move AppConfigSchema out of AppProvider into src/lib/schemas.ts to
eliminate duplication.
2026-02-26 17:53:54 -06:00
Alex Gleason d45adf604a Route all light/dark theme resolution through resolveThemeConfig()
Every place that previously read builtinThemes directly for light/dark
mode now calls resolveThemeConfig(), which checks config.themes first
and falls back to builtinThemes. This ensures configured themes are
actually used for colors, fonts, and backgrounds in all code paths:
AppProvider, useTheme, ThemeSelector, ThemeBuilderPage, ProfilePage.
2026-02-26 17:41:31 -06:00
Alex Gleason 97f873118e Add themes config to AppConfig for configurable light/dark themes
Allow self-hosters to override the builtin light/dark themes by setting
a themes field in AppConfig with full ThemeConfig objects (colors, fonts,
backgrounds) for each mode.
2026-02-26 17:29:54 -06:00
Alex Gleason 3247624600 Fix font not updating when switching between presets
Use primitive fontFamily/fontUrl strings as effect dependencies instead
of the font object reference, matching the same fix applied to
background handling.
2026-02-26 16:13:51 -06:00
Alex Gleason 724df5e5d9 Fix background not clearing when switching to a preset without one
Use primitive bgUrl/bgMode strings as effect dependencies instead of
the background object reference, ensuring React detects the change
when switching between presets with and without backgrounds.
2026-02-26 16:03:15 -06:00
Alex Gleason b5a59ac9a6 Remove 'contain' background mode from NIP.md and codebase, keep only cover and tile 2026-02-26 15:22:35 -06:00
Alex Gleason 78169c62d3 Add background image picker to theme settings
Upload images via Blossom, store in ThemeConfig.background, and apply
as a fixed CSS background on <body>. Supports cover/tile/contain modes.
Background picker sits in the consolidated customize card between the
font picker and the share toggle.
2026-02-26 15:14:00 -06:00
Alex Gleason bc4cc80581 Simplify theme fonts to a single font (remove heading/body roles)
Reduce font complexity from two-role (title/body) to a single font
that applies globally to all text. Updates NIP.md f tag format from
["f", family, role, url] to ["f", family, url], removes ThemeFonts
wrapper in favor of a single ThemeFont on ThemeConfig.font, and
simplifies FontPicker to a single dropdown.
2026-02-26 14:57:41 -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
Alex Gleason 3732843fd4 Reduce core theme colors to 3 (primary, text, background) and reorder UI
Remove the secondary/accent color from user-level configuration. The
Tailwind 'accent' token now mirrors 'primary' directly. CoreThemeColors
is now { background, text, primary } — 3 fields instead of 4.

- deriveTokensFromCore() takes 3 params; accent = primary
- Theme builder shows pickers in order: Primary, Text, Background
- Backward-compatible parsing for old 4-color and 19-token formats
- Color swatches reordered to primary, text, background everywhere
2026-02-25 23:55:01 -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
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 67f0dc32e7 Merge branch 'main' of gitlab.com:soapbox-pub/ditto-mew
# Conflicts:
#	src/components/AppProvider.tsx
#	src/hooks/useTheme.ts
2026-02-24 22:09:09 -06:00
Alex Gleason 6328c6f6ae Remove builtin/custom labels from theme UI and add preset emojis
Drop the 'Builtin' and 'Custom' section headers from the ThemeSelector
grid and the LeftSidebar dropdown so the distinction is invisible to
users. Add emoji metadata to theme presets (ThemePreset interface) and
display them in the sidebar dropdown and mobile drawer cycle button
instead of the generic Palette icon.
2026-02-24 21:54:44 -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 3c91952e5c Fix theme flicker by using useLayoutEffect for CSS var injection
useEffect fires after paint, causing a one-frame flash of old colors when switching themes. useLayoutEffect fires synchronously before paint, eliminating the flicker. Also keep document.documentElement.className in sync with the active theme.
2026-02-24 21:36:30 -06:00
Alex Gleason b42ca9434a Add 'system' theme option that follows OS prefers-color-scheme 2026-02-24 20:56:17 -06:00
Chad Curtis 1af6a45a77 Fix preloader flash and green logo on light/pink themes
Defer body inline style removal until CSS variables are injected by
useApplyTheme, preventing a one-frame flash of unstyled background.

Replace preloader logo <img> with CSS mask technique matching the React
DittoLogo component, so the logo uses the theme's primary color instead
of filter:invert() which turned purple into green.
2026-02-24 00:39:27 -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 0d48221476 Validate encrypted settings with Zod to prevent corrupted data from crashing the app
Encrypted settings synced via NIP-78 were parsed with a bare JSON.parse()
and cast with 'as EncryptedSettings', allowing invalid data (e.g. theme as
an object instead of a string) to pass through unchecked and crash the UI
when applied to classList.add(). Now both useEncryptedSettings and
useInitialSync validate decrypted JSON with a shared EncryptedSettingsSchema,
gracefully dropping invalid fields instead of propagating them.
2026-02-23 11:37:17 -06:00
Alex Gleason f826379d95 Fix crash when theme from localStorage has no matching tokens 2026-02-23 11:15:47 -06:00
Alex Gleason f45e585c8f Migrate theme definitions from CSS to JS 2026-02-22 22:39:10 -06:00
Alex Gleason f453df10a0 Replace CORS proxy HTML scraping with configurable OEmbed link preview endpoint
Link previews now fetch from a dedicated link preview service (default:
https://fetch.ditto.pub/link/{url}) that returns OEmbed JSON, instead of
fetching raw HTML through a CORS proxy and parsing OG tags client-side.

- Add linkPreviewUrl config with RFC 6570 URI template support
- Rewrite useLinkPreview to consume OEmbed responses
- Update LinkPreview to render OEmbed fields (thumbnail_url, provider_name, etc.)
- Use ExternalFavicon component for link preview favicons (consistent with rest of app)
- Add linkPreviewUrl setting to Advanced Settings UI
- Generalize faviconUrl.ts into templateUrl() with {url} variable support
2026-02-21 16:28:23 -06:00
Alex Gleason cfb5659020 Replace DomainFavicon with ExternalFavicon using configurable favicon URL template
The old DomainFavicon component had a multi-step fallback chain (HTML scraping,
direct URL guessing, then the configured provider) which meant the configurable
setting was almost never reached. The new ExternalFavicon component uses the
configured favicon URL template directly via RFC 6570 URI templates.

- Rename config field faviconProvider -> faviconUrl
- Add faviconUrl() utility with uri-templates for RFC 6570 support
- Remove local Favicon component from ProfileRightSidebar
- Update all consumers to use ExternalFavicon
2026-02-21 15:14:30 -06:00
Chad Curtis ffc7672183 Add Magic: The Gathering deck lists as extra kind (NIP-MG, kind 37381)
Support kind 37381 addressable events for MTG deck sharing per NIP-MG spec.
Includes MagicDeckContent component with card list rendering, format/archetype
badges, commander/companion display, sideboard, foil indicators, and
expand/collapse for large decks. Adds /decks route and sidebar navigation.
2026-02-21 05:03:46 -06:00
Chad Curtis 9074c9b763 Move articles to Media section with sidebar/page toggle
Articles (kind 30023) now have both a showArticles sidebar toggle and
feedIncludeArticles feed toggle, matching the pattern of other content
types like Vines and Streams. Added FileText icon to all icon maps.
2026-02-21 01:06:41 -06:00
Chad Curtis 1e9bd782aa Add Notes section for feed content organization (posts, reposts, articles)
- Add 'feed' section to EXTRA_KINDS for Posts (kind 1), Reposts (kind 6),
  and Articles (kind 30023) as feed-only toggles
- Add feedIncludePosts, feedIncludeReposts, feedIncludeArticles to FeedSettings
  (posts and reposts default to enabled, articles disabled)
- Add 'Notes' collapsible section in ContentSettings above 'Other Stuff'
- Feed kinds are now fully dynamic from settings instead of hardcoded
- Repost unwrapping accepts any event kind, not just kind 1
- Add article (kind 30023) card rendering with title, image, and summary
- Update all feed hooks for consistency (useFeed, useProfileFeed,
  useStreamPosts, DomainFeedPage, HashtagPage)
2026-02-21 00:36:58 -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 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 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
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
shakespeare.diy e7277c6fee Revert to 5fd4ff4: Enable NIP-85 stats mode by default
This reverts the codebase back to the state at commit 5fd4ff4.

Reverted 1 commit(s):
- a3d2492: Add three-mode stats calculation: NIP-85 Only, Manual Only, and Both

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-19 04:50:50 -06:00
shakespeare.diy a3d24927d4 Add three-mode stats calculation: NIP-85 Only, Manual Only, and Both
Replace the binary nip85OnlyMode boolean with a statsMode enum that supports three options:
- "nip85-only": Show only pre-computed NIP-85 stats (fastest, may be empty)
- "manual-only": Always calculate stats from relay queries (slower, guaranteed)
- "both": Use NIP-85 when available with manual fallback (recommended default)

Updated components:
- AppContext: Changed nip85OnlyMode to statsMode with StatsMode type
- AppProvider: Updated Zod schema to validate three-mode enum
- useTrending.ts: Implemented logic for all three modes in useEventStats and useBatchEventStats
- AdvancedSettings: Replaced switch with radio group for better UX

Default remains "nip85-only" for optimal performance.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-19 04:50:07 -06:00
Chad Curtis 4a27abb021 Add NIP-85 only mode and improve settings UX
- Add nip85OnlyMode setting to disable manual stat calculation fallback
- When enabled, stats only show if NIP-85 pubkey provides them (no fallback queries)
- Allow clearing NIP-85 pubkey to disable it entirely (empty string now valid)
- Update Zod schema to accept empty string or 64-char hex pubkey
- Match ContentSettings presentation style (no boxes, simple switches)
- Show toast notifications when enabling/disabling NIP-85 only mode
- Disable NIP-85 only mode toggle when no pubkey is configured
- Update useEventStats and useBatchEventStats to respect nip85OnlyMode
2026-02-19 04:35:18 -06:00
Chad Curtis 8a4ea45035 Add NIP-85 stats integration with fallback to manual calculation
- Add nip85StatsPubkey to AppConfig (default: 5f68e85ee174102ca8978eef302129f081f03456c884185d5ec1c1224ab633ea)
- Create useNip85Stats hook for querying NIP-85 events (kinds 30382, 30383, 30384)
- Update useEventInteractions to fetch NIP-85 event stats and reduce query limits when available
- Update useComments to fetch NIP-85 stats for events and addressable events
- Add NIP-85 Stats Source section to Advanced Settings with pubkey input field
- Falls back to manual stats calculation when NIP-85 events are not available
2026-02-19 04:25:30 -06:00
shakespeare.diy 41cdf72bab Remove all theme transitions - apply instantly
- Strip out View Transitions API and RAF complexity
- Just apply theme class change synchronously
- Debounce still prevents signer spam
- Let browser handle the paint naturally

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-18 03:38:49 -06:00
shakespeare.diy 62d5625adb Use View Transitions API and double RAF for smooth theme changes
- Use native View Transitions API when available for smooth theme switch
- Fall back to manual transitions with double requestAnimationFrame
- Double RAF ensures theme change happens after browser paint cycle
- Prevents glitching even when React re-renders from signer prompt

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-18 03:37:18 -06:00
shakespeare.diy faef42481d Add smooth CSS transition for theme changes
- Apply 300ms transition to background and text colors during theme switch
- Prevents jarring flash when signer prompt appears
- Transition removed after completion to avoid affecting other animations

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-18 03:36:35 -06:00
shakespeare.diy a167c878ca Add separate App Relays section with toggle in settings
- Add `useAppRelays` boolean option to AppConfig
- Define APP_RELAYS constant with default app relays:
  - wss://relay.ditto.pub
  - wss://relay.primal.net
  - wss://relay.damus.io
- Update NostrProvider to use getEffectiveRelays() which merges
  app relays with user relays when useAppRelays is true
- Redesign RelayListManager with two sections:
  - App Relays: Read-only list with enable/disable toggle
  - Your Relays: User's personal NIP-65 relay list (editable)
- User relays now stored separately from app relays in config
- Default config starts with empty user relays and useAppRelays=true

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 22:58:47 -06:00
shakespeare.diy c938b75887 Add sub-options for Treasures feed settings (geocaches & found logs)
- Split Treasures into two sub-kinds: Geocaches (kind 37516) and Found Logs (kind 7516)
- Add `showTreasureGeocaches`, `showTreasureFoundLogs`, `feedIncludeTreasureGeocaches`, `feedIncludeTreasureFoundLogs` to FeedSettings
- Extend ExtraKindDef with optional `subKinds` array for nested settings
- Update FeedSettingsForm to render nested sub-kind toggles under parent entries
- Update useStreamKind to accept single kind or array of kinds
- Create TreasuresPage that filters kinds based on sub-kind settings
- Add getPageKinds() utility for resolving sub-kind-aware page kinds

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 19:56:57 -06:00
shakespeare.diy 769c179d1a feat: add Follow Packs to feed options
- Add kind 39089 (starter packs) to EXTRA_KINDS with sidebar/feed toggles
- Create FollowPackContent component for NoteCard rendering with title,
  description, member count badge, cover image, and avatar stack preview
- Add kind dispatch in NoteCard for 39089 and 30000
- Add /packs route using KindFeedPage
- Add PartyPopper icon in sidebar and feed settings
- Default showPacks to true so it appears in sidebar

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 19:26:10 -06:00
shakespeare.diy c7718f7a1f Add Feed settings tab with sidebar link and feed content toggles
- Add FeedSettings to AppConfig for persisting user preferences
- Create Settings > Feed tab with two sections:
  - Sidebar Links: toggle visibility of Vines, Polls, Treasures, Colors in nav
  - Feed Content: include these kinds in Follows/Global feeds
- Update LeftSidebar and MobileBottomNav to conditionally render nav items
- Update useFeed hook to include extra kinds (1068 Polls, 3367 Colors,
  34236 Vines, 37516 Treasures) based on feed settings
- Add routes for /polls, /treasures, /colors (placeholder pages)
- Vines enabled in sidebar by default; all others off by default

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 05:12:24 -06:00
shakespeare.diy 1004f86415 Fix theme selector and logo display issues
- Show current theme name and icon in dropdown trigger button
- Fix light theme not working (update class removal from 'mew' to 'dark')
- Remove opacity from logo in pink theme (keep full visibility)
- Logo now only uses opacity in light theme (70%)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 00:14:55 -06:00