fix(events): keep event-detail ticket counts live after a purchase #119
1 changed files with 30 additions and 20 deletions
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue