From d2265b59d78143cf51fe4dc3d5dee9da66873cc1 Mon Sep 17 00:00:00 2001 From: TC Date: Thu, 7 Apr 2022 20:01:29 +0200 Subject: [PATCH] Create first version of picture in picture plugin --- plugins/picture-in-picture/back.js | 58 +++++++++++++++++++ plugins/picture-in-picture/front.js | 42 ++++++++++++++ plugins/picture-in-picture/style.css | 7 +++ .../templates/picture-in-picture.html | 51 ++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 plugins/picture-in-picture/back.js create mode 100644 plugins/picture-in-picture/front.js create mode 100644 plugins/picture-in-picture/style.css create mode 100644 plugins/picture-in-picture/templates/picture-in-picture.html diff --git a/plugins/picture-in-picture/back.js b/plugins/picture-in-picture/back.js new file mode 100644 index 00000000..02ade2b9 --- /dev/null +++ b/plugins/picture-in-picture/back.js @@ -0,0 +1,58 @@ +const path = require("path"); + +const { app, ipcMain } = require("electron"); + +const { injectCSS } = require("../utils"); + +let isInPiPMode = false; +let originalPosition; +let originalSize; + +const pipPosition = [10, 10]; +const pipSize = [400, 220]; + +const togglePiP = async (win) => { + isInPiPMode = !isInPiPMode; + + if (isInPiPMode) { + injectCSS(win.webContents, path.join(__dirname, "style.css")); + + originalPosition = win.getPosition(); + originalSize = win.getSize(); + + win.setFullScreenable(false); + await win.webContents.executeJavaScript( + // Go fullscreen + `document.querySelector(".fullscreen-button").click()` + ); + + app.dock.hide(); + win.setVisibleOnAllWorkspaces(true, { + visibleOnFullScreen: true, + }); + app.dock.show(); + win.setAlwaysOnTop(true, "screen-saver", 1); + } else { + win.setFullScreenable(true); + await win.webContents.executeJavaScript( + // Exit fullscreen + `document.querySelector(".exit-fullscreen-button").click()` + ); + + win.setVisibleOnAllWorkspaces(false); + win.setAlwaysOnTop(false); + } + + const [x, y] = isInPiPMode ? pipPosition : originalPosition; + const [w, h] = isInPiPMode ? pipSize : originalSize; + win.setPosition(x, y); + win.setSize(w, h); + + win.setWindowButtonVisibility(!isInPiPMode); +}; + +module.exports = (win) => { + ipcMain.on("picture-in-picture", async () => { + await togglePiP(win); + }); +}; diff --git a/plugins/picture-in-picture/front.js b/plugins/picture-in-picture/front.js new file mode 100644 index 00000000..637c7fb6 --- /dev/null +++ b/plugins/picture-in-picture/front.js @@ -0,0 +1,42 @@ +const { ipcRenderer } = require("electron"); + +const { getSongMenu } = require("../../providers/dom-elements"); +const { ElementFromFile, templatePath } = require("../utils"); + +let menu = null; +const pipButton = ElementFromFile( + templatePath(__dirname, "picture-in-picture.html") +); + +const observer = new MutationObserver(() => { + if (!menu) { + menu = getSongMenu(); + if (!menu) return; + } + if (menu.contains(pipButton)) return; + const menuUrl = document.querySelector( + 'tp-yt-paper-listbox [tabindex="0"] #navigation-endpoint' + )?.href; + if (menuUrl && !menuUrl.includes("watch?")) return; + + menu.prepend(pipButton); +}); + +global.togglePictureInPicture = () => { + ipcRenderer.send("picture-in-picture"); +}; + +function observeMenu(options) { + document.addEventListener( + "apiLoaded", + () => { + observer.observe(document.querySelector("ytmusic-popup-container"), { + childList: true, + subtree: true, + }); + }, + { once: true, passive: true } + ); +} + +module.exports = observeMenu; diff --git a/plugins/picture-in-picture/style.css b/plugins/picture-in-picture/style.css new file mode 100644 index 00000000..de6a9ace --- /dev/null +++ b/plugins/picture-in-picture/style.css @@ -0,0 +1,7 @@ +/* Make entire window draggable */ +body { + -webkit-app-region: drag; +} +button { + -webkit-app-region: no-drag; +} diff --git a/plugins/picture-in-picture/templates/picture-in-picture.html b/plugins/picture-in-picture/templates/picture-in-picture.html new file mode 100644 index 00000000..6dd0440c --- /dev/null +++ b/plugins/picture-in-picture/templates/picture-in-picture.html @@ -0,0 +1,51 @@ +