@wordpress/block-library
Version:
Block library for the WordPress editor.
8 lines (7 loc) • 9.84 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/playlist/view.js"],
"sourcesContent": ["import { store, getContext, getElement } from '@wordpress/interactivity';\nimport {\n\tinitWaveformPlayer,\n\tlogPlayError,\n\tsetupPlayButtonArtwork,\n\tupdateSeekControlLabel,\n} from '../utils/waveform-utils';\n\n/**\n * Store player state for each element.\n */\nconst playerState = new WeakMap();\nconst playlistPlayerState = new Map();\n\nconst { state } = store(\n\t'core/playlist',\n\t{\n\t\tstate: {\n\t\t\tplaylists: {},\n\t\t\tget isCurrentTrack() {\n\t\t\t\tconst { currentId, trackId } = getContext();\n\t\t\t\treturn currentId === trackId;\n\t\t\t},\n\t\t\tget isCurrentTrackPlaying() {\n\t\t\t\tconst { currentId, isPlaying, trackId } = getContext();\n\t\t\t\treturn currentId === trackId && !! isPlaying;\n\t\t\t},\n\t\t\tget trackButtonActionLabel() {\n\t\t\t\tconst { labelPauseTrack, labelSelectTrack } = getContext();\n\t\t\t\treturn state.isCurrentTrackPlaying\n\t\t\t\t\t? labelPauseTrack\n\t\t\t\t\t: labelSelectTrack;\n\t\t\t},\n\t\t},\n\t\tactions: {\n\t\t\tchangeTrack() {\n\t\t\t\tconst context = getContext();\n\t\t\t\tif ( context.currentId === context.trackId ) {\n\t\t\t\t\tconst player = playlistPlayerState.get(\n\t\t\t\t\t\tcontext.playlistId\n\t\t\t\t\t)?.instance;\n\t\t\t\t\tif ( player?.isPlaying ) {\n\t\t\t\t\t\tcontext.isPlaying = false;\n\t\t\t\t\t\tplayer.pause();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tplayer?.play()?.catch( logPlayError );\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontext.isPlaying = false;\n\t\t\t\tcontext.currentId = context.trackId;\n\t\t\t},\n\t\t},\n\t\tcallbacks: {\n\t\t\tinitWaveformPlayer() {\n\t\t\t\tconst context = getContext();\n\t\t\t\tconst { ref } = getElement();\n\n\t\t\t\tif ( ! context.currentId || ! ref ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst track =\n\t\t\t\t\tstate.playlists[ context.playlistId ]?.tracks[\n\t\t\t\t\t\tcontext.currentId\n\t\t\t\t\t];\n\t\t\t\tif ( ! track?.url ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst existing = playerState.get( ref );\n\n\t\t\t\t// Skip if we already initialized with this exact URL.\n\t\t\t\tif ( existing?.url === track.url ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Autoplay if we're switching from a different track (user action),\n\t\t\t\t// but not on initial page load (when existing has no URL).\n\t\t\t\tconst shouldAutoPlay = !! existing?.url;\n\n\t\t\t\tinitPlayer( ref, track, shouldAutoPlay, context );\n\t\t\t},\n\t\t},\n\t},\n\t{ lock: true }\n);\n\n/**\n * Initialize the waveform player for a given element.\n *\n * @param {Element} ref - The container element.\n * @param {Object} track - The track data.\n * @param {boolean} shouldAutoPlay - Whether to auto-play after initialization.\n * @param {Object} context - The Interactivity API context.\n */\nfunction initPlayer( ref, track, shouldAutoPlay, context ) {\n\tconst existing = playerState.get( ref );\n\tconst showPlayButtonArtwork = context.showPlayButtonArtwork === true;\n\tconst playerArtwork = showPlayButtonArtwork ? '' : track.image;\n\n\t// If a player already exists, load the new track without recreating.\n\tif ( existing?.instance ) {\n\t\tconst shouldRecreatePlayer =\n\t\t\t!! existing.instance.artworkEl !== !! playerArtwork;\n\n\t\tif ( shouldRecreatePlayer ) {\n\t\t\texisting.destroy?.();\n\t\t\tplayerState.delete( ref );\n\t\t} else {\n\t\t\tplaylistPlayerState.set( context.playlistId, existing );\n\t\t\texisting.instance\n\t\t\t\t.loadTrack( track.url, track.title, track.artist, {\n\t\t\t\t\tartwork: playerArtwork,\n\t\t\t\t\tartworkAlt: playerArtwork ? track.imageAlt : '',\n\t\t\t\t} )\n\t\t\t\t.then( () => {\n\t\t\t\t\texisting.url = track.url;\n\t\t\t\t\tif ( existing.instance.artworkEl ) {\n\t\t\t\t\t\texisting.instance.artworkEl.alt = track.imageAlt || '';\n\t\t\t\t\t}\n\t\t\t\t\t// loadTrack() preserves the previous explicit seekLabel option.\n\t\t\t\t\tupdateSeekControlLabel(\n\t\t\t\t\t\texisting.instance,\n\t\t\t\t\t\ttrack.title || ref.dataset.labelSeek\n\t\t\t\t\t);\n\t\t\t\t\tif ( showPlayButtonArtwork ) {\n\t\t\t\t\t\tsetupPlayButtonArtwork(\n\t\t\t\t\t\t\texisting.container,\n\t\t\t\t\t\t\ttrack.image\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif ( shouldAutoPlay ) {\n\t\t\t\t\t\texisting.instance.play()?.catch( logPlayError );\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.catch( logPlayError );\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Read translated labels from server-rendered data attributes.\n\tconst labels = {\n\t\tplay: ref.dataset.labelPlay,\n\t\tpause: ref.dataset.labelPause,\n\t\tseek: ref.dataset.labelSeek,\n\t\tseekValueText: ref.dataset.labelSeekValue,\n\t};\n\n\t// Initialize using the shared core.\n\tconst player = initWaveformPlayer( ref, {\n\t\tsrc: track.url,\n\t\ttitle: track.title,\n\t\tartist: track.artist,\n\t\timage: track.image,\n\t\timageAlt: track.imageAlt,\n\t\twaveformColor: ref.dataset.waveformPlayerColor,\n\t\twaveformGradient: ref.dataset.waveformPlayerGradient,\n\t\tbackgroundColor: ref.dataset.waveformPlayerBackgroundColor,\n\t\tbackgroundGradient: ref.dataset.waveformPlayerBackgroundGradient,\n\t\tautoPlay: shouldAutoPlay,\n\t\tlabels,\n\t\twaveformStyle: context.waveformStyle,\n\t\tshowPlayButtonArtwork,\n\t\tonEnded: () => {\n\t\t\t// Advance to next track (autoPlay handles playback).\n\t\t\tconst currentIndex = context.tracks.findIndex(\n\t\t\t\t( trackId ) => trackId === context.currentId\n\t\t\t);\n\t\t\tconst nextTrack = context.tracks[ currentIndex + 1 ];\n\t\t\tif ( nextTrack ) {\n\t\t\t\tcontext.currentId = nextTrack;\n\t\t\t}\n\t\t},\n\t} );\n\tconst setIsPlaying = ( isPlaying ) => {\n\t\tcontext.isPlaying = isPlaying;\n\t};\n\tconst onPlay = () => setIsPlaying( true );\n\tconst onPause = () => setIsPlaying( false );\n\tplayer.container.addEventListener( 'waveformplayer:play', onPlay );\n\tplayer.container.addEventListener( 'waveformplayer:pause', onPause );\n\tplayer.container.addEventListener( 'waveformplayer:ended', onPause );\n\tconst destroy = () => {\n\t\tplayer.container.removeEventListener( 'waveformplayer:play', onPlay );\n\t\tplayer.container.removeEventListener( 'waveformplayer:pause', onPause );\n\t\tplayer.container.removeEventListener( 'waveformplayer:ended', onPause );\n\t\tplayer.destroy();\n\t};\n\n\t// Store state for cleanup, including instance for loadTrack reuse.\n\tconst nextState = {\n\t\turl: track.url,\n\t\tinstance: player.instance,\n\t\tcontainer: player.container,\n\t\tdestroy,\n\t};\n\tplayerState.set( ref, nextState );\n\tplaylistPlayerState.set( context.playlistId, nextState );\n}\n"],
"mappings": "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",
"names": []
}