8 changed files with 118 additions and 67 deletions
@ -1,56 +0,0 @@ |
|||||||
import { canonicalZapStreamWatchUrl } from '@/lib/zap-stream-url' |
|
||||||
import { cn } from '@/lib/utils' |
|
||||||
import { useContentPolicyOptional } from '@/providers/ContentPolicyProvider' |
|
||||||
import { useLayoutEffect, useMemo, useState } from 'react' |
|
||||||
import ExternalLink from '../ExternalLink' |
|
||||||
import LazyMediaTapPlaceholder from '../MediaPlayer/LazyMediaTapPlaceholder' |
|
||||||
|
|
||||||
export default function ZapStreamEmbeddedPlayer({ |
|
||||||
url, |
|
||||||
className, |
|
||||||
mustLoad = false |
|
||||||
}: { |
|
||||||
url: string |
|
||||||
className?: string |
|
||||||
mustLoad?: boolean |
|
||||||
}) { |
|
||||||
const contentPolicy = useContentPolicyOptional() |
|
||||||
const autoLoadMedia = contentPolicy?.autoLoadMedia ?? true |
|
||||||
const [userClickedLoad, setUserClickedLoad] = useState(false) |
|
||||||
const embedSrc = useMemo(() => canonicalZapStreamWatchUrl(url), [url]) |
|
||||||
const showEmbed = mustLoad || autoLoadMedia || userClickedLoad |
|
||||||
|
|
||||||
useLayoutEffect(() => { |
|
||||||
if (!autoLoadMedia) setUserClickedLoad(false) |
|
||||||
}, [autoLoadMedia]) |
|
||||||
|
|
||||||
if (!embedSrc) { |
|
||||||
return <ExternalLink url={url} /> |
|
||||||
} |
|
||||||
|
|
||||||
if (!mustLoad && !showEmbed) { |
|
||||||
return ( |
|
||||||
<LazyMediaTapPlaceholder |
|
||||||
src={embedSrc} |
|
||||||
mediaKind="video" |
|
||||||
onActivate={() => setUserClickedLoad(true)} |
|
||||||
className={cn('aspect-video max-h-[min(70vh,28rem)]', className)} |
|
||||||
/> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
return ( |
|
||||||
<iframe |
|
||||||
title="zap.stream" |
|
||||||
src={embedSrc} |
|
||||||
className={cn( |
|
||||||
'not-prose rounded-lg border w-full max-w-[400px] aspect-video max-h-[min(70vh,28rem)]', |
|
||||||
className |
|
||||||
)} |
|
||||||
allow="autoplay; encrypted-media; fullscreen; clipboard-write" |
|
||||||
allowFullScreen |
|
||||||
loading="lazy" |
|
||||||
referrerPolicy="no-referrer-when-downgrade" |
|
||||||
/> |
|
||||||
) |
|
||||||
} |
|
||||||
@ -0,0 +1,31 @@ |
|||||||
|
import { EmbeddedNote } from '@/components/Embedded/EmbeddedNote' |
||||||
|
import ExternalLink from '@/components/ExternalLink' |
||||||
|
import { naddrFromZapStreamWatchUrl } from '@/lib/zap-stream-url' |
||||||
|
import { cn } from '@/lib/utils' |
||||||
|
import type { Event } from 'nostr-tools' |
||||||
|
|
||||||
|
/** zap.stream `/naddr1…` → fetch kind 30311 and render as embedded note (LiveEvent), not a full-site iframe. */ |
||||||
|
export default function ZapStreamLiveEventEmbed({ |
||||||
|
url, |
||||||
|
className, |
||||||
|
containingEvent, |
||||||
|
showFull |
||||||
|
}: { |
||||||
|
url: string |
||||||
|
className?: string |
||||||
|
containingEvent?: Event |
||||||
|
showFull?: boolean |
||||||
|
}) { |
||||||
|
const naddr = naddrFromZapStreamWatchUrl(url) |
||||||
|
if (!naddr) { |
||||||
|
return <ExternalLink url={url} className={cn('not-prose', className)} /> |
||||||
|
} |
||||||
|
return ( |
||||||
|
<EmbeddedNote |
||||||
|
noteId={naddr} |
||||||
|
className={cn('not-prose', className)} |
||||||
|
containingEvent={containingEvent} |
||||||
|
showFull={showFull} |
||||||
|
/> |
||||||
|
) |
||||||
|
} |
||||||
Loading…
Reference in new issue