Files
eranos/src/lib/streamStatus.ts
T
Derek Ross adc370a598 Fix live streams showing as active when ended, and fix muted icon state
Implement NIP-53 staleness heuristic (24h threshold) to mark abandoned
status=live streams as ended. Fetch all streams globally and filter
follows client-side (including p-tag participants for streaming services).
Add Live/Planned/Past pill tabs to the streams strip on /videos.

Also fix pre-existing bug where the volume icon showed unmuted while the
video was actually muted (autoplay requires muted), by syncing the
initial muted state from the media element in usePlayerControls.

Closes #88
2026-03-16 16:36:54 -04:00

35 lines
1.1 KiB
TypeScript

import type { NostrEvent } from '@nostrify/nostrify';
/**
* Staleness threshold in seconds.
*
* NIP-53 suggests 1 hour, but in practice relays often serve older versions
* of addressable events (different `created_at` depending on query filters),
* which causes false positives at short thresholds. 24 hours is lenient
* enough to avoid misclassifying genuinely live streams while still catching
* streams that were abandoned without setting `status=ended`.
*/
const STALE_THRESHOLD_SECONDS = 24 * 3600; // 24 hours
/**
* Returns the effective stream status for a kind 30311 event, applying
* a staleness heuristic inspired by NIP-53: a `status=live` event whose
* `created_at` is older than 24 hours is treated as `ended`.
*
* When no status tag is present the event is treated as `ended`.
*/
export function getEffectiveStreamStatus(event: NostrEvent): string {
const status = event.tags.find(([n]) => n === 'status')?.[1] ?? 'ended';
if (status === 'live') {
const now = Math.floor(Date.now() / 1000);
if (now - event.created_at > STALE_THRESHOLD_SECONDS) {
return 'ended';
}
}
return status;
}