358358 let pipIgnoreMediaControlEvent = false ;
359359 let pipLastFrameAt = 0 ;
360360 let pipWindowResizeFallbackActive = false ;
361+ let pipNeedsPopupForLyrics = false ;
361362
362363 // ------------------------
363364 // Constants & Configuration
16471648 if ( activeIndex > 0 ) {
16481649 blocks . push ( {
16491650 texts : prevTexts . length ? prevTexts : ( fallbackPrev ? [ fallbackPrev ] : [ ] ) ,
1650- color : 'rgba(255, 255, 255, 0.45) ' ,
1651+ color : 'white ' ,
16511652 primaryFont : `${ contextFontSize } px sans-serif` ,
16521653 primaryLineHeight : contextLineHeight ,
16531654 kind : 'context'
16631664 if ( activeIndex < currentSyncedLyrics . length - 1 ) {
16641665 blocks . push ( {
16651666 texts : nextTexts . length ? nextTexts : ( fallbackNext ? [ fallbackNext ] : [ ] ) ,
1666- color : 'rgba(255, 255, 255, 0.45) ' ,
1667+ color : 'white ' ,
16671668 primaryFont : `${ contextFontSize } px sans-serif` ,
16681669 primaryLineHeight : contextLineHeight ,
16691670 kind : 'context'
17101711 pipCtx . font = `${ Math . round ( activeFontSize * 0.6 ) } px sans-serif` ;
17111712 pipCtx . fillStyle = 'rgba(255, 255, 255, 0.6)' ;
17121713 pipCtx . fillText ( 'Open popup for full lyrics' , centerX , centerY + Math . round ( activeFontSize * 0.6 ) , textMaxWidth ) ;
1714+ } else if ( pipNeedsPopupForLyrics ) {
1715+ pipCtx . font = `bold ${ activeFontSize } px sans-serif` ;
1716+ pipCtx . fillStyle = 'white' ;
1717+ pipCtx . fillText ( 'Open Lyrics+ popup' , centerX , centerY - Math . round ( activeFontSize * 0.8 ) , textMaxWidth ) ;
1718+ pipCtx . font = `${ Math . round ( activeFontSize * 0.6 ) } px sans-serif` ;
1719+ pipCtx . fillStyle = 'rgba(255, 255, 255, 0.6)' ;
1720+ pipCtx . fillText ( 'to resume lyric updates' , centerX , centerY + Math . round ( activeFontSize * 0.6 ) , textMaxWidth ) ;
17131721 } else {
17141722 pipCtx . font = `bold ${ activeFontSize } px sans-serif` ;
17151723 pipCtx . fillStyle = 'rgba(255, 255, 255, 0.7)' ;
@@ -4336,6 +4344,7 @@ const Providers = {
43364344
43374345 function removePopup ( ) {
43384346 DEBUG . ui . popupRemoved ( ) ;
4347+ const wasPipActive = isPipActive || isPagePipActive ;
43394348
43404349 if ( isPagePipActive && pipVideo ) {
43414350 closePagePipFallback ( ) ;
@@ -4353,6 +4362,11 @@ const Providers = {
43534362 DEBUG . debug ( 'Cleanup' , 'pollingInterval cleared' ) ;
43544363 }
43554364
4365+ if ( wasPipActive ) {
4366+ currentLyricsContainer = null ;
4367+ pipNeedsPopupForLyrics = true ;
4368+ }
4369+
43564370 if ( pipVideo && ! isPipActive && ! isPagePipActive ) {
43574371 pipVideo . removeEventListener ( 'play' , handlePipVideoPlay ) ;
43584372 pipVideo . removeEventListener ( 'pause' , handlePipVideoPause ) ;
@@ -4491,9 +4505,10 @@ const Providers = {
44914505 popup . _playPauseObserver = ResourceManager . registerObserver ( observer , 'Play/pause button state' ) ;
44924506 }
44934507
4494- function createPopup ( ) {
4495- DEBUG . ui . popupCreated ( ) ;
4496- removePopup ( ) ;
4508+ function createPopup ( ) {
4509+ DEBUG . ui . popupCreated ( ) ;
4510+ removePopup ( ) ;
4511+ pipNeedsPopupForLyrics = false ;
44974512
44984513 // Clear current provider so no provider is highlighted while searching for lyrics
44994514 Providers . current = null ;
@@ -7216,10 +7231,11 @@ const Providers = {
72167231 console . log ( ` 📦 Source: ${ providerDisplay } (previously fetched)` ) ;
72177232 DEBUG . log ( 'Cache' , `Loading lyrics from cache for: ${ info . title } - ${ info . artist } ` ) ;
72187233
7219- currentLyricsContainer = lyricsContainer ;
7220- currentSyncedLyrics = cachedData . synced ;
7221- currentUnsyncedLyrics = cachedData . unsynced ;
7222- currentLyricsMetadata = cachedData . metadata || null ; // Restore metadata from cache
7234+ currentLyricsContainer = lyricsContainer ;
7235+ currentSyncedLyrics = cachedData . synced ;
7236+ currentUnsyncedLyrics = cachedData . unsynced ;
7237+ pipNeedsPopupForLyrics = false ;
7238+ currentLyricsMetadata = cachedData . metadata || null ; // Restore metadata from cache
72237239
72247240 // Reset translation state
72257241 translationPresent = false ;
@@ -7344,13 +7360,14 @@ const Providers = {
73447360 return true ;
73457361 }
73467362
7347- async function updateLyricsContent ( popup , info , cachedResult = null ) {
7363+ async function updateLyricsContent ( popup , info , cachedResult = null ) {
73487364 if ( ! info ) return ;
73497365 const lyricsContainer = popup . querySelector ( "#lyrics-plus-content" ) ;
73507366 if ( ! lyricsContainer ) return ;
7351- currentLyricsContainer = lyricsContainer ;
7352- currentSyncedLyrics = null ;
7353- currentUnsyncedLyrics = null ;
7367+ currentLyricsContainer = lyricsContainer ;
7368+ pipNeedsPopupForLyrics = false ;
7369+ currentSyncedLyrics = null ;
7370+ currentUnsyncedLyrics = null ;
73547371 // Reset translation state when loading new lyrics
73557372 translationPresent = false ;
73567373 transliterationPresent = false ;
@@ -7794,10 +7811,11 @@ const Providers = {
77947811 Providers . current = null ;
77957812 if ( popup . _lyricsTabs ) updateTabs ( popup . _lyricsTabs , true ) ;
77967813
7797- const lyricsContainer = popup . querySelector ( "#lyrics-plus-content" ) ;
7798- if ( lyricsContainer ) lyricsContainer . textContent = "No lyrics found from any provider" ;
7799- currentSyncedLyrics = null ;
7800- currentLyricsContainer = lyricsContainer ;
7814+ const lyricsContainer = popup . querySelector ( "#lyrics-plus-content" ) ;
7815+ if ( lyricsContainer ) lyricsContainer . textContent = "No lyrics found from any provider" ;
7816+ currentSyncedLyrics = null ;
7817+ currentLyricsContainer = lyricsContainer ;
7818+ pipNeedsPopupForLyrics = false ;
78017819 // Reset translation state when no lyrics are found
78027820 translationPresent = false ;
78037821 transliterationPresent = false ;
@@ -7807,11 +7825,24 @@ const Providers = {
78077825 DEBUG . warn ( 'Autodetect' , `No lyrics found after checking all providers (${ totalDuration . toFixed ( 2 ) } ms)` ) ;
78087826 }
78097827
7810- function startPollingForTrackChange ( popup ) {
7811- if ( pollingInterval ) clearInterval ( pollingInterval ) ;
7812- pollingInterval = setInterval ( ( ) => {
7813- const info = getCurrentTrackInfo ( ) ;
7814- if ( ! info ) return ;
7828+ function startPollingForTrackChange ( popup ) {
7829+ if ( pollingInterval ) clearInterval ( pollingInterval ) ;
7830+ pollingInterval = setInterval ( ( ) => {
7831+ const livePopup = document . getElementById ( "lyrics-plus-popup" ) ;
7832+ const activePopup = ( popup && popup . isConnected ) ? popup : livePopup ;
7833+ if ( isPipActive && ! activePopup ) {
7834+ currentLyricsContainer = null ;
7835+ pipNeedsPopupForLyrics = true ;
7836+ } else if ( activePopup ) {
7837+ const activeContainer = activePopup . querySelector ( "#lyrics-plus-content" ) ;
7838+ if ( activeContainer ) {
7839+ currentLyricsContainer = activeContainer ;
7840+ pipNeedsPopupForLyrics = false ;
7841+ }
7842+ }
7843+
7844+ const info = getCurrentTrackInfo ( ) ;
7845+ if ( ! info ) return ;
78157846
78167847 // Get current playback position
78177848 const posEl = document . querySelector ( '[data-testid="playback-position"]' ) ;
@@ -7843,14 +7874,16 @@ const Providers = {
78437874 }
78447875
78457876 // Track changed to a different song
7846- if ( info . id !== currentTrackId ) {
7847- DEBUG . track . changed ( currentTrackId , info . id , info ) ;
7848- currentTrackId = info . id ;
7849- lastPlaybackPosition = 0 ;
7850- lastTrackDuration = info . duration || 0 ;
7851- const lyricsContainer = popup . querySelector ( "#lyrics-plus-content" ) ;
7852- if ( lyricsContainer ) lyricsContainer . textContent = "Loading lyrics..." ;
7853- autodetectProviderAndLoad ( popup , info ) ;
7877+ if ( info . id !== currentTrackId ) {
7878+ DEBUG . track . changed ( currentTrackId , info . id , info ) ;
7879+ currentTrackId = info . id ;
7880+ lastPlaybackPosition = 0 ;
7881+ lastTrackDuration = info . duration || 0 ;
7882+ const lyricsContainer = activePopup ? activePopup . querySelector ( "#lyrics-plus-content" ) : null ;
7883+ if ( lyricsContainer ) lyricsContainer . textContent = "Loading lyrics..." ;
7884+ if ( activePopup ) {
7885+ autodetectProviderAndLoad ( activePopup , info ) ;
7886+ }
78547887 }
78557888
78567889 if ( isPipActive ) {
@@ -7861,22 +7894,22 @@ const Providers = {
78617894 lastPlaybackPosition = currentPosition ;
78627895
78637896 // Update all button states using DOM-cloned icons from Spotify's visible buttons
7864- if ( popup && popup . _playPauseBtn ) {
7865- updatePlayPauseButton ( popup . _playPauseBtn . button , popup . _playPauseBtn . iconWrapper ) ;
7866- }
7867- if ( popup && popup . _shuffleBtn ) {
7868- updateShuffleButton ( popup . _shuffleBtn . button , popup . _shuffleBtn . iconWrapper ) ;
7869- }
7870- if ( popup && popup . _repeatBtn ) {
7871- updateRepeatButton ( popup . _repeatBtn . button , popup . _repeatBtn . iconWrapper ) ;
7872- }
7873- // Update prev/next button icons from Spotify's DOM
7874- if ( popup && popup . _prevBtn ) {
7875- updatePreviousButtonIcon ( popup . _prevBtn . iconWrapper ) ;
7876- }
7877- if ( popup && popup . _nextBtn ) {
7878- updateNextButtonIcon ( popup . _nextBtn . iconWrapper ) ;
7879- }
7897+ if ( activePopup && activePopup . _playPauseBtn ) {
7898+ updatePlayPauseButton ( activePopup . _playPauseBtn . button , activePopup . _playPauseBtn . iconWrapper ) ;
7899+ }
7900+ if ( activePopup && activePopup . _shuffleBtn ) {
7901+ updateShuffleButton ( activePopup . _shuffleBtn . button , activePopup . _shuffleBtn . iconWrapper ) ;
7902+ }
7903+ if ( activePopup && activePopup . _repeatBtn ) {
7904+ updateRepeatButton ( activePopup . _repeatBtn . button , activePopup . _repeatBtn . iconWrapper ) ;
7905+ }
7906+ // Update prev/next button icons from Spotify's DOM
7907+ if ( activePopup && activePopup . _prevBtn ) {
7908+ updatePreviousButtonIcon ( activePopup . _prevBtn . iconWrapper ) ;
7909+ }
7910+ if ( activePopup && activePopup . _nextBtn ) {
7911+ updateNextButtonIcon ( activePopup . _nextBtn . iconWrapper ) ;
7912+ }
78807913 } , TIMING . POLLING_INTERVAL_MS ) ;
78817914 }
78827915
0 commit comments