fix: allow multiple YouTube embeds to render in a single note
Two issues prevented multiple YouTube URLs from rendering: 1. YOUTUBE_URL_REGEX and X_URL_REGEX had the global flag, causing stateful lastIndex to skip matches on alternating calls. 2. Each YouTube Player overwrote window.onYouTubeIframeAPIReady, so only the last mounted player received the callback. Replace with a shared callback queue via ensureYTApi(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2b97adfdca
commit
2fbbe6ce1d
2 changed files with 30 additions and 14 deletions
|
|
@ -4,6 +4,30 @@ import mediaManager from '@/services/media-manager.service'
|
|||
import { YouTubePlayer } from '@/types/youtube'
|
||||
import { memo, useEffect, useRef, useState } from 'react'
|
||||
|
||||
let ytApiReady = false
|
||||
const ytApiCallbacks: (() => void)[] = []
|
||||
|
||||
function ensureYTApi(callback: () => void) {
|
||||
if (ytApiReady && window.YT?.Player) {
|
||||
callback()
|
||||
return
|
||||
}
|
||||
|
||||
ytApiCallbacks.push(callback)
|
||||
|
||||
if (!document.querySelector('script[src="https://www.youtube.com/iframe_api"]')) {
|
||||
const script = document.createElement('script')
|
||||
script.src = 'https://www.youtube.com/iframe_api'
|
||||
document.body.appendChild(script)
|
||||
|
||||
window.onYouTubeIframeAPIReady = () => {
|
||||
ytApiReady = true
|
||||
ytApiCallbacks.forEach((cb) => cb())
|
||||
ytApiCallbacks.length = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface PlayerProps {
|
||||
videoId: string
|
||||
isShort: boolean
|
||||
|
|
@ -25,19 +49,11 @@ const Player = memo(({ videoId, isShort, className }: PlayerProps) => {
|
|||
|
||||
if (!videoId || !containerRef.current) return
|
||||
|
||||
if (!window.YT) {
|
||||
const script = document.createElement('script')
|
||||
script.src = 'https://www.youtube.com/iframe_api'
|
||||
document.body.appendChild(script)
|
||||
|
||||
window.onYouTubeIframeAPIReady = () => {
|
||||
if (!unmountedRef.current) {
|
||||
initPlayer()
|
||||
}
|
||||
ensureYTApi(() => {
|
||||
if (!unmountedRef.current) {
|
||||
initPlayer()
|
||||
}
|
||||
} else {
|
||||
initPlayer()
|
||||
}
|
||||
})
|
||||
|
||||
let checkMutedInterval: NodeJS.Timeout | null = null
|
||||
function initPlayer() {
|
||||
|
|
|
|||
|
|
@ -142,9 +142,9 @@ export const LN_INVOICE_REGEX = /(ln(?:bc|tb|bcrt))([0-9]+[munp]?)?1([02-9ac-hj-
|
|||
export const EMOJI_REGEX =
|
||||
/[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F900}-\u{1F9FF}]|[\u{1FA70}-\u{1FAFF}]|[\u{1F004}]|[\u{1F0CF}]|[\u{1F18E}]|[\u{3030}]|[\u{2B50}]|[\u{2B55}]|[\u{2934}-\u{2935}]|[\u{2B05}-\u{2B07}]|[\u{2B1B}-\u{2B1C}]|[\u{3297}]|[\u{3299}]|[\u{303D}]|[\u{00A9}]|[\u{00AE}]|[\u{2122}]|[\u{23E9}-\u{23EF}]|[\u{23F0}]|[\u{23F3}]|[\u{FE00}-\u{FE0F}]|[\u{200D}]/gu
|
||||
export const YOUTUBE_URL_REGEX =
|
||||
/https?:\/\/(?:(?:www|m)\.)?(?:youtube\.com\/(?:watch\?[^#\s]*|embed\/[\w-]+|shorts\/[\w-]+|live\/[\w-]+)|youtu\.be\/[\w-]+)(?:\?[^#\s]*)?(?:#[^\s]*)?/gi
|
||||
/https?:\/\/(?:(?:www|m)\.)?(?:youtube\.com\/(?:watch\?[^#\s]*|embed\/[\w-]+|shorts\/[\w-]+|live\/[\w-]+)|youtu\.be\/[\w-]+)(?:\?[^#\s]*)?(?:#[^\s]*)?/i
|
||||
export const X_URL_REGEX =
|
||||
/https?:\/\/(?:www\.)?(twitter\.com|x\.com)\/(?:#!\/)?(\w+)\/status(?:es)?\/(\d+)(?:[?#].*)?/gi
|
||||
/https?:\/\/(?:www\.)?(twitter\.com|x\.com)\/(?:#!\/)?(\w+)\/status(?:es)?\/(\d+)(?:[?#].*)?/i
|
||||
|
||||
export const JUMBLE_PUBKEY = 'f4eb8e62add1340b9cadcd9861e669b2e907cea534e0f7f3ac974c11c758a51a'
|
||||
export const CODY_PUBKEY = '8125b911ed0e94dbe3008a0be48cfe5cd0c0b05923cfff917ae7e87da8400883'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue