From eae3c1c49660ea75c19157109e6e3e61722cebe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 26 Dec 2020 08:32:51 +0100 Subject: [PATCH] Get screen-sharing working, somehow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- .../_DesktopCapturerSourcePicker.scss | 73 ++++++++++++ src/CallHandler.tsx | 25 +++- .../elements/DesktopCapturerSourcePicker.tsx | 109 ++++++++++++++++++ 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 res/css/views/elements/_DesktopCapturerSourcePicker.scss create mode 100644 src/components/views/elements/DesktopCapturerSourcePicker.tsx diff --git a/res/css/views/elements/_DesktopCapturerSourcePicker.scss b/res/css/views/elements/_DesktopCapturerSourcePicker.scss new file mode 100644 index 0000000000..c23fbdf6ac --- /dev/null +++ b/res/css/views/elements/_DesktopCapturerSourcePicker.scss @@ -0,0 +1,73 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_streamSelectorDialog { + -ms-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + margin: 0 auto; + padding-right: 80px; +} +.desktop-capturer-selection-scroller { + width: 100%; + max-height: 100vh; + overflow-y: auto; +} +.desktop-capturer-selection-list { + max-width: calc(100% - 100px); + margin: 0 50px 0 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-button { + display: flex; + flex-direction: column; + align-items: stretch; + width: 145px; + margin: 0; + border: 0; + border-radius: 4px; + padding: 4px; + background: #20262b; + color: #ffffff; + text-align: left; + transition: background-color .15s, box-shadow .15s; +} +.desktop-capturer-selection-button:hover, +.desktop-capturer-selection-button:focus { + background: #363c43; +} +.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; +} diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 504dae5c84..83af34c165 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -82,6 +82,13 @@ import CountlyAnalytics from "./CountlyAnalytics"; import {UIFeature} from "./settings/UIFeature"; import { CallError } from "matrix-js-sdk/src/webrtc/call"; import { logger } from 'matrix-js-sdk/src/logger'; +import DesktopCapturerSourcePicker from "./components/views/elements/DesktopCapturerSourcePicker" + +export interface ElectronDesktopCapturerSource { + display_id: string; + id: string; + name: string; +} enum AudioID { Ring = 'ringAudio', @@ -474,7 +481,23 @@ export default class CallHandler { }); return; } - call.placeScreenSharingCall(remoteElement, localElement); + + const selectDesktopCapturerSource = async ( + sources: Array, + ): Promise => { + console.log(DesktopCapturerSourcePicker); + const params = { + sources: sources, + }; + + const {finished} = Modal.createDialog(DesktopCapturerSourcePicker, params); + + const [source] = await finished; + console.log("Dialog closed with", source); + return source; + }; + + call.placeScreenSharingCall(remoteElement, localElement, selectDesktopCapturerSource); } else { console.error("Unknown conf call type: %s", type); } diff --git a/src/components/views/elements/DesktopCapturerSourcePicker.tsx b/src/components/views/elements/DesktopCapturerSourcePicker.tsx new file mode 100644 index 0000000000..a1d57884e1 --- /dev/null +++ b/src/components/views/elements/DesktopCapturerSourcePicker.tsx @@ -0,0 +1,109 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import { _td } from '../../../languageHandler'; +import BaseDialog from "..//dialogs/BaseDialog" + +export interface DesktopCapturerSourceIProps { + source: ElectronDesktopCapturerSource, + onSelect(source: ElectronDesktopCapturerSource): void, +} + +export class DesktopCapturerSource extends React.Component { + constructor(props) { + super(props); + } + + onClick = (ev) => { + //ev.stopPropagation(); + this.props.onSelect(this.props.source); + } + + render() { + return ( + + ); + } +} + +export interface ElectronDesktopCapturerSource { + display_id: string; + id: string; + name: string; + thumbnail, + appIcon, +} + + +export interface DesktopCapturerSourcePickerIProps { + sources: Array; + onFinished(source: ElectronDesktopCapturerSource): void, +} + +// TODO: Figure out a way to update sources for live preview + +export default class DesktopCapturerSourcePicker extends React.Component { + constructor(props) { + super(props); + } + + onSelect = (source) => { + this.props.onFinished(source); + } + + render() { + const screens = this.props.sources + .filter((source) => { + return source.id.startsWith("screen"); + }) + .map((source) => { + return ; + }); + + const windows = this.props.sources + .filter((source) => { + return source.id.startsWith("window"); + }) + .map((source) => { + return ; + }); + + return ( + +

{_td("Screens")}

+
+ { screens } +
+

{_td("Windows")}

+
+ { windows } +
+
+ ); + } +}