//Fixed context isolation version https://github.com/getferdi/ferdi/blob/develop/src/webview/screenshare.ts //original https://github.com/electron/electron/issues/16513#issuecomment-602070250 import {ipcRenderer} from "electron"; import {addStyle, addScript} from "../utils"; const desktopCapturer = { getSources: (opts: any) => ipcRenderer.invoke("DESKTOP_CAPTURER_GET_SOURCES", opts) }; const CANCEL_ID = "desktop-capturer-selection__cancel"; interface IPCSources { id: string; name: string; thumbnail: HTMLCanvasElement; } export async function getDisplayMediaSelector() { const sources: IPCSources[] = await desktopCapturer.getSources({ types: ["screen", "window"] }); return `
`; } const screenShareCSS = ` .desktop-capturer-selection { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background: rgba(30,30,30,.75); color: #FFFFFF; z-index: 10000000; display: flex; align-items: center; justify-content: center; } .desktop-capturer-selection__scroller { width: 100%; max-height: 100vh; overflow-y: auto; } .desktop-capturer-selection__list { max-width: calc(100% - 100px); margin: 50px; padding: 0; display: flex; flex-wrap: wrap; list-style: none; overflow: hidden; justify-content: center; } .desktop-capturer-selection__item { display: flex; margin: 4px; } .desktop-capturer-selection__btn { display: flex; flex-direction: column; align-items: stretch; width: 145px; margin: 0; border: 0; border-radius: 3px; padding: 4px; background: #2C2F33; text-align: left; @media (prefers-reduced-motion: no-preference) { transition: background-color .15s, box-shadow .15s, color .15s; } color: #dedede; } .desktop-capturer-selection__btn:hover, .desktop-capturer-selection__btn:focus { background: #7289DA; box-shadow: 0 0 4px rgba(0,0,0,0.45), 0 0 2px rgba(0,0,0,0.25); color: #fff; } .desktop-capturer-selection__thumbnail { width: 100%; height: 81px; object-fit: cover; } .desktop-capturer-selection__name { margin: 6px 0; white-space: nowrap; color: white; text-overflow: ellipsis; text-align: center; overflow: hidden; } .desktop-capturer-selection__name--cancel { margin: auto 0; } `; const screenShareJS = ` window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => { try { const selectionElem = document.createElement('div'); selectionElem.classList = ['desktop-capturer-selection']; selectionElem.innerHTML = await window.armcord.getDisplayMediaSelector(); document.body.appendChild(selectionElem); document .querySelectorAll('.desktop-capturer-selection__btn') .forEach((button) => { button.addEventListener('click', async () => { try { const id = button.getAttribute('data-id'); if (id === '${CANCEL_ID}') { reject(new Error('Cancelled by user')); } else { const stream = await window.navigator.mediaDevices.getUserMedia({ audio: false, video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: id, }, }, }); resolve(stream); } } catch (err) { reject(err); } finally { selectionElem.remove(); } }); }); } catch (err) { reject(err); } }); `; document.addEventListener("DOMContentLoaded", function () { addScript(screenShareJS); addStyle(screenShareCSS); console.log("Capturer injected."); });