Commit Graph

2756 Commits

Author SHA1 Message Date
filemon 60747de33c Clean up first-hatch tour: real loading state, dev naming, reveal centering
- Wire real companionsFetching prop into BlobbiDashboard and pass it to
  useFirstHatchTourActivation instead of hardcoded isLoading: false
- Rename skipPostRequirement to skipToEggGlow in both BlobbiPage and
  BlobbiDevEditor (no post requirement exists in the simplified flow)
- Update dev button labels: 'Skip to Glow', 'Restart Tour',
  'Reset to Egg + Tour' with accurate titles/descriptions
- Handle async resetTour consistently with void in all onClick handlers
- Fix reveal overlay centering: move rays/glow/particles inside the
  Blobbi visual container (relative positioning) instead of a separate
  viewport-centered absolute layer, so the composition is anchored to
  the Blobbi regardless of header/naming section height
2026-04-03 20:22:17 -03:00
filemon f408f2424f Remove localStorage from first hatch tour; use profile tag as sole persisted truth
- Rewrite useFirstHatchTour to use pure in-memory useState instead of
  useLocalStorage. The Kind 11125 profile tag blobbi_first_hatch_tour_done
  is now the only persisted completion signal. Refreshing mid-tour simply
  re-enters the tour if activation conditions are still met.
- Remove TourPersistedState, FirstHatchTourPersistedState, and
  FIRST_HATCH_TOUR_DEFAULT_STATE from tour-types (no longer needed).
- Remove pubkey parameter from useFirstHatchTour (no localStorage to scope).
- Remove profileOnboardingDone from activation input (unused after
  localStorage removal; blobbi_first_hatch_tour_done is the only check).
- Make dev reset (Restart Tour button) also republish the Kind 11125
  profile with blobbi_first_hatch_tour_done=false so the tour can
  immediately re-activate for testing.
2026-04-03 19:57:02 -03:00
filemon b132e03481 Fix first hatch tour reliability, reveal content, and stale data bugs
- User-scope tour localStorage key by pubkey so different users on the
  same device get independent tour state (fixes tour not starting)
- Set current_companion when auto-creating first egg so the Blobbi is
  immediately active as the floating companion
- Centralize generateBlobbiContent in blobbi.ts and use it in the reveal
  rename flow instead of publishing content: '' (fixes invalid event)
- Gate reveal overlay on companion.stage !== 'egg' so stale cache data
  never shows the egg visual instead of the newly hatched baby
- Remove duplicate generateBlobbiContent from useBlobbiStageTransition
  and useBlobbiDevUpdate in favor of the shared export
2026-04-03 18:56:37 -03:00
filemon 514dd82ad3 Simplify first-time Blobbi experience: auto-create profile + egg with instant hatch flow
Restructure the first Blobbi onboarding to feel instant, magical, and effortless:

- Add useFirstEggExperience hook: auto-creates Blobbonaut profile (kind 11125) and first egg (kind 31124) without any user confirmation, cost, or reroll
- Remove post-mission requirement from hatch tour (no 'show_hatch_card' step)
- Simplified tour flow: idle -> glowing -> crack stages -> opening -> hatching -> reveal
- Add BlobbiRevealOverlay: celebratory full-screen overlay after hatch with light rays, particles, and naming input
- Add 'blobbi_first_hatch_tour_done' profile tag for future-proof tour completion tracking (separate from blobbi_onboarding_done)
- Update useFirstHatchTourActivation to use the new dedicated tag
- Keep existing adoption flow intact for subsequent Blobbis
- Backward compatible: old users with blobbi_onboarding_done=true can still enter the hatch tour if they have a single unhatched egg
2026-04-03 16:01:41 -03:00
Alex Gleason 7d83273410 Simplify sidebar media query to a single useQuery with inline fallback logic 2026-04-03 00:53:45 -05:00
Alex Gleason fabcb4170d Fill profile media sidebar with kind 1 fallback when kind 20 results are sparse
When fewer than 9 media-native events (kind 20, 21, 22, etc.) are found for a
profile, perform a secondary query for kind 1 events with search:media:true and
append them to fill the remaining slots. Kind 20 events are always displayed first.
2026-04-03 00:36:44 -05:00
Alex Gleason 3e429fe0b0 Add rendering for Zapstore release (kind 30063) and asset (kind 3063) events
- New ZapstoreReleaseContent component: shows app icon/name fetched from the
  linked kind 32267, version badge, channel badge, release notes, and a
  downloads section that fetches and renders each linked kind 3063 asset
