/** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { PanelBody, SelectControl } from '@wordpress/components'; import { useEntityProp } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; import { useEffect } from '@wordpress/element'; /** * Internal dependencies */ import { getDefaultEmbed, getEmbedOptions, isEmbedValid, normalizeSource, OUTPUT_AUDIO, } from './helpers'; import Stack from '../stack'; export function PlayerSection( { withPanel = true } ) { const postType = useSelect( ( select ) => select( 'core/editor' ).getCurrentPostType(), [] ); // `useEntityProp` yields undefined meta until the post entity record is hydrated. const [ rawMeta, setMeta ] = useEntityProp( 'postType', postType, 'meta' ); const meta = rawMeta ?? {}; const source = normalizeSource( meta.beyondwords_source ); const output = meta.beyondwords_output || OUTPUT_AUDIO; const stored = meta.beyondwords_embed; // Unset → default to the first asset so the player shows ("None" is the // opt-out; the v7.0.0 migration converts legacy `beyondwords_disabled` posts). const embed = stored || getDefaultEmbed( source, output ); const embedOptions = getEmbedOptions( source, output ); const setEmbed = ( value ) => { setMeta( { ...meta, beyondwords_embed: value } ); }; // Never write meta on mount: an unset value already means "show", and a // mount-time write races the other panels' preselect writes (e.g. Generate audio). // Only a stale value lands here — None is valid for every combination. useEffect( () => { if ( stored && ! isEmbedValid( stored, source, output ) ) { setEmbed( getDefaultEmbed( source, output ) ); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ source, output ] ); const field = ( ); // Document/pre-publish panels render the field without nesting another panel. if ( ! withPanel ) { return { field }; } return ( { field } ); } export default PlayerSection;