From 97408875613c39ea0acc33af41c5caf6a82e7ba1 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Fri, 28 May 2021 19:51:37 +0200 Subject: 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 --- src/webview/recipe.js | 123 +-------------------------------------- src/webview/screenshare.js | 139 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 121 deletions(-) create mode 100644 src/webview/screenshare.js (limited to 'src') diff --git a/src/webview/recipe.js b/src/webview/recipe.js index 6180270b2..5a24effa2 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js @@ -1,5 +1,5 @@ /* eslint-disable import/first */ -import { ipcRenderer, desktopCapturer } from 'electron'; +import { ipcRenderer } from 'electron'; import { getCurrentWebContents } from '@electron/remote'; import path from 'path'; import { autorun, computed, observable } from 'mobx'; @@ -27,75 +27,13 @@ import { switchDict, getSpellcheckerLocaleByFuzzyIdentifier } from './spellcheck import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; import contextMenu from './contextMenu'; import './notifications'; +import { screenShareCss } from './screenshare'; import { DEFAULT_APP_SETTINGS } from '../config'; import { isDevMode } from '../environment'; const debug = require('debug')('Ferdi:Plugin'); -const screenShareCss = ` -.desktop-capturer-selection { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100vh; - background: rgba(30,30,30,.75); - color: #fff; - 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: #252626; - text-align: left; - transition: background-color .15s, box-shadow .15s; -} -.desktop-capturer-selection__btn:hover, -.desktop-capturer-selection__btn:focus { - background: rgba(98,100,167,.8); -} -.desktop-capturer-selection__thumbnail { - width: 100%; - height: 81px; - object-fit: cover; -} -.desktop-capturer-selection__name { - margin: 6px 0 6px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} -`; - class RecipeController { @observable settings = { overrideSpellcheckerLanguage: false, @@ -438,60 +376,3 @@ window.open = (url, frameName, features) => { if (isDevMode) { window.log = console.log; } - -// Patch getDisplayMedia for screen sharing -window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => { - try { - const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] }); - - const selectionElem = document.createElement('div'); - selectionElem.classList = 'desktop-capturer-selection'; - selectionElem.innerHTML = ` -
- -
- `; - document.body.appendChild(selectionElem); - - document.querySelectorAll('.desktop-capturer-selection__btn') - .forEach((button) => { - button.addEventListener('click', async () => { - try { - const id = button.getAttribute('data-id'); - const mediaSource = sources.find(source => source.id === id); - if (!mediaSource) { - throw new Error(`Source with id ${id} does not exist`); - } - - const stream = await window.navigator.mediaDevices.getUserMedia({ - audio: false, - video: { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: mediaSource.id, - }, - }, - }); - resolve(stream); - - selectionElem.remove(); - } catch (err) { - reject(err); - } - }); - }); - } catch (err) { - reject(err); - } -}); 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 @@ +import { desktopCapturer } from 'electron'; + +const CANCEL_ID = 'desktop-capturer-selection__cancel'; + +export const screenShareCss = ` +.desktop-capturer-selection { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background: rgba(30,30,30,.75); + color: #fff; + 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: #252626; + text-align: left; + transition: background-color .15s, box-shadow .15s, color .15s; + color: #dedede; +} +.desktop-capturer-selection__btn:hover, +.desktop-capturer-selection__btn:focus { + background: rgba(98,100,167,.8); + 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; + text-overflow: ellipsis; + text-align: center; + overflow: hidden; +} +.desktop-capturer-selection__name--cancel { + margin: auto 0; +} +`; + +// Patch getDisplayMedia for screen sharing +window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => { + try { + const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] }); + + const selectionElem = document.createElement('div'); + selectionElem.classList = 'desktop-capturer-selection'; + selectionElem.innerHTML = ` +
+ +
+ `; + 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 mediaSource = sources.find(source => source.id === id); + if (!mediaSource) { + throw new Error(`Source with id ${id} does not exist`); + } + + const stream = await window.navigator.mediaDevices.getUserMedia({ + audio: false, + video: { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: mediaSource.id, + }, + }, + }); + resolve(stream); + } + } catch (err) { + reject(err); + } finally { + selectionElem.remove(); + } + }); + }); + } catch (err) { + reject(err); + } +}); -- cgit v1.2.3-54-g00ecf