feat(activities): event name on My tickets + organizer on cards #102

Merged
padreug merged 2 commits from feat/event-name-and-organizer into dev 2026-06-10 23:10:01 +00:00
Owner

Summary

Two related polish items for the events stack:

  • My tickets — event names instead of Event: <id>…. The grouped ticket cards on /my-tickets rendered the truncated LNbits event id as the card title (e.g. Event: Z3wbKx7w…). They now show the actual event title, sourced from the shared events store, and the title is a RouterLink to the event detail page. Subscribes to the events feed on mount so titles resolve even when a user lands on My tickets directly from a purchase flow without first visiting /events. Falls back to the old short-id label until the event arrives (or if the event was deleted upstream).

  • Organizer on every feed card + composable fix. OrganizerCard gets a compact variant (tiny avatar + display name, single line) used inside EventCard so viewers see who's hosting before tapping in. Hidden on the host's own roster (compact feed rows). Detail page keeps the original two-line layout.

    Along the way, useOrganizerProfile is rerouted through the centralized ProfileService to fix two real bugs that meant kind-0 metadata could never reach the rendered card:

    • displayName was exposed via a get accessor on the returned object; destructuring it resolved once at the destructure site, so a kind-0 arriving later never updated the bound name. Now exposed as computed<string>.
    • relayHub.subscribe() throws synchronously when the hub isn't connected yet. OrganizerCard mounting during cold start swallowed the throw silently in onMounted, leaving the user with the pubkey-truncated fallback forever. ProfileService.getProfile() awaits the relay-hub connection before issuing the filter.

    Bonus: the kind-0 cache is now shared with chat / market / nostr-feed, so a profile fetched by any module is immediately visible to all of them.

End-to-end note on display-name visibility

For the organizer name to actually populate, the LNbits side needed to broadcast kind-0 via the configured relays rather than direct-inserting into a hardcoded relay_id="test1" row. That's been fixed on the dev branch of aiolabs/lnbits (commit 2169c1b8fix(auth): broadcast kind-0 via nostrclient, not direct nostrrelay insert). After deploying that LNbits build, existing users get their kind-0 republished the next time they edit their profile through the webapp's gear popup (PATCH /api/v1/auth already calls _publish_nostr_metadata_event).

Test plan

  • On /my-tickets, ticket-group card title shows the real event name and clicking it navigates to the event detail page.
  • On /my-tickets, opening the page directly (no prior /events visit) eventually populates the names as the feed subscription warms up.
  • On the events feed, every card shows the organizer's display name + avatar once kind-0 has been received.
  • On the event detail page, the Organizer section continues to render correctly (compact prop defaults to false).
  • On the Hosting tab (compact cards), the organizer line is hidden as expected.

🤖 Generated with Claude Code

## Summary Two related polish items for the events stack: - **My tickets — event names instead of `Event: <id>…`.** The grouped ticket cards on `/my-tickets` rendered the truncated LNbits event id as the card title (e.g. `Event: Z3wbKx7w…`). They now show the actual event title, sourced from the shared events store, and the title is a `RouterLink` to the event detail page. Subscribes to the events feed on mount so titles resolve even when a user lands on My tickets directly from a purchase flow without first visiting `/events`. Falls back to the old short-id label until the event arrives (or if the event was deleted upstream). - **Organizer on every feed card + composable fix.** `OrganizerCard` gets a `compact` variant (tiny avatar + display name, single line) used inside `EventCard` so viewers see who's hosting before tapping in. Hidden on the host's own roster (compact feed rows). Detail page keeps the original two-line layout. Along the way, **`useOrganizerProfile` is rerouted through the centralized `ProfileService`** to fix two real bugs that meant kind-0 metadata could never reach the rendered card: - `displayName` was exposed via a `get` accessor on the returned object; destructuring it resolved once at the destructure site, so a kind-0 arriving later never updated the bound name. Now exposed as `computed<string>`. - `relayHub.subscribe()` throws synchronously when the hub isn't connected yet. `OrganizerCard` mounting during cold start swallowed the throw silently in `onMounted`, leaving the user with the pubkey-truncated fallback forever. `ProfileService.getProfile()` awaits the relay-hub connection before issuing the filter. Bonus: the kind-0 cache is now shared with chat / market / nostr-feed, so a profile fetched by any module is immediately visible to all of them. ## End-to-end note on display-name visibility For the organizer name to actually populate, the LNbits side needed to broadcast kind-0 via the configured relays rather than direct-inserting into a hardcoded `relay_id="test1"` row. That's been fixed on the `dev` branch of [aiolabs/lnbits](https://git.atitlan.io/aiolabs/lnbits) (commit `2169c1b8` — `fix(auth): broadcast kind-0 via nostrclient, not direct nostrrelay insert`). After deploying that LNbits build, existing users get their kind-0 republished the next time they edit their profile through the webapp's gear popup (`PATCH /api/v1/auth` already calls `_publish_nostr_metadata_event`). ## Test plan - [ ] On `/my-tickets`, ticket-group card title shows the real event name and clicking it navigates to the event detail page. - [ ] On `/my-tickets`, opening the page directly (no prior `/events` visit) eventually populates the names as the feed subscription warms up. - [ ] On the events feed, every card shows the organizer's display name + avatar once kind-0 has been received. - [ ] On the event detail page, the `Organizer` section continues to render correctly (compact prop defaults to false). - [ ] On the Hosting tab (compact cards), the organizer line is hidden as expected. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replace the "Event: <8-char-id>…" placeholder with the actual event
title, sourced from the shared events store, and wrap it in a
RouterLink to the event detail page. Card title truncates so long
names don't push the per-event ticket-count badge out of the row.

Subscribe to the events feed on mount so titles resolve as relay
events stream in — the user can land on My tickets directly from a
purchase flow without having to visit /events first to populate the
store. Falls back to the old short-id label until the event arrives
(or if it's been deleted upstream).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two changes that ship together:

- Compact variant of OrganizerCard (tiny avatar + display name on a
  single line) used on every feed EventCard so viewers see who's
  hosting before they tap into the detail page. Hidden on compact
  feed rows (host's own roster — they already know).

- Refactor useOrganizerProfile.ts to route through the centralized
  ProfileService. Two bugs the local impl was carrying:
  * `displayName` was exposed via a `get` accessor on the returned
    object; destructuring it (`const { displayName } = …`) resolved
    once at the destructure site, so a kind-0 arriving later never
    updated the bound name. Now exposed as `computed<string>`.
  * `relayHub.subscribe()` throws synchronously when the hub isn't
    connected yet. OrganizerCard mounted during cold start swallowed
    the throw silently in onMounted, leaving the user with the
    pubkey-truncated fallback forever. ProfileService.getProfile()
    awaits the relay-hub connection before issuing the filter.

  Bonus: ProfileService's kind-0 cache is shared with chat / market /
  nostr-feed, so a profile fetched by any module is immediately
  visible to all of them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
padreug deleted branch feat/event-name-and-organizer 2026-06-10 23:10:01 +00:00
Sign in to join this conversation.
No description provided.