diff --git a/plugins/picture-in-picture/front.js b/plugins/picture-in-picture/front.js index 8ac8aa5775..941a4333bd 100644 --- a/plugins/picture-in-picture/front.js +++ b/plugins/picture-in-picture/front.js @@ -1,13 +1,14 @@ const { ipcRenderer } = require("electron"); -const { toKeyEvent } = require('keyboardevent-from-electron-accelerator'); -const keyEventAreEqual = require('keyboardevents-areequal'); +const { toKeyEvent } = require("keyboardevent-from-electron-accelerator"); +const keyEventAreEqual = require("keyboardevents-areequal"); const { getSongMenu } = require("../../providers/dom-elements"); const { ElementFromFile, templatePath } = require("../utils"); function $(selector) { return document.querySelector(selector); } +let useNativePiP = false; let menu = null; const pipButton = ElementFromFile( templatePath(__dirname, "picture-in-picture.html") @@ -42,8 +43,24 @@ const observer = new MutationObserver(() => { menu.prepend(pipButton); }); -global.togglePictureInPicture = () => { +global.togglePictureInPicture = async () => { + if (useNativePiP) { + const isInPiP = document.pictureInPictureElement !== null; + const video = $("video"); + const togglePiP = () => + isInPiP + ? document.exitPictureInPicture.call(document) + : video.requestPictureInPicture.call(video); + + try { + await togglePiP(); + $("#icon").click(); // Close the menu + return true; + } catch {} + } + ipcRenderer.send("picture-in-picture"); + return false; }; const listenForToggle = () => { @@ -57,11 +74,12 @@ const listenForToggle = () => { const player = $('#player'); const onPlayerDblClick = player.onDoubleClick_; - const titlebar = $('.cet-titlebar'); + const titlebar = $(".cet-titlebar"); - ipcRenderer.on('pip-toggle', (_, isPip) => { + ipcRenderer.on("pip-toggle", (_, isPip) => { if (isPip) { - replaceButton(".exit-fullscreen-button", originalExitButton).onclick = () => togglePictureInPicture(); + replaceButton(".exit-fullscreen-button", originalExitButton).onclick = + () => togglePictureInPicture(); player.onDoubleClick_ = () => {}; expandMenu.onmouseleave = () => middleControls.click(); if (!playerPage.playerPageOpen_) { @@ -69,32 +87,33 @@ const listenForToggle = () => { } fullScreenButton.click(); appLayout.classList.add("pip"); - if (titlebar) titlebar.style.display = 'none'; + if (titlebar) titlebar.style.display = "none"; } else { $(".exit-fullscreen-button").replaceWith(originalExitButton); player.onDoubleClick_ = onPlayerDblClick; expandMenu.onmouseleave = undefined; originalExitButton.click(); appLayout.classList.remove("pip"); - if (titlebar) titlebar.style.display = 'flex'; + if (titlebar) titlebar.style.display = "flex"; } }); } -function observeMenu() { +function observeMenu(options) { + useNativePiP = options.useNativePiP; document.addEventListener( "apiLoaded", () => { listenForToggle(); - // remove native listeners - cloneButton(".player-minimize-button").onclick = () => { - global.togglePictureInPicture(); - setTimeout(() => $('#player').click()); + + cloneButton(".player-minimize-button").onclick = async () => { + await global.togglePictureInPicture(); + setTimeout(() => $("#player").click()); }; // allows easily closing the menu by programmatically clicking outside of it $("#expanding-menu").removeAttribute("no-cancel-on-outside-click"); - // TODO: think about wether an additional button in songMenu is needed + // TODO: think about wether an additional button in songMenu is needed observer.observe($("ytmusic-popup-container"), { childList: true, subtree: true, @@ -105,12 +124,15 @@ function observeMenu() { } module.exports = (options) => { - observeMenu(); + observeMenu(options); if (options.hotkey) { const hotkeyEvent = toKeyEvent(options.hotkey); - window.addEventListener('keydown', (event) => { - if (keyEventAreEqual(event, hotkeyEvent) && !$('ytmusic-search-box').opened) { + window.addEventListener("keydown", (event) => { + if ( + keyEventAreEqual(event, hotkeyEvent) && + !$("ytmusic-search-box").opened + ) { togglePictureInPicture(); } }); diff --git a/plugins/picture-in-picture/menu.js b/plugins/picture-in-picture/menu.js index bdbc1ceef9..61014c228e 100644 --- a/plugins/picture-in-picture/menu.js +++ b/plugins/picture-in-picture/menu.js @@ -45,16 +45,24 @@ module.exports = (win, options) => [ }], ...promptOptions() }, win) - + if (output) { const { value, accelerator } = output[0]; setOptions({ [value]: accelerator }); - + item.checked = !!accelerator; } else { // Reset checkbox if prompt was canceled item.checked = !item.checked; } }, + }, + { + label: "Use native PiP", + type: "checkbox", + checked: options.useNativePiP, + click: (item) => { + setOptions({ useNativePiP: item.checked }); + }, } ];