diff --git a/src/modules/activities/composables/useActivityDetail.ts b/src/modules/activities/composables/useActivityDetail.ts index e29a272..9fc3ce4 100644 --- a/src/modules/activities/composables/useActivityDetail.ts +++ b/src/modules/activities/composables/useActivityDetail.ts @@ -32,18 +32,24 @@ export function useActivityDetail(activityId: string) { isLoading.value = true error.value = null - // Subscribe and wait for this specific event + // Scope both the subscription and the one-shot query to this + // activity's d-tag. Without this scope, the query asks every + // relay for every kind-31922/31923 event and races a 5s timeout + // to find ours — on a cold page refresh that race is often lost + // even when the activity is reachable. + const detailFilters = { dTags: [activityId] } + unsubscribe = nostrService.subscribeToCalendarEvents( (incoming) => { store.upsertActivity(incoming) if (incoming.id === activityId) { isLoading.value = false } - } + }, + detailFilters ) - // Also do a one-shot query - const results = await nostrService.queryCalendarEvents() + const results = await nostrService.queryCalendarEvents(detailFilters) store.upsertActivities(results) // If we still don't have it after query, stop loading diff --git a/src/modules/activities/services/ActivitiesNostrService.ts b/src/modules/activities/services/ActivitiesNostrService.ts index 0b0a00e..4883910 100644 --- a/src/modules/activities/services/ActivitiesNostrService.ts +++ b/src/modules/activities/services/ActivitiesNostrService.ts @@ -23,6 +23,8 @@ export interface CalendarEventFilters { hashtags?: string[] /** Filter by geohash prefix (NIP-52 'g' tag) */ geohash?: string + /** Filter by NIP-52 'd' tag — scopes the query to specific parameterized-replaceable events */ + dTags?: string[] } /** @@ -148,6 +150,7 @@ export class ActivitiesNostrService extends BaseService { if (filters?.authors?.length) filter.authors = filters.authors if (filters?.hashtags?.length) filter['#t'] = filters.hashtags if (filters?.geohash) filter['#g'] = [filters.geohash] + if (filters?.dTags?.length) filter['#d'] = filters.dTags return [filter] }