Browse Source

update carousel when live-stream is hidden/revealed

imwald
Silberengel 2 weeks ago
parent
commit
85128d795d
  1. 20
      src/lib/live-activities.test.ts
  2. 22
      src/lib/live-activities.ts

20
src/lib/live-activities.test.ts

@ -35,6 +35,26 @@ describe('liveActivityAddressFromEvent', () => {
['title', 'X'] ['title', 'X']
], pk) ], pk)
expect(liveActivityAddressFromEvent(ev)).toBe(`30311:${pk}:my-stream`) expect(liveActivityAddressFromEvent(ev)).toBe(`30311:${pk}:my-stream`)
expect(parseLiveActivityEvent(ev, new Set())?.address).toBe(`30311:${pk}:my-stream`)
})
it('matches parseLiveActivityEvent address when d tag has surrounding spaces (raw d)', () => {
const pk = 'a'.repeat(64)
const ev = base(
30312,
[
['d', ' spaced-room '],
['room', 'R'],
['status', 'open'],
['service', 'https://meet.example/r/abc']
],
pk
)
const addr = liveActivityAddressFromEvent(ev)
const parsed = parseLiveActivityEvent(ev, new Set())
expect(parsed).not.toBeNull()
expect(addr).toBe(parsed!.address)
expect(addr).toBe(`30312:${pk}: spaced-room `)
}) })
it('returns null without d tag', () => { it('returns null without d tag', () => {

22
src/lib/live-activities.ts

@ -38,13 +38,14 @@ export const LIVE_ACTIVITY_KINDS = [30311, 30312, 30313] as const
/** /**
* Stable NIP-33 address `kind:pubkey:d` for a live-activity replaceable event (carousel dedupe / user hide list). * Stable NIP-33 address `kind:pubkey:d` for a live-activity replaceable event (carousel dedupe / user hide list).
* Must match {@link parseLiveActivityEvent} `address` and {@link dedupeLatestForLiveTicker} keys exactly
* (raw `d` tag value from the event, same as {@link firstTagValue}).
*/ */
export function liveActivityAddressFromEvent(ev: Event): string | null { export function liveActivityAddressFromEvent(ev: Event): string | null {
if (!LIVE_ACTIVITY_KINDS.includes(ev.kind as (typeof LIVE_ACTIVITY_KINDS)[number])) return null if (!LIVE_ACTIVITY_KINDS.includes(ev.kind as (typeof LIVE_ACTIVITY_KINDS)[number])) return null
for (const t of ev.tags) { const dTag = firstTagValue(ev, 'd')
if (t[0] === 'd' && t[1]?.trim()) return `${ev.kind}:${ev.pubkey}:${t[1].trim()}` if (!dTag) return null
} return `${ev.kind}:${ev.pubkey}:${dTag}`
return null
} }
const LIVE_ACTIVITIES_MAX_ITEMS = 10 const LIVE_ACTIVITIES_MAX_ITEMS = 10
@ -518,9 +519,8 @@ function dedupeEventsById(events: Event[]): Event[] {
function dedupeLatestForLiveTicker(events: Event[]): Map<string, Event> { function dedupeLatestForLiveTicker(events: Event[]): Map<string, Event> {
const byAddress = new Map<string, Event>() const byAddress = new Map<string, Event>()
for (const ev of events) { for (const ev of events) {
const d = firstTagValue(ev, 'd') const addr = liveActivityAddressFromEvent(ev)
if (!d) continue if (!addr) continue
const addr = `${ev.kind}:${ev.pubkey}:${d}`
const prev = byAddress.get(addr) const prev = byAddress.get(addr)
if (!prev || ev.created_at > prev.created_at) { if (!prev || ev.created_at > prev.created_at) {
byAddress.set(addr, ev) byAddress.set(addr, ev)
@ -534,9 +534,8 @@ function parent30312MapFromEvents(events: Event[]): Map<string, Event> {
const m = new Map<string, Event>() const m = new Map<string, Event>()
for (const ev of events) { for (const ev of events) {
if (ev.kind !== 30312) continue if (ev.kind !== 30312) continue
const d = firstTagValue(ev, 'd') const addr = liveActivityAddressFromEvent(ev)
if (!d) continue if (!addr) continue
const addr = `30312:${ev.pubkey}:${d}`
const prev = m.get(addr) const prev = m.get(addr)
if (!prev || ev.created_at > prev.created_at) m.set(addr, ev) if (!prev || ev.created_at > prev.created_at) m.set(addr, ev)
} }
@ -615,7 +614,8 @@ export function parseLiveActivityEvent(
const summary = firstTagValue(ev, 'summary')?.trim() || '' const summary = firstTagValue(ev, 'summary')?.trim() || ''
const image = firstTagValue(ev, 'image') const image = firstTagValue(ev, 'image')
const imageUrl = image?.startsWith('https://') ? image : undefined const imageUrl = image?.startsWith('https://') ? image : undefined
const address = `${ev.kind}:${ev.pubkey}:${dTag}` const address = liveActivityAddressFromEvent(ev)
if (!address) return null
return { return {
address, address,
kind: ev.kind, kind: ev.kind,

Loading…
Cancel
Save