- New ZapstoreAssetContent component: shows MIME-type icon, platform/arch
  badges, file size, SHA-256 hash, commit hash, supported NIPs, and APK
  certificate hashes
- Register both kinds in NoteCard, PostDetailPage, extraKinds, CommentContext,
  ExternalContentHeader, and NotificationsPage label/icon maps
- Route kind 3063 to the Zapstore relay in NostrProvider and useEvent
- Kind 3063 is excluded from feeds (display-only on direct navigation)
2026-04-02 23:09:01 -05:00
filemon afa475ecef Allow first-hatch tour for migrated accounts with blobbi_onboarding_done=true
Older accounts had onboarding_done migrated to blobbi_onboarding_done=true
before the first-hatch tour existed. When the user has exactly 1 egg and
no baby/adult companions, skip the profileOnboardingDone gate so those
accounts can still enter the tour. The localStorage isCompleted check
still prevents re-triggering for users who already finished it.

This is a temporary migration safeguard. The long-term fix is a dedicated
blobbi_first_hatch_tour_done tag.
2026-04-03 00:34:51 -03:00
Alex Gleason a5746ee915 Merge branch 'update-hatch-action' into 'main'
Add first-hatch tour orchestration layer (state machine + activation)

See merge request soapbox-pub/ditto!153
2026-04-03 02:43:05 +00:00
filemon fa3376ac4f Remove legacy blobbi re-export wrappers and unused duplicate hooks
No imports remained pointing at the @/lib/blobbi* or @/hooks/use{ProjectedBlobbiState,BlobbisCollection,BlobbiMigration} paths.
Delete the transitional re-exports and the dead hook copies so only
src/blobbi/core/lib/ and src/blobbi/core/hooks/ remain as the single
source of truth.
2026-04-02 23:25:52 -03:00
filemon 6f0c10fe9b Address review feedback: deduplicate blobbi.ts, remove dead props and state
- Convert src/lib/blobbi*.ts files to thin re-exports from canonical
  src/blobbi/core/lib/ sources, eliminating duplicated logic
- Remove unused emoji, title, description props from TasksPanelProps
  and their call site in BlobbiMissionsModal
- Remove dead direction state from MissionSurfaceCard (was always 'right')
- Remove unused onContinue prop from FirstHatchTourCard and call site
2026-04-02 23:10:10 -03:00
Chad Curtis 2f1bf0bca5 Fix notification dot reappearing after marking as read
Remove the invalidateQueries call in markAsRead that raced with the
setQueriesData(false) update. The invalidation triggered an immediate
refetch whose queryFn closure still held the old notificationsCursor
(from a render before the settings cache update propagated). That stale
refetch re-queried the relay with the old since value, found the same
unread events, returned true, and overwrote the false just set --
causing the dot to reappear.

The setQueriesData(false) call provides the immediate UI update. The
60-second poll and real-time subscription naturally re-evaluate once
the cursor has fully propagated.
2026-04-02 20:35:09 -05:00
filemon 9be98d9a8d Merge branch 'main' into update-hatch-action 2026-04-02 20:47:21 -03:00
filemon c4dd8e7c3d Set blobbi_onboarding_done at tour completion, not at egg adoption
Adopting a first Blobbi egg should not mark onboarding as complete —
the user still needs to go through the first-hatch tutorial. Removed
the premature blobbi_onboarding_done:'true' write from adoptPreview()
in useBlobbiOnboarding.

