diff --git a/packages/webamp/CHANGELOG.md b/packages/webamp/CHANGELOG.md index 1d6a58d1..184ce5ef 100644 --- a/packages/webamp/CHANGELOG.md +++ b/packages/webamp/CHANGELOG.md @@ -10,6 +10,7 @@ - `webamp.toggleShuffle` - `webamp.toggleRepeat` - Add new config option `enableMediaSession` to allow Webamp to connect to the browser's Media Session API. This enables OS/hardware level media controls like play/pause/next/previous. +- Ensure the promise returned from `renderWhenReady` only resolves after the Webamp instance has been fully mounted and inserted into the DOM. Previously it resolved after the DOM node was created but before it was inserted into the DOM. ## 2.1.2 [CURRENT] diff --git a/packages/webamp/js/components/App.tsx b/packages/webamp/js/components/App.tsx index bbf74881..28abe631 100644 --- a/packages/webamp/js/components/App.tsx +++ b/packages/webamp/js/components/App.tsx @@ -30,12 +30,19 @@ import cssText from "../../css/webamp.css?inline"; interface Props { filePickers: FilePicker[]; media: IMedia; + parentDomNode: HTMLElement; + onMount?: () => void; } /** * Constructs the windows to render */ -export default function App({ media, filePickers }: Props) { +export default function App({ + media, + filePickers, + onMount, + parentDomNode, +}: Props) { const closed = useTypedSelector(Selectors.getClosed); const genWindowsInfo = useTypedSelector(Selectors.getGenWindows); const zIndex = useTypedSelector(Selectors.getZIndex); @@ -58,11 +65,11 @@ export default function App({ media, filePickers }: Props) { }, [webampNode, zIndex]); useLayoutEffect(() => { - document.body.appendChild(webampNode); + parentDomNode.appendChild(webampNode); return () => { - document.body.removeChild(webampNode); + parentDomNode.removeChild(webampNode); }; - }, [webampNode]); + }, [webampNode, parentDomNode]); useEffect(() => { const handleWindowResize = () => { @@ -95,6 +102,12 @@ export default function App({ media, filePickers }: Props) { }; }, [browserWindowSizeChanged, webampNode]); + useEffect(() => { + if (onMount != null) { + onMount(); + } + }, [onMount]); + const renderWindows = useCallback(() => { return Utils.objectMap(genWindowsInfo, (w, id) => { if (!w.open) { diff --git a/packages/webamp/js/webampLazy.tsx b/packages/webamp/js/webampLazy.tsx index 8a4326b2..13a23f0d 100644 --- a/packages/webamp/js/webampLazy.tsx +++ b/packages/webamp/js/webampLazy.tsx @@ -101,10 +101,6 @@ class Webamp { __customMediaClass, } = this.options; - if (options.enableMediaSession) { - enableMediaSession(this); - } - // TODO: Make this much cleaner. let convertPreset = null; if (__butterchurnOptions != null) { @@ -142,6 +138,10 @@ class Webamp { } ) as Store; + if (options.enableMediaSession) { + enableMediaSession(this); + } + if (enableDoubleSizeMode) { this.store.dispatch(Actions.toggleDoubleSizeMode()); } @@ -473,11 +473,22 @@ class Webamp { } }); + let onMount: (() => void) | undefined; + const mountPromise = new Promise((resolve) => { + onMount = resolve; + }); + this._root.render( - + ); + await mountPromise; } /**