aboutsummaryrefslogtreecommitdiffstats
path: root/src/webview/screenshare.js
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-05-28 19:51:37 +0200
committerLibravatar GitHub <noreply@github.com>2021-05-28 19:51:37 +0200
commit97408875613c39ea0acc33af41c5caf6a82e7ba1 (patch)
tree48e9411543fbde7fad0af62b402fadc32bbd4e92 /src/webview/screenshare.js
parentRead CSS assets in recipes as utf8 (#1459) (diff)
downloadferdium-app-97408875613c39ea0acc33af41c5caf6a82e7ba1.tar.gz
ferdium-app-97408875613c39ea0acc33af41c5caf6a82e7ba1.tar.zst
ferdium-app-97408875613c39ea0acc33af41c5caf6a82e7ba1.zip
Screen share refactoring (#1460)
* Extract screenshare into a separate file Extracted from 240c3a72363e7388779c9ed3c6467ec63bb64d94 according to https://github.com/getferdi/ferdi/pull/1456#discussion_r641194876 * Cosmetic screenshare changes and cancellation * Makes the screen/window selector more readable * Adds a Cancel button to close the selector
Diffstat (limited to 'src/webview/screenshare.js')
-rw-r--r--src/webview/screenshare.js139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/webview/screenshare.js b/src/webview/screenshare.js
new file mode 100644
index 000000000..2715f2e3e
--- /dev/null
+++ b/src/webview/screenshare.js
@@ -0,0 +1,139 @@
1import { desktopCapturer } from 'electron';
2
3const CANCEL_ID = 'desktop-capturer-selection__cancel';
4
5export const screenShareCss = `
6.desktop-capturer-selection {
7 position: fixed;
8 top: 0;
9 left: 0;
10 width: 100%;
11 height: 100vh;
12 background: rgba(30,30,30,.75);
13 color: #fff;
14 z-index: 10000000;
15 display: flex;
16 align-items: center;
17 justify-content: center;
18}
19.desktop-capturer-selection__scroller {
20 width: 100%;
21 max-height: 100vh;
22 overflow-y: auto;
23}
24.desktop-capturer-selection__list {
25 max-width: calc(100% - 100px);
26 margin: 50px;
27 padding: 0;
28 display: flex;
29 flex-wrap: wrap;
30 list-style: none;
31 overflow: hidden;
32 justify-content: center;
33}
34.desktop-capturer-selection__item {
35 display: flex;
36 margin: 4px;
37}
38.desktop-capturer-selection__btn {
39 display: flex;
40 flex-direction: column;
41 align-items: stretch;
42 width: 145px;
43 margin: 0;
44 border: 0;
45 border-radius: 3px;
46 padding: 4px;
47 background: #252626;
48 text-align: left;
49 transition: background-color .15s, box-shadow .15s, color .15s;
50 color: #dedede;
51}
52.desktop-capturer-selection__btn:hover,
53.desktop-capturer-selection__btn:focus {
54 background: rgba(98,100,167,.8);
55 box-shadow: 0 0 4px rgba(0,0,0,0.45), 0 0 2px rgba(0,0,0,0.25);
56 color: #fff;
57}
58.desktop-capturer-selection__thumbnail {
59 width: 100%;
60 height: 81px;
61 object-fit: cover;
62}
63.desktop-capturer-selection__name {
64 margin: 6px 0;
65 white-space: nowrap;
66 text-overflow: ellipsis;
67 text-align: center;
68 overflow: hidden;
69}
70.desktop-capturer-selection__name--cancel {
71 margin: auto 0;
72}
73`;
74
75// Patch getDisplayMedia for screen sharing
76window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => {
77 try {
78 const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] });
79
80 const selectionElem = document.createElement('div');
81 selectionElem.classList = 'desktop-capturer-selection';
82 selectionElem.innerHTML = `
83 <div class="desktop-capturer-selection__scroller">
84 <ul class="desktop-capturer-selection__list">
85 ${sources.map(({
86 id, name, thumbnail,
87 }) => `
88 <li class="desktop-capturer-selection__item">
89 <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}">
90 <img class="desktop-capturer-selection__thumbnail" src="${thumbnail.toDataURL()}" />
91 <span class="desktop-capturer-selection__name">${name}</span>
92 </button>
93 </li>
94 `).join('')}
95 <li class="desktop-capturer-selection__item">
96 <button class="desktop-capturer-selection__btn" data-id="${CANCEL_ID}" title="Cancel">
97 <span class="desktop-capturer-selection__name desktop-capturer-selection__name--cancel">Cancel</span>
98 </button>
99 </li>
100 </ul>
101 </div>
102 `;
103 document.body.appendChild(selectionElem);
104
105 document.querySelectorAll('.desktop-capturer-selection__btn')
106 .forEach((button) => {
107 button.addEventListener('click', async () => {
108 try {
109 const id = button.getAttribute('data-id');
110 if (id === CANCEL_ID) {
111 reject(new Error('Cancelled by user'));
112 } else {
113 const mediaSource = sources.find(source => source.id === id);
114 if (!mediaSource) {
115 throw new Error(`Source with id ${id} does not exist`);
116 }
117
118 const stream = await window.navigator.mediaDevices.getUserMedia({
119 audio: false,
120 video: {
121 mandatory: {
122 chromeMediaSource: 'desktop',
123 chromeMediaSourceId: mediaSource.id,
124 },
125 },
126 });
127 resolve(stream);
128 }
129 } catch (err) {
130 reject(err);
131 } finally {
132 selectionElem.remove();
133 }
134 });
135 });
136 } catch (err) {
137 reject(err);
138 }
139});