The flag is now set to 'true' only when the first-hatch tour reaches
its final step (egg_hatching), right after the hatch mutation succeeds.
This is the correct semantic: onboarding means the full tutorial is
done, not just that the user created a profile or adopted an egg.
2026-04-02 20:40:17 -03:00
Chad Curtis 42832b72e3 Revert dialog fly-up on mobile keyboard open
The keyboard-aware repositioning of dialogs was too aggressive and broken.
Removes the CSS rule, dialog-keyboard-aware class, and global keyboard
detector mount. The useKeyboardVisible hook is preserved for ArticleEditor.
2026-04-02 18:20:56 -05:00
filemon e77436d02a Rename onboarding_done to blobbi_onboarding_done and make profile authoritative
The onboarding completion flag was stored as a generic 'onboarding_done'
tag on the kind 11125 Blobbonaut profile, while the first-hatch tour
relied solely on device-local localStorage. This caused issues with
multi-account usage on the same browser.

Changes:
- New profiles write 'blobbi_onboarding_done' (not 'onboarding_done')
- Parsing reads 'blobbi_onboarding_done' first, falls back to old tag
- Auto-migration: useBlobbonautProfileNormalization detects old tag
  and replaces it with the new one on next profile republish
- MANAGED_BLOBBONAUT_PROFILE_TAG_NAMES includes both tags so the
  merge logic can remove the old one during migration
- Tour activation now accepts profileOnboardingDone flag from the
  Blobbonaut profile as the authoritative completion source;
  localStorage remains a secondary fallback for in-progress UI state
