aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/pictureInPicture/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/pictureInPicture/index.tsx')
-rw-r--r--src/plugins/pictureInPicture/index.tsx83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/plugins/pictureInPicture/index.tsx b/src/plugins/pictureInPicture/index.tsx
new file mode 100644
index 0000000..d10d42f
--- /dev/null
+++ b/src/plugins/pictureInPicture/index.tsx
@@ -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,!(\i).{0,7}children:\[(\i),/,
+ replace: "$&$1&&$2&&$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 })
+});