From 37886808a6215ae72d90a75641f3e564df753267 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 15 Apr 2023 23:40:23 +0200 Subject: [PATCH] Add screenshare capabilities --- src/main/ipc.ts | 4 +- src/preload/VencordDesktopNative.ts | 11 ++++ src/renderer/index.ts | 1 + src/renderer/screenshare/ScreenPicker.tsx | 80 +++++++++++++++++++++++ src/renderer/screenshare/index.ts | 32 +++++++++ src/renderer/screenshare/styles.css | 29 ++++++++ src/shared/IpcEvents.ts | 2 + 7 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/renderer/screenshare/ScreenPicker.tsx create mode 100644 src/renderer/screenshare/index.ts create mode 100644 src/renderer/screenshare/styles.css diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 5dc3479..e78e09e 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -4,7 +4,7 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -import { app, dialog, ipcMain, session, shell } from "electron"; +import { app, desktopCapturer, dialog, ipcMain, session, shell } from "electron"; import { existsSync, readFileSync, watch } from "fs"; import { open, readFile } from "fs/promises"; import { join } from "path"; @@ -68,6 +68,8 @@ ipcMain.handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => { if (applicable.length) ses.setSpellCheckerLanguages(applicable); }); +ipcMain.handle(IpcEvents.CAPTURER_GET_SOURCES, (_, options) => desktopCapturer.getSources(options)); + ipcMain.handle(IpcEvents.SELECT_VENCORD_DIR, async () => { const res = await dialog.showOpenDialog(mainWin!, { properties: ["openDirectory"] diff --git a/src/preload/VencordDesktopNative.ts b/src/preload/VencordDesktopNative.ts index f6b0829..b24be18 100644 --- a/src/preload/VencordDesktopNative.ts +++ b/src/preload/VencordDesktopNative.ts @@ -4,6 +4,7 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ +import type { DesktopCapturerSource, SourcesOptions } from "electron"; import type { Settings } from "shared/settings"; import type { LiteralUnion } from "type-fest"; @@ -29,5 +30,15 @@ export const VencordDesktopNative = { }, win: { focus: () => invoke(IpcEvents.FOCUS) + }, + capturer: { + getSources: async (options?: SourcesOptions) => { + const res = await invoke(IpcEvents.CAPTURER_GET_SOURCES, options); + return res.map(({ id, name, thumbnail }) => ({ + id, + name, + url: thumbnail.toDataURL() + })); + } } }; diff --git a/src/renderer/index.ts b/src/renderer/index.ts index c2c76ca..5d84cfe 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -5,6 +5,7 @@ */ import "./fixes"; +import "./screenshare"; console.log("read if cute :3"); diff --git a/src/renderer/screenshare/ScreenPicker.tsx b/src/renderer/screenshare/ScreenPicker.tsx new file mode 100644 index 0000000..74ea760 --- /dev/null +++ b/src/renderer/screenshare/ScreenPicker.tsx @@ -0,0 +1,80 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience + * Copyright (c) 2023 Vendicated and Vencord contributors + */ + +import "./styles.css"; + +import { Common, Util } from "renderer/vencord"; + +const { Modals } = Util; + +type Sources = Awaited>; + +export function openScreenPicker(screens: Sources) { + return new Promise((resolve, reject) => { + const key = Modals.openModal(props => ( + { + Modals.closeModal(key); + reject(new Error("Aborted")); + }} + /> + )); + }); +} + +function ModalComponent({ + screens, + modalProps, + submit, + close +}: { + screens: Sources; + modalProps: any; + submit: (id: string) => void; + close: () => void; +}) { + const [selected, setSelected] = Common.React.useState(screens[0]?.id); + + return ( + + + Screen Picker + + + + +
+ {screens.map(({ id, name, url }) => ( + + ))} +
+
+ + + { + submit(selected); + close(); + }} + > + Go Live + + + Cancel + + +
+ ); +} diff --git a/src/renderer/screenshare/index.ts b/src/renderer/screenshare/index.ts new file mode 100644 index 0000000..a3d1203 --- /dev/null +++ b/src/renderer/screenshare/index.ts @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience + * Copyright (c) 2023 Vendicated and Vencord contributors + */ + +import { openScreenPicker } from "./ScreenPicker"; + +navigator.mediaDevices.getDisplayMedia = async options => { + const sources = await VencordDesktopNative.capturer.getSources({ + types: ["window", "screen"], + thumbnailSize: { + width: 176, + height: 99 + } + }); + const id = await openScreenPicker(sources); + + return navigator.mediaDevices.getUserMedia({ + audio: { + mandatory: { + chromeMediaSource: "desktop" + } + }, + video: { + mandatory: { + chromeMediaSource: "desktop", + chromeMediaSourceId: id + } + } + } as any); +}; diff --git a/src/renderer/screenshare/styles.css b/src/renderer/screenshare/styles.css new file mode 100644 index 0000000..91f668c --- /dev/null +++ b/src/renderer/screenshare/styles.css @@ -0,0 +1,29 @@ +.vcd-screen-picker-grid { + padding: 1em; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2em 1em; +} + +.vcd-screen-picker-grid input { + appearance: none; + cursor: pointer; +} + +.vcd-screen-picker-selected img { + outline: 2px solid var(--brand-experiment); +} + +.vcd-screen-picker-grid label { + overflow: hidden; + padding: 4px 0px; +} + +.vcd-screen-picker-grid div { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-align: center; + font-weight: 600; + margin-inline: 0.5em; +} diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index 9d1c75f..1d0edfe 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -27,5 +27,7 @@ export const enum IpcEvents { SPELLCHECK_SET_LANGUAGES = "VCD_SPELLCHECK_SET_LANGUAGES", + CAPTURER_GET_SOURCES = "VCD_CAPTURER_GET_SOURCES", + CLOSE = "VCD_CLOSE" }