- BlobbiPage passes profile.onboardingDone to the activation hook
2026-04-02 20:13:36 -03:00
filemon 302d7732ef Keep first-hatch card visible with completed state before advancing
When the user's hatch post is detected, the tour card now stays on
the 'show_hatch_card' step for 2 seconds showing a celebratory
completed state (large checkmark, 'Post shared!', 'Continuing in a
moment...') before auto-advancing to 'egg_glowing_waiting_click'.

Previously the effect called goTo() immediately on post detection,
so the checkmark was never visible — the card jumped straight to
the tap-egg phase.

Changes:
- BlobbiPage.tsx: wrap the goTo() in a 2s setTimeout
- FirstHatchTourCard.tsx: redesign completed state with centered
  checkmark, bold success text, and 'continuing' hint; remove the
  manual Continue button (auto-advance handles progression);
  update title/description to reflect the confirmed state
2026-04-02 19:28:05 -03:00
filemon b09b4938d2 Add lightweight collapsible sections to missions modal
Both Current Focus and Daily Bounties sections are now collapsible
via Radix Collapsible, defaulting to open. Section headers stay
visible when collapsed and show summary info at a glance:

- Current Focus: Hatch/Evolve badge + progress count (e.g. 2 / 5)
- Daily Bounties: coin progress + green dot for claimable count

A subtle animated chevron rotates on toggle. The collapsible
animation uses new collapsible-down/up keyframes added to the
Tailwind config (mirrors the existing accordion pattern but uses
--radix-collapsible-content-height).

Settings row stays non-collapsible to keep it simple.
2026-04-02 19:05:51 -03:00
filemon 0a0d6de111 Refactor missions modal to card-grid layout with expandable cards
- Add ExpandableMissionCard: shared component with compact collapsed
  state (icon + title + progress ring) and full-width expanded state
  with details, progress bar, action links, claim buttons
- Rework TasksPanel as a 2-col (3-col on sm+) grid of task cards;
  each card maps its task id to a specific lucide icon (Palette,
  Droplets, MessageSquare, Heart, UserPen, Activity)
- Rework DailyMissionsPanel as the same grid; each card maps its
  action type to an icon (Utensils, Moon, Camera, Mic, etc.)
- Only one card expanded at a time per section
- Add MissionTypeLegend popover in the header (? icon) explaining
  Daily / Hatch / Evolve mission types with color-coded dots
- Pass category prop (hatch | evolve | daily) through to cards for
  per-type accent colors (sky / violet / amber)
- Keep all existing behavior: claim, reroll, stop, CTA buttons
2026-04-02 18:47:29 -03:00
filemon 4e9b893822 Redesign missions modal with lighter quest-board aesthetic
- Remove all Collapsible wrappers; sections are always visible
- Restructure layout: Current Focus (hatch/evolve) on top, Daily
  Bounties below, settings toggle at footer
- Flatten TasksPanel: remove Card/CardHeader chrome, use minimal
  rows with soft rounded backgrounds and inline action links
- Lighten DailyMissionsPanel: compact mission rows, smaller claim
  buttons, muted claimed state, no heavy border cards
- Add empty focus state with Compass icon when no active process
- Sticky header with quest-themed subtitle
- ~100 fewer lines across the three files
2026-04-02 17:52:46 -03:00
filemon c60e87ad65 Merge branch 'main' into update-hatch-action 2026-04-02 16:49:03 -03:00
filemon b4c4b8eb21 Rename wall-specific identifiers to profile-oriented naming
- KIND_WALL_EDIT → KIND_PROFILE_TABS
- wallEditEvents → profileTabsEvents
- edit_wall task id → edit_profile
- Split completion check into hasTabsEdit / hasMetadataEdit / hasProfileEdit
2026-04-02 15:52:54 -03:00
filemon 23ee6f1196 Broaden evolve 'Edit Wall' mission to accept profile metadata edits (kind 0)
The mission now completes when the user either:
- Edits custom profile tabs (kind 16769, existing behavior)
- Updates profile metadata (kind 0, new)

Both paths require the event's created_at to be after the evolution
start timestamp (stateStartedAt), so pre-existing events won't
auto-complete the task.

Updated UI copy: 'Edit Your Profile' / 'Update your profile info or
customize your profile tabs'.
2026-04-02 15:32:36 -03:00
Alex Gleason 4b97baa428 Merge branch 'exclude-text-from-media-sidebar' into 'main'
Exclude kind 1 and kind 1111 from profile Media sidebar

See merge request soapbox-pub/ditto!152
2026-04-02 16:51:27 +00:00
Chad Curtis 205a252cac Fix slug collision check blocking edits to existing articles
Replace isEditMode guard with originalSlug comparison so the collision
check is skipped when republishing an article with the same slug it was
loaded with, but still runs if the user changes the slug to one that
would overwrite a different article.
2026-04-02 07:48:14 -05:00
Chad Curtis ad604eae68 Improve dialog UX on mobile: rounded corners, button spacing, keyboard awareness
- Add rounded-xl to Dialog and AlertDialog (was sm:rounded-lg only)
- Add consistent gap-2 to footer buttons on mobile (was no gap)
- Use w-[calc(100%-2rem)] for mobile side margins
- Push dialogs to top of viewport only when keyboard is visible via
  .keyboard-visible class on <html>, toggled by useKeyboardVisible
- Mount useKeyboardVisible globally in MainLayout so the class is
  always available for CSS-only consumers
2026-04-02 05:10:07 -05:00
Chad Curtis 57064b4f40 Save draft on blur and show cloud sync indicator
- Trigger silent draft save when title or editor loses focus
- Add onBlur prop to MilkdownEditor, wired to both WYSIWYG and source textarea
- Mark saved immediately after local write instead of waiting for relay
- Show persistent cloud icon in status; pulses while relay sync is in flight
2026-04-02 05:10:07 -05:00
Chad Curtis bb7b8da581 Always save drafts locally so they appear immediately in My Articles
Previously, drafts were only saved to localStorage on relay failure.
If the relay accepted the event but hadn't indexed it yet for queries,
the draft would show 'Saved' but not appear under My Articles. Now
we always persist locally first for instant visibility, then sync to
the relay in the background.
2026-04-02 05:10:07 -05:00
Chad Curtis 5683f6ea1e Fix source mode toggle clearing editor content
initialValueRef was only set once on mount, so toggling back from
source mode reinitialized Milkdown with stale content. Keep
initialValueRef and lastExternalValue in sync with the current value
so remounts and the replaceAll guard work correctly.
2026-04-02 05:10:07 -05:00
Chad Curtis 61c606822a Fix crash when editing in markdown source mode
The replaceAll effect tried to access editorViewCtx while in source
mode where the ProseMirror view isn't mounted, causing a 'Context
editorView not found' error. Skip the sync when sourceMode is active
and add a try/catch for the initial render race.
2026-04-02 05:10:07 -05:00
Chad Curtis bc12331cd4 Keep tab bar in article editor but make it non-sticky on mobile write mode
Add ARC_OVERHANG_PX spacer div after the header to prevent arc
overlapping content, matching the pattern used across other pages.
2026-04-02 05:10:07 -05:00
Chad Curtis 2478bf1c66 Improve mobile article editor UX when virtual keyboard is open
- Hide tab bar in write mode on mobile, replace with slim back+title header
- Hide publish FAB when keyboard is visible (was floating over content)
- Collapse metadata (summary, slug, tags) behind a 'Details' toggle on mobile
- Hide header image and stats bar when keyboard is up to maximize writing area
- Add useKeyboardVisible hook using Visual Viewport API
2026-04-02 05:10:07 -05:00
filemon ade9eb4999 Merge branch 'main' into update-hatch-action 2026-04-02 06:17:41 -03:00
Alex Gleason 681d2ab90b Merge branch 'main' of gitlab.com:soapbox-pub/ditto 2026-04-02 03:51:09 -05:00
Alex Gleason 24a645277e Fix custom emoji stretching by adding object-contain to all emoji images
Custom emoji images with non-1:1 aspect ratios were being stretched
into a square. Added object-contain to preserve natural aspect ratio
within the bounding box. Moved text sizing classes to parent containers
for reaction emoji bubbles so unicode emojis still size correctly.
2026-04-02 03:50:50 -05:00
Chad Curtis fa34922cce refactor: harden article editor — encryption, mobile UX, deduplication, source toggle
- Encrypt drafts with NIP-44 via NIP-37 (kind 31234) instead of
  plaintext kind 30024
- Fix slug auto-generation overwriting manual edits
- Guard auto-save state setters against unmount
- Deduplicate save logic, load handlers, tag extraction, and types
  via shared ArticleFields/parseArticleEvent helpers
- Replace derived state (wordCount/readingTime) with useMemo
- Mobile UX: sticky toolbar, touch-friendly header image swap,
  adaptive tooltips (pointer:fine only), FAB bottom clearance,
  responsive editor min-height
- Editor placeholder: hide on focus, handle trailing whitespace
- Tighten editor padding and paragraph spacing
- Add raw markdown source toggle (Eye/EyeOff) in toolbar
- Shrink slug/tag fields, consistent sizing
2026-04-02 03:48:10 -05:00
Chad Curtis 89c71ed073 Merge branch 'feat/article-editor' into 'main'
feat: add in-app article editor with Milkdown WYSIWYG

See merge request soapbox-pub/ditto!150
2026-04-02 08:47:37 +00:00
filemon 0f02563d3a Add mission card dismiss/toggle and fix More menu for hidden bar items
- Mission surface card now has an X dismiss button (onHide prop)
  that hides it via localStorage ('blobbi:mission-card-visible')
- BlobbiMissionsModal gains a 'Show mission card on main page'
  toggle at the bottom, reflecting the same preference
- Both controls share the same state: hiding from the card or
  toggling from the modal are equivalent
- More dropdown now conditionally shows items: if an action
  (Blobbies, Items, Missions, Photo, Companion) is visible in
  the bottom bar, it is skipped in More to avoid duplication;
  if removed from the bar, it appears in More so no action
  becomes inaccessible
2026-04-02 05:26:21 -03:00
Alex Gleason f49909dedf Close mobile drawer when clicking footer links (Changelog, Privacy) 2026-04-02 03:23:13 -05:00
Alex Gleason f93c759bf2 Fix VersionCheck crash: move VersionCheck and Toaster inside BrowserRouter
VersionCheck and Toaster were rendering outside the BrowserRouter in App.tsx,
so the <Link> in the version update toast had no Router context. Moved both
into AppRouter.tsx inside BrowserRouter. Also truncate changelog excerpt
to 60 chars with ellipsis for cleaner toast display.
2026-04-02 03:01:32 -05:00
filemon 38630be23d Add customizable bottom bar, mission surface card, and action bar editor
Bottom bar simplification:
- Default to 3 visible items: Blobbies (left), Main Action (center),
  More (right). Items/Missions/Photo moved into More dropdown.
- All existing actions (Set as Companion, Evolve/Hatch, View Blobbi,
  dev tools) remain in More with existing guards.
- 'Edit action bar' entry in More opens the new editor.

Editable action bar preferences:
- New preference model (action-bar-preferences.ts) with localStorage
  persistence, validation, and migration support.
- Candidates: Blobbies, Missions, Items, Take Photo, Set as Companion.
- Up to 3 custom visible slots (Main Action + More are fixed).
- Each slot can be shown/hidden, reordered, or highlighted.
- ActionBarEditor modal for editing with reset-to-default option.

Mission surface card:
- MissionSurfaceCard renders below the Blobbi visual, above the bar.
- Shows one mission at a time with badge (Hatch/Evolve/Daily),
  progress bar, description, and coin reward for dailies.
- Priority: hatch/evolve tasks first, then unclaimed daily missions.
- Auto-rotates every 5s when multiple cards; manual tap cycles.
- 'View all missions' link opens existing missions modal.
- Hidden during first-hatch tour (preserves tour behavior).
2026-04-02 04:55:00 -03:00
Alex Gleason 32b36b2f54 Merge branch 'main' of gitlab.com:soapbox-pub/ditto 2026-04-02 02:40:44 -05:00
Alex Gleason dee5c82fa8 Add 'deployed an nsite' action header to nsite detail page 2026-04-02 02:39:40 -05:00
Alex Gleason 22d66a28d7 Add Open App button to compact view, fix stopPropagation on all buttons 2026-04-02 02:37:13 -05:00
Alex Gleason 984a56c412 Add 'published an app' action header to app detail page 2026-04-02 02:34:14 -05:00
Alex Gleason 207e7a13a2 Move Shakespeare badge above Open App button, restore h-6 size 2026-04-02 02:25:44 -05:00
Alex Gleason cc7feebbb0 Replace small external link icon with prominent Visit Website button 2026-04-02 02:22:25 -05:00
filemon 9b8cff63da Polish first-hatch tour: center click hint over egg, keep crack visible during opening
- Move click hint emoji to centered overlay with larger size (text-4xl)
  so users clearly see it over the egg, not tucked in a corner
- Keep crack overlay visible during egg_opening state by including
  'opening' in tourShowCrack and mapping it to crack level 3
- The crack SVG lives inside the shell div, so it inherits the
  opening animation (scale/blur/fade) and disappears with the shell
- Suppress shake animation during opening so it doesn't conflict
  with the smooth open sequence
2026-04-02 04:12:00 -03:00
Alex Gleason 925619b13c Add background color to app icon for transparent images 2026-04-02 02:09:58 -05:00
Alex Gleason ceb7bbc718 Fix app icon z-index so it renders above the og:image hero 2026-04-02 02:06:41 -05:00