/* * Vencord, a Discord client mod * Copyright (c) 2023 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import "./styles.css"; import { definePluginSettings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { React, Tooltip } from "@webpack/common"; const settings = definePluginSettings({ loop: { description: "Whether to make the PiP video loop or not", type: OptionType.BOOLEAN, default: true, restartNeeded: false } }); export default definePlugin({ name: "PictureInPicture", description: "Adds picture in picture to videos (next to the Download button)", authors: [Devs.Lumap], settings, patches: [ { find: ".onRemoveAttachment,", replacement: { match: /\.nonMediaAttachment,!(\i).{0,7}children:\[(\i),/, replace: "$&$1&&$2&&$self.renderPiPButton()," }, }, ], renderPiPButton: ErrorBoundary.wrap(() => { return ( {tooltipProps => (
{ const video = e.currentTarget.parentNode!.parentNode!.querySelector("video")!; const videoClone = document.body.appendChild(video.cloneNode(true)) as HTMLVideoElement; videoClone.loop = settings.store.loop; videoClone.style.display = "none"; videoClone.onleavepictureinpicture = () => videoClone.remove(); function launchPiP() { videoClone.currentTime = video.currentTime; videoClone.requestPictureInPicture(); video.pause(); videoClone.play(); } if (videoClone.readyState === 4 /* HAVE_ENOUGH_DATA */) launchPiP(); else videoClone.onloadedmetadata = launchPiP; }} >
)}
); }, { noop: true }) });