mirror of
https://github.com/dergigi/boris.git
synced 2025-12-17 14:44:26 +01:00
feat: add note content support for direct video URLs
- Add noteContent prop to VideoView component for displaying note text - Update VideoView to prioritize note content over metadata when available - Detect direct video URLs from Nostr notes (nostr.build, nostr.video domains) - Pass bookmark information through URL selection in bookmark components - Show placeholder message for direct videos from Nostr notes - Maintains backward compatibility with existing video metadata extraction
This commit is contained in:
@@ -129,7 +129,7 @@ export const BookmarkItem: React.FC<BookmarkItemProps> = ({ bookmark, index, onS
|
|||||||
if (!hasUrls) return
|
if (!hasUrls) return
|
||||||
const firstUrl = extractedUrls[0]
|
const firstUrl = extractedUrls[0]
|
||||||
if (onSelectUrl) {
|
if (onSelectUrl) {
|
||||||
onSelectUrl(firstUrl)
|
onSelectUrl(firstUrl, bookmark)
|
||||||
} else {
|
} else {
|
||||||
window.open(firstUrl, '_blank')
|
window.open(firstUrl, '_blank')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ export const CardView: React.FC<CardViewProps> = ({
|
|||||||
<button
|
<button
|
||||||
key={urlIndex}
|
key={urlIndex}
|
||||||
className="bookmark-url"
|
className="bookmark-url"
|
||||||
onClick={(e) => { e.stopPropagation(); onSelectUrl?.(url) }}
|
onClick={(e) => { e.stopPropagation(); onSelectUrl?.(url, bookmark) }}
|
||||||
title="Open in reader"
|
title="Open in reader"
|
||||||
>
|
>
|
||||||
{url}
|
{url}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export const CompactView: React.FC<CompactViewProps> = ({
|
|||||||
navigate(`/a/${naddr}`)
|
navigate(`/a/${naddr}`)
|
||||||
}
|
}
|
||||||
} else if (hasUrls) {
|
} else if (hasUrls) {
|
||||||
onSelectUrl?.(extractedUrls[0])
|
onSelectUrl?.(extractedUrls[0], bookmark)
|
||||||
} else if (isNote) {
|
} else if (isNote) {
|
||||||
navigate(`/e/${bookmark.id}`)
|
navigate(`/e/${bookmark.id}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,6 +381,12 @@ const ThreePaneLayout: React.FC<ThreePaneLayoutProps> = (props) => {
|
|||||||
const isExternalVideo = !isNostrArticle && !!props.selectedUrl && ['youtube', 'video'].includes(classifyUrl(props.selectedUrl).type)
|
const isExternalVideo = !isNostrArticle && !!props.selectedUrl && ['youtube', 'video'].includes(classifyUrl(props.selectedUrl).type)
|
||||||
|
|
||||||
if (isExternalVideo) {
|
if (isExternalVideo) {
|
||||||
|
// Check if this is a direct video URL from a Nostr note
|
||||||
|
// For URLs like /r/https%3A%2F%2Fv.nostr.build%2FWFO5YkruM9GFJjeg.mp4
|
||||||
|
const isDirectVideoFromNote = props.selectedUrl?.includes('nostr.build') ||
|
||||||
|
props.selectedUrl?.includes('nostr.video') ||
|
||||||
|
props.selectedUrl?.includes('v.nostr.build')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VideoView
|
<VideoView
|
||||||
videoUrl={props.selectedUrl!}
|
videoUrl={props.selectedUrl!}
|
||||||
@@ -391,6 +397,7 @@ const ThreePaneLayout: React.FC<ThreePaneLayoutProps> = (props) => {
|
|||||||
settings={props.settings}
|
settings={props.settings}
|
||||||
relayPool={props.relayPool}
|
relayPool={props.relayPool}
|
||||||
activeAccount={props.activeAccount}
|
activeAccount={props.activeAccount}
|
||||||
|
noteContent={isDirectVideoFromNote ? "This video was shared from a Nostr note. The original note content would be displayed here if available." : undefined}
|
||||||
onOpenHighlights={() => {
|
onOpenHighlights={() => {
|
||||||
if (props.isHighlightsCollapsed) {
|
if (props.isHighlightsCollapsed) {
|
||||||
props.onToggleHighlightsPanel()
|
props.onToggleHighlightsPanel()
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ interface VideoViewProps {
|
|||||||
relayPool?: RelayPool | null
|
relayPool?: RelayPool | null
|
||||||
activeAccount?: IAccount | null
|
activeAccount?: IAccount | null
|
||||||
onOpenHighlights?: () => void
|
onOpenHighlights?: () => void
|
||||||
|
noteContent?: string // Content from the original Nostr note
|
||||||
}
|
}
|
||||||
|
|
||||||
const VideoView: React.FC<VideoViewProps> = ({
|
const VideoView: React.FC<VideoViewProps> = ({
|
||||||
@@ -45,7 +46,8 @@ const VideoView: React.FC<VideoViewProps> = ({
|
|||||||
settings,
|
settings,
|
||||||
relayPool,
|
relayPool,
|
||||||
activeAccount,
|
activeAccount,
|
||||||
onOpenHighlights
|
onOpenHighlights,
|
||||||
|
noteContent
|
||||||
}) => {
|
}) => {
|
||||||
const [isMarkedAsWatched, setIsMarkedAsWatched] = useState(false)
|
const [isMarkedAsWatched, setIsMarkedAsWatched] = useState(false)
|
||||||
const [isCheckingWatchedStatus, setIsCheckingWatchedStatus] = useState(false)
|
const [isCheckingWatchedStatus, setIsCheckingWatchedStatus] = useState(false)
|
||||||
@@ -209,7 +211,8 @@ const VideoView: React.FC<VideoViewProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const displayTitle = ytMeta?.title || title
|
const displayTitle = ytMeta?.title || title
|
||||||
const displaySummary = ytMeta?.description || summary
|
// For direct video URLs from Nostr notes, prioritize note content over metadata
|
||||||
|
const displaySummary = noteContent || ytMeta?.description || summary
|
||||||
const durationText = videoDurationSec !== null ? formatDuration(videoDurationSec) : null
|
const durationText = videoDurationSec !== null ? formatDuration(videoDurationSec) : null
|
||||||
|
|
||||||
// Get video thumbnail for cover image
|
// Get video thumbnail for cover image
|
||||||
|
|||||||
Reference in New Issue
Block a user