Add screenshare capabilities
This commit is contained in:
parent
a12ba017bc
commit
37886808a6
7 changed files with 158 additions and 1 deletions
|
@ -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"]
|
||||
|
|
|
@ -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<void>(IpcEvents.FOCUS)
|
||||
},
|
||||
capturer: {
|
||||
getSources: async (options?: SourcesOptions) => {
|
||||
const res = await invoke<DesktopCapturerSource[]>(IpcEvents.CAPTURER_GET_SOURCES, options);
|
||||
return res.map(({ id, name, thumbnail }) => ({
|
||||
id,
|
||||
name,
|
||||
url: thumbnail.toDataURL()
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import "./fixes";
|
||||
import "./screenshare";
|
||||
|
||||
console.log("read if cute :3");
|
||||
|
||||
|
|
80
src/renderer/screenshare/ScreenPicker.tsx
Normal file
80
src/renderer/screenshare/ScreenPicker.tsx
Normal file
|
@ -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<ReturnType<(typeof VencordDesktopNative)["capturer"]["getSources"]>>;
|
||||
|
||||
export function openScreenPicker(screens: Sources) {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const key = Modals.openModal(props => (
|
||||
<ModalComponent
|
||||
screens={screens}
|
||||
modalProps={props}
|
||||
submit={resolve}
|
||||
close={() => {
|
||||
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 (
|
||||
<Modals.ModalRoot {...modalProps}>
|
||||
<Modals.ModalHeader>
|
||||
<Common.Forms.FormTitle tag="h2">Screen Picker</Common.Forms.FormTitle>
|
||||
<Modals.ModalCloseButton onClick={close} />
|
||||
</Modals.ModalHeader>
|
||||
|
||||
<Modals.ModalContent>
|
||||
<div className="vcd-screen-picker-grid">
|
||||
{screens.map(({ id, name, url }) => (
|
||||
<label key={id} className={selected === id ? "vcd-screen-picker-selected" : ""}>
|
||||
<input type="radio" name="screen" value={id} onChange={() => setSelected(id)} />
|
||||
|
||||
<img src={url} alt="" />
|
||||
<Common.Forms.Text variant="text-sm/normal">{name}</Common.Forms.Text>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</Modals.ModalContent>
|
||||
|
||||
<Modals.ModalFooter>
|
||||
<Common.Button
|
||||
disabled={!selected}
|
||||
onClick={() => {
|
||||
submit(selected);
|
||||
close();
|
||||
}}
|
||||
>
|
||||
Go Live
|
||||
</Common.Button>
|
||||
<Common.Button color={Common.Button.Colors.TRANSPARENT} onClick={close}>
|
||||
Cancel
|
||||
</Common.Button>
|
||||
</Modals.ModalFooter>
|
||||
</Modals.ModalRoot>
|
||||
);
|
||||
}
|
32
src/renderer/screenshare/index.ts
Normal file
32
src/renderer/screenshare/index.ts
Normal file
|
@ -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);
|
||||
};
|
29
src/renderer/screenshare/styles.css
Normal file
29
src/renderer/screenshare/styles.css
Normal file
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
|
|
Reference in a new issue