feat(plugin): PictureInPicture (#1697)

Co-authored-by: V <vendicated@riseup.net>
This commit is contained in:
Hugo C 2023-09-08 03:57:44 +02:00 committed by GitHub
parent 885c75fdaa
commit 4c9996d620
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 1 deletions

@ -0,0 +1,83 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2023 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
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.{0,10}children:\[(\i),/,
replace: "$&$1&&$self.renderPiPButton(),"
},
},
],
renderPiPButton: ErrorBoundary.wrap(() => {
return (
<Tooltip text="Toggle Picture in Picture">
{tooltipProps => (
<div
{...tooltipProps}
role="button"
style={{
cursor: "pointer",
paddingTop: "4px",
paddingLeft: "4px",
paddingRight: "4px",
}}
onClick={e => {
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;
}}
>
<svg width="24px" height="24px" viewBox="0 0 24 24">
<path
fill="var(--interactive-normal)"
d="M21 3a1 1 0 0 1 1 1v7h-2V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h18zm0 10a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1h-8a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h8zm-1 2h-6v4h6v-4z"
/>
</svg>
</div>
)}
</Tooltip>
);
}, { noop: true })
});

@ -355,6 +355,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
name: "bb010g", name: "bb010g",
id: 72791153467990016n, id: 72791153467990016n,
}, },
Lumap: {
name: "lumap",
id: 635383782576357407n
},
Dolfies: { Dolfies: {
name: "Dolfies", name: "Dolfies",
id: 852892297661906993n, id: 852892297661906993n,
@ -362,7 +366,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
RuukuLada: { RuukuLada: {
name: "RuukuLada", name: "RuukuLada",
id: 119705748346241027n, id: 119705748346241027n,
}, }
} satisfies Record<string, Dev>); } satisfies Record<string, Dev>);
// iife so #__PURE__ works correctly // iife so #__PURE__ works correctly