diff --git a/src/main/index.ts b/src/main/index.ts index 4730d63..d70f2a2 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -13,6 +13,7 @@ import { ICON_PATH } from "../shared/paths"; import { DATA_DIR } from "./constants"; import { createFirstLaunchTour } from "./firstLaunch"; import { createWindows, mainWin } from "./mainWindow"; +import { registerScreenShareHandler } from "./screenShare"; import { Settings } from "./settings"; if (IS_DEV) { @@ -51,6 +52,7 @@ function init() { if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop"); else if (process.platform === "darwin") app.dock.setIcon(ICON_PATH); + registerScreenShareHandler(); bootstrap(); app.on("activate", () => { diff --git a/src/main/screenShare.ts b/src/main/screenShare.ts new file mode 100644 index 0000000..d0bdc1e --- /dev/null +++ b/src/main/screenShare.ts @@ -0,0 +1,40 @@ +/* + * 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 { desktopCapturer, session } from "electron"; + +export function registerScreenShareHandler() { + session.defaultSession.setDisplayMediaRequestHandler(async (request, callback) => { + const sources = await desktopCapturer.getSources({ + types: ["window", "screen"], + thumbnailSize: { + width: 176, + height: 99 + } + }); + + const data = sources.map(({ id, name, thumbnail }) => ({ + id, + name, + url: thumbnail.toDataURL() + })); + + const choice = await request.frame + .executeJavaScript(`VencordDesktop.Components.ScreenShare.openScreenSharePicker(${JSON.stringify(data)})`) + .catch(() => "cancelled"); + + if (choice === "cancelled") { + callback({}); + return; + } + + const source = sources.find(s => s.id === choice); + callback({ + video: source, + audio: "loopback" + }); + }); +} diff --git a/src/renderer/components/ScreenSharePicker.tsx b/src/renderer/components/ScreenSharePicker.tsx new file mode 100644 index 0000000..bea0e7c --- /dev/null +++ b/src/renderer/components/ScreenSharePicker.tsx @@ -0,0 +1,193 @@ +/* + * 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 "./screenSharePicker.css"; + +import { Modals, openModal } from "@vencord/types/utils"; +import { Button, Card, Forms, Switch, Text, useState } from "@vencord/types/webpack/common"; +import { Dispatch, SetStateAction } from "react"; + +const StreamResolutions = ["720", "1080", "1440", "Source"] as const; +const StreamFps = ["15", "30", "60"] as const; + +export type StreamResolution = (typeof StreamResolutions)[number]; +export type StreamFps = (typeof StreamFps)[number]; + +interface StreamSettings { + resolution: StreamResolution; + fps: StreamFps; + audio: boolean; +} + +interface Source { + id: string; + name: string; + url: string; +} + +export function openScreenSharePicker(screens: Source[]) { + return new Promise((resolve, reject) => { + openModal(props => ( + { + props.onClose(); + reject(new Error("Aborted")); + }} + /> + )); + }); +} + +function ScreenPicker({ screens, onPick }: { screens: Source[]; onPick: (id: string) => void; }) { + return ( +
+ {screens.map(({ id, name, url }) => ( + + ))} +
+ ); +} + +function StreamSettings({ + source, + settings, + setSettings +}: { + source: Source; + settings: StreamSettings; + setSettings: Dispatch>; +}) { + return ( +
+ What you're streaming + + + {source.name} + + + Stream Settings + + +
+
+ Resolution +
+ {StreamResolutions.map(res => ( + + ))} +
+
+ +
+ Frame Rate +
+ {StreamFps.map(fps => ( + + ))} +
+
+
+ + setSettings(s => ({ ...s, audio: checked }))} + hideBorder + className="vcd-screen-picker-audio" + > + Stream With Audio + +
+
+ ); +} + +function ModalComponent({ + screens, + modalProps, + submit, + close +}: { + screens: Source[]; + modalProps: any; + submit: (id: string) => void; + close: () => void; +}) { + const [selected, setSelected] = useState(); + const [settings, setSettings] = useState({ + resolution: "1080", + fps: "60", + audio: true + }); + + return ( + + + Screen Picker + + + + + {!selected ? ( + + ) : ( + s.id === selected)!} + settings={settings} + setSettings={setSettings} + /> + )} + + + + + + {selected ? ( + + ) : ( + + )} + + + ); +} diff --git a/src/renderer/components/index.ts b/src/renderer/components/index.ts index ab7b2da..f921a98 100644 --- a/src/renderer/components/index.ts +++ b/src/renderer/components/index.ts @@ -4,4 +4,5 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ +export * as ScreenShare from "./ScreenSharePicker"; export { default as Settings } from "./Settings"; diff --git a/src/renderer/components/screenSharePicker.css b/src/renderer/components/screenSharePicker.css new file mode 100644 index 0000000..7186462 --- /dev/null +++ b/src/renderer/components/screenSharePicker.css @@ -0,0 +1,114 @@ +.vcd-screen-picker-modal { + padding: 1em; +} + +.vcd-screen-picker-grid { 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; + cursor: pointer; +} + +.vcd-screen-picker-grid label:hover { + outline: 2px solid var(--brand-experiment); +} + + +.vcd-screen-picker-grid div { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-align: center; + font-weight: 600; + margin-inline: 0.5em; +} + +.vcd-screen-picker-card { + padding: 0.5em; + box-sizing: border-box; +} + +.vcd-screen-picker-preview img { + width: 100%; + height: 100%; +} + +.vcd-screen-picker-preview { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; +} + +.vcd-screen-picker-radio input { + display: none; +} + +.vcd-screen-picker-radio { + background-color: var(--background-secondary); + border: 1px solid var(--primary-800); + padding: 0.3em; + cursor: pointer; +} + +.vcd-screen-picker-radio h2 { + margin: 0; +} + +.vcd-screen-picker-radio[data-checked="true"] { + background-color: var(--brand-experiment); + border-color: var(--brand-experiment); +} + +.vcd-screen-picker-radio[data-checked="true"] h2 { + color: var(--interactive-active); +} + +.vcd-screen-picker-quality { + display: flex; + gap: 1em; + + margin-bottom: 0.5em; +} + +.vcd-screen-picker-quality section { + flex: 1 1 auto; +} + +.vcd-screen-picker-radios { + display: flex; + width: 100%; + border-radius: 3px; +} + +.vcd-screen-picker-radios label { + flex: 1 1 auto; + text-align: center; +} + +.vcd-screen-picker-radios label:first-child { + border-radius: 3px 0 0 3px; +} + +.vcd-screen-picker-radios label:last-child { + border-radius: 0 3px 3px 0; +} + +.vcd-screen-picker-audio { + margin-bottom: 0; +} diff --git a/src/renderer/index.ts b/src/renderer/index.ts index bc1de64..8d1442d 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -5,7 +5,6 @@ */ import "./fixes"; -import "./screenshare"; console.log("read if cute :3"); diff --git a/src/renderer/screenshare/ScreenPicker.tsx b/src/renderer/screenshare/ScreenPicker.tsx deleted file mode 100644 index 74ea760..0000000 --- a/src/renderer/screenshare/ScreenPicker.tsx +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 deleted file mode 100644 index a3d1203..0000000 --- a/src/renderer/screenshare/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 deleted file mode 100644 index 91f668c..0000000 --- a/src/renderer/screenshare/styles.css +++ /dev/null @@ -1,29 +0,0 @@ -.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; -}