aboutsummaryrefslogtreecommitdiffstats
path: root/src/webview
diff options
context:
space:
mode:
authorLibravatar André Oliveira <37463445+SpecialAro@users.noreply.github.com>2024-05-02 17:38:48 +0100
committerLibravatar GitHub <noreply@github.com>2024-05-02 17:38:48 +0100
commit92d845adc3c07bcea290eb6fefe0a998cd8f7a98 (patch)
tree1133efe2b1bd9f678cf912bb83f87e8e005bf1f1 /src/webview
parentUpgrade electron to '30.0.2' (diff)
downloadferdium-app-92d845adc3c07bcea290eb6fefe0a998cd8f7a98.tar.gz
ferdium-app-92d845adc3c07bcea290eb6fefe0a998cd8f7a98.tar.zst
ferdium-app-92d845adc3c07bcea290eb6fefe0a998cd8f7a98.zip
fix: screenshare feature not working on Teams (#1733)
Diffstat (limited to 'src/webview')
-rw-r--r--src/webview/recipe.ts7
-rw-r--r--src/webview/screenshare.ts154
2 files changed, 29 insertions, 132 deletions
diff --git a/src/webview/recipe.ts b/src/webview/recipe.ts
index d6db39779..a35a99699 100644
--- a/src/webview/recipe.ts
+++ b/src/webview/recipe.ts
@@ -32,11 +32,7 @@ import {
32 NotificationsHandler, 32 NotificationsHandler,
33 notificationsClassDefinition, 33 notificationsClassDefinition,
34} from './notifications'; 34} from './notifications';
35import { 35import { getDisplayMediaSelector, screenShareJs } from './screenshare';
36 getDisplayMediaSelector,
37 screenShareCss,
38 screenShareJs,
39} from './screenshare';
40import SessionHandler from './sessionHandler'; 36import SessionHandler from './sessionHandler';
41import { 37import {
42 getSpellcheckerLocaleByFuzzyIdentifier, 38 getSpellcheckerLocaleByFuzzyIdentifier,
@@ -267,7 +263,6 @@ class RecipeController {
267 263
268 async loadUserFiles(recipe, config) { 264 async loadUserFiles(recipe, config) {
269 const styles = document.createElement('style'); 265 const styles = document.createElement('style');
270 styles.innerHTML = screenShareCss;
271 266
272 const userCss = join(recipe.path, 'user.css'); 267 const userCss = join(recipe.path, 'user.css');
273 if (pathExistsSync(userCss)) { 268 if (pathExistsSync(userCss)) {
diff --git a/src/webview/screenshare.ts b/src/webview/screenshare.ts
index e631ce52f..521f95bd6 100644
--- a/src/webview/screenshare.ts
+++ b/src/webview/screenshare.ts
@@ -1,139 +1,41 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import { v4 as uuidV4 } from 'uuid';
2 3
3const CANCEL_ID = 'desktop-capturer-selection__cancel'; 4const debug = require('../preload-safe-debug')('Ferdium:Screenshare');
4 5
5export async function getDisplayMediaSelector() { 6export async function getDisplayMediaSelector() {
6 const sources = await ipcRenderer.invoke('get-desktop-capturer-sources'); 7 return new Promise((resolve, reject) => {
7 return `<div class="desktop-capturer-selection__scroller"> 8 const trackerId = uuidV4();
8 <ul class="desktop-capturer-selection__list"> 9 debug('New screenshare request', trackerId);
9 ${sources
10 .map(
11 ({ id, name, thumbnail }) => `
12 <li class="desktop-capturer-selection__item">
13 <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}">
14 <img class="desktop-capturer-selection__thumbnail" src="${thumbnail.toDataURL()}" />
15 <span class="desktop-capturer-selection__name">${name}</span>
16 </button>
17 </li>
18 `,
19 )
20 .join('')}
21 <li class="desktop-capturer-selection__item">
22 <button class="desktop-capturer-selection__btn" data-id="${CANCEL_ID}" title="Cancel">
23 <span class="desktop-capturer-selection__name desktop-capturer-selection__name--cancel">Cancel</span>
24 </button>
25 </li>
26 </ul>
27</div>`;
28}
29 10
30export const screenShareCss = ` 11 ipcRenderer.sendToHost('load-available-displays', {
31.desktop-capturer-selection { 12 trackerId,
32 position: fixed; 13 });
33 top: 0; 14
34 left: 0; 15 ipcRenderer.once(`selected-media-source:${trackerId}`, (_e, data) => {
35 width: 100%; 16 if (data.mediaSourceId === 'desktop-capturer-selection__cancel') {
36 height: 100vh; 17 return reject(new Error('Cancelled by user'));
37 background: rgba(30,30,30,.75); 18 }
38 color: #fff; 19
39 z-index: 10000000; 20 return resolve(data.mediaSourceId);
40 display: flex; 21 });
41 align-items: center; 22 });
42 justify-content: center;
43}
44.desktop-capturer-selection__scroller {
45 width: 100%;
46 max-height: 100vh;
47 overflow-y: auto;
48}
49.desktop-capturer-selection__list {
50 max-width: calc(100% - 100px);
51 margin: 50px;
52 padding: 0;
53 display: flex;
54 flex-wrap: wrap;
55 list-style: none;
56 overflow: hidden;
57 justify-content: center;
58}
59.desktop-capturer-selection__item {
60 display: flex;
61 margin: 4px;
62}
63.desktop-capturer-selection__btn {
64 display: flex;
65 flex-direction: column;
66 align-items: stretch;
67 width: 145px;
68 margin: 0;
69 border: 0;
70 border-radius: 3px;
71 padding: 4px;
72 background: #252626;
73 text-align: left;
74 @media (prefers-reduced-motion: no-preference) {
75 transition: background-color .15s, box-shadow .15s, color .15s;
76 }
77 color: #dedede;
78}
79.desktop-capturer-selection__btn:hover,
80.desktop-capturer-selection__btn:focus {
81 background: rgba(98,100,167,.8);
82 box-shadow: 0 0 4px rgba(0,0,0,0.45), 0 0 2px rgba(0,0,0,0.25);
83 color: #fff;
84}
85.desktop-capturer-selection__thumbnail {
86 width: 100%;
87 height: 81px;
88 object-fit: cover;
89}
90.desktop-capturer-selection__name {
91 margin: 6px 0;
92 white-space: nowrap;
93 text-overflow: ellipsis;
94 text-align: center;
95 overflow: hidden;
96}
97.desktop-capturer-selection__name--cancel {
98 margin: auto 0;
99} 23}
100`;
101 24
102export const screenShareJs = ` 25export const screenShareJs = `
103window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => { 26window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => {
104 try { 27 try {
105 const selectionElem = document.createElement('div'); 28 const displayId = await window.ferdium.getDisplayMediaSelector();
106 selectionElem.classList = ['desktop-capturer-selection']; 29 const stream = await window.navigator.mediaDevices.getUserMedia({
107 selectionElem.innerHTML = await window.ferdium.getDisplayMediaSelector(); 30 audio: false,
108 document.body.appendChild(selectionElem); 31 video: {
109 32 mandatory: {
110 document 33 chromeMediaSource: 'desktop',
111 .querySelectorAll('.desktop-capturer-selection__btn') 34 chromeMediaSourceId: displayId,
112 .forEach((button) => { 35 },
113 button.addEventListener('click', async () => { 36 },
114 try { 37 });
115 const id = button.getAttribute('data-id'); 38 resolve(stream);
116 if (id === '${CANCEL_ID}') {
117 reject(new Error('Cancelled by user'));
118 } else {
119 const stream = await window.navigator.mediaDevices.getUserMedia({
120 audio: false,
121 video: {
122 mandatory: {
123 chromeMediaSource: 'desktop',
124 chromeMediaSourceId: id,
125 },
126 },
127 });
128 resolve(stream);
129 }
130 } catch (err) {
131 reject(err);
132 } finally {
133 selectionElem.remove();
134 }
135 });
136 });
137 } catch (err) { 39 } catch (err) {
138 reject(err); 40 reject(err);
139 } 41 }