aboutsummaryrefslogtreecommitdiffstats
path: root/src/webview/screenshare.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/webview/screenshare.js')
-rw-r--r--src/webview/screenshare.js91
1 files changed, 44 insertions, 47 deletions
diff --git a/src/webview/screenshare.js b/src/webview/screenshare.js
index 84d2e1e95..e7e43c04e 100644
--- a/src/webview/screenshare.js
+++ b/src/webview/screenshare.js
@@ -2,6 +2,33 @@ import { desktopCapturer } from 'electron';
2 2
3const CANCEL_ID = 'desktop-capturer-selection__cancel'; 3const CANCEL_ID = 'desktop-capturer-selection__cancel';
4 4
5export async function getDisplayMediaSelector() {
6 const sources = await desktopCapturer.getSources({
7 types: ['screen', 'window'],
8 });
9 return `<div class="desktop-capturer-selection__scroller">
10 <ul class="desktop-capturer-selection__list">
11 ${sources
12 .map(
13 ({ id, name, thumbnail }) => `
14 <li class="desktop-capturer-selection__item">
15 <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}">
16 <img class="desktop-capturer-selection__thumbnail" src="${thumbnail.toDataURL()}" />
17 <span class="desktop-capturer-selection__name">${name}</span>
18 </button>
19 </li>
20 `,
21 )
22 .join('')}
23 <li class="desktop-capturer-selection__item">
24 <button class="desktop-capturer-selection__btn" data-id="${CANCEL_ID}" title="Cancel">
25 <span class="desktop-capturer-selection__name desktop-capturer-selection__name--cancel">Cancel</span>
26 </button>
27 </li>
28 </ul>
29</div>`;
30}
31
5export const screenShareCss = ` 32export const screenShareCss = `
6.desktop-capturer-selection { 33.desktop-capturer-selection {
7 position: fixed; 34 position: fixed;
@@ -46,7 +73,9 @@ export const screenShareCss = `
46 padding: 4px; 73 padding: 4px;
47 background: #252626; 74 background: #252626;
48 text-align: left; 75 text-align: left;
49 transition: background-color .15s, box-shadow .15s, color .15s; 76 @media (prefers-reduced-motion: no-preference) {
77 transition: background-color .15s, box-shadow .15s, color .15s;
78 }
50 color: #dedede; 79 color: #dedede;
51} 80}
52.desktop-capturer-selection__btn:hover, 81.desktop-capturer-selection__btn:hover,
@@ -72,38 +101,12 @@ export const screenShareCss = `
72} 101}
73`; 102`;
74 103
75// Patch getDisplayMedia for screen sharing 104export const screenShareJs = `
76window.navigator.mediaDevices.getDisplayMedia = () => async (resolve, reject) => { 105window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => {
77 try { 106 try {
78 const sources = await desktopCapturer.getSources({
79 types: ['screen', 'window'],
80 });
81
82 const selectionElem = document.createElement('div'); 107 const selectionElem = document.createElement('div');
83 selectionElem.classList = 'desktop-capturer-selection'; 108 selectionElem.classList = ['desktop-capturer-selection'];
84 selectionElem.innerHTML = ` 109 selectionElem.innerHTML = await window.ferdi.getDisplayMediaSelector();
85 <div class="desktop-capturer-selection__scroller">
86 <ul class="desktop-capturer-selection__list">
87 ${sources
88 .map(
89 ({ id, name, thumbnail }) => `
90 <li class="desktop-capturer-selection__item">
91 <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}">
92 <img class="desktop-capturer-selection__thumbnail" src="${thumbnail.toDataURL()}" />
93 <span class="desktop-capturer-selection__name">${name}</span>
94 </button>
95 </li>
96 `,
97 )
98 .join('')}
99 <li class="desktop-capturer-selection__item">
100 <button class="desktop-capturer-selection__btn" data-id="${CANCEL_ID}" title="Cancel">
101 <span class="desktop-capturer-selection__name desktop-capturer-selection__name--cancel">Cancel</span>
102 </button>
103 </li>
104 </ul>
105 </div>
106 `;
107 document.body.appendChild(selectionElem); 110 document.body.appendChild(selectionElem);
108 111
109 document 112 document
@@ -112,25 +115,18 @@ window.navigator.mediaDevices.getDisplayMedia = () => async (resolve, reject) =>
112 button.addEventListener('click', async () => { 115 button.addEventListener('click', async () => {
113 try { 116 try {
114 const id = button.getAttribute('data-id'); 117 const id = button.getAttribute('data-id');
115 if (id === CANCEL_ID) { 118 if (id === '${CANCEL_ID}') {
116 reject(new Error('Cancelled by user')); 119 reject(new Error('Cancelled by user'));
117 } else { 120 } else {
118 const mediaSource = sources.find((source) => source.id === id); 121 const stream = await window.navigator.mediaDevices.getUserMedia({
119 if (!mediaSource) { 122 audio: false,
120 throw new Error(`Source with id ${id} does not exist`); 123 video: {
121 } 124 mandatory: {
122 125 chromeMediaSource: 'desktop',
123 const stream = await window.navigator.mediaDevices.getUserMedia( 126 chromeMediaSourceId: id,
124 {
125 audio: false,
126 video: {
127 mandatory: {
128 chromeMediaSource: 'desktop',
129 chromeMediaSourceId: mediaSource.id,
130 },
131 }, 127 },
132 }, 128 },
133 ); 129 });
134 resolve(stream); 130 resolve(stream);
135 } 131 }
136 } catch (err) { 132 } catch (err) {
@@ -143,4 +139,5 @@ window.navigator.mediaDevices.getDisplayMedia = () => async (resolve, reject) =>
143 } catch (err) { 139 } catch (err) {
144 reject(err); 140 reject(err);
145 } 141 }
146}; 142});
143`;