fix(events): keep event-detail ticket counts live after a purchase #119

Merged
padreug merged 1 commit from feat/event-detail-live-ticket-count into dev 2026-06-18 12:44:10 +00:00

View file

@ -19,19 +19,12 @@ export function useEventDetail(eventId: string) {
) )
async function load() { async function load() {
// Already in cache
if (event.value) return
const nostrService = tryInjectService<EventsNostrService>(SERVICE_TOKENS.EVENTS_NOSTR_SERVICE) const nostrService = tryInjectService<EventsNostrService>(SERVICE_TOKENS.EVENTS_NOSTR_SERVICE)
if (!nostrService) { if (!nostrService) {
error.value = 'Events service not available' error.value = 'Events service not available'
return return
} }
try {
isLoading.value = true
error.value = null
// Scope both the subscription and the one-shot query to this // Scope both the subscription and the one-shot query to this
// event's d-tag. Without this scope, the query asks every // event's d-tag. Without this scope, the query asks every
// relay for every kind-31922/31923 event and races a 5s timeout // relay for every kind-31922/31923 event and races a 5s timeout
@ -39,6 +32,15 @@ export function useEventDetail(eventId: string) {
// even when the event is reachable. // even when the event is reachable.
const detailFilters = { dTags: [eventId] } const detailFilters = { dTags: [eventId] }
// Subscribe for LIVE updates regardless of cache state. NIP-52
// calendar events are replaceable, so when the events extension
// republishes after a ticket sells (updating tickets_sold /
// tickets_available — see events services.py), the new version
// arrives here and the reactive `event` (and its ticket counts)
// updates without a reload. Subscribing only on a cache miss meant
// arriving from the feed (event already cached) left the detail
// page with no live subscription, so counts went stale until reload.
if (unsubscribe) unsubscribe() // avoid leaking a sub if load() re-runs
unsubscribe = nostrService.subscribeToCalendarEvents( unsubscribe = nostrService.subscribeToCalendarEvents(
(incoming) => { (incoming) => {
store.upsertEvent(incoming) store.upsertEvent(incoming)
@ -49,6 +51,14 @@ export function useEventDetail(eventId: string) {
detailFilters detailFilters
) )
// Already cached — the subscription above keeps it fresh; skip the
// one-shot query + loading state.
if (event.value) return
try {
isLoading.value = true
error.value = null
const results = await nostrService.queryCalendarEvents(detailFilters) const results = await nostrService.queryCalendarEvents(detailFilters)
store.upsertEvents(results) store.upsertEvents(results)