Bug 1214215: Part 2 - remove screen sharing controls entirely from the conversation window. r=Standard8
@ -7,7 +7,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
@ -773,11 +772,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
this.setTitle(roomTitle);
|
||||
}
|
||||
|
||||
var screenShareData = {
|
||||
state: this.state.screenSharingState || SCREEN_SHARE_STATES.INACTIVE,
|
||||
visible: true
|
||||
};
|
||||
|
||||
var shouldRenderInvitationOverlay = this._shouldRenderInvitationOverlay();
|
||||
var shouldRenderEditContextView = this.state.showEditContext;
|
||||
var roomData = this.props.roomStore.getStoreState("activeRoom");
|
||||
@ -833,7 +827,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
dispatcher: this.props.dispatcher,
|
||||
hangup: this.leaveRoom,
|
||||
publishStream: this.publishStream,
|
||||
screenShare: screenShareData,
|
||||
settingsMenuItems: settingsMenuItems,
|
||||
show: !shouldRenderEditContextView,
|
||||
showHangup: this.props.chatWindowDetached,
|
||||
|
@ -7,7 +7,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
@ -773,11 +772,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
this.setTitle(roomTitle);
|
||||
}
|
||||
|
||||
var screenShareData = {
|
||||
state: this.state.screenSharingState || SCREEN_SHARE_STATES.INACTIVE,
|
||||
visible: true
|
||||
};
|
||||
|
||||
var shouldRenderInvitationOverlay = this._shouldRenderInvitationOverlay();
|
||||
var shouldRenderEditContextView = this.state.showEditContext;
|
||||
var roomData = this.props.roomStore.getStoreState("activeRoom");
|
||||
@ -833,7 +827,6 @@ loop.roomViews = (function(mozL10n) {
|
||||
dispatcher={this.props.dispatcher}
|
||||
hangup={this.leaveRoom}
|
||||
publishStream={this.publishStream}
|
||||
screenShare={screenShareData}
|
||||
settingsMenuItems={settingsMenuItems}
|
||||
show={!shouldRenderEditContextView}
|
||||
showHangup={this.props.chatWindowDetached}
|
||||
|
@ -160,24 +160,6 @@ html[dir="rtl"] .conversation-toolbar-btn-box.btn-edit-entry {
|
||||
background-image: url("../img/settings-hover.svg");
|
||||
}
|
||||
|
||||
.btn-screen-share {
|
||||
background-image: url("../img/sharing.svg");
|
||||
}
|
||||
|
||||
.btn-screen-share:hover,
|
||||
.btn-screen-share:active {
|
||||
background-image: url("../img/sharing-hover.svg");
|
||||
}
|
||||
|
||||
.btn-screen-share.active {
|
||||
background-image: url("../img/sharing-active.svg");
|
||||
}
|
||||
|
||||
.btn-screen-share.disabled {
|
||||
/* The screen share button is in its pending state when its disabled. */
|
||||
background-image: url("../img/sharing-pending.svg");
|
||||
}
|
||||
|
||||
/* General Call (incoming or outgoing). */
|
||||
|
||||
.call-action-group {
|
||||
@ -319,7 +301,6 @@ html[dir="rtl"] .room-failure > .settings-control {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.screen-share-menu.dropdown-menu,
|
||||
.settings-menu.dropdown-menu {
|
||||
bottom: 3.1rem;
|
||||
}
|
||||
@ -330,16 +311,10 @@ html[dir="rtl"] .room-failure > .settings-control {
|
||||
right: 14px;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .screen-share-menu.dropdown-menu,
|
||||
html[dir="rtl"] .settings-menu.dropdown-menu {
|
||||
right: auto;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .screen-share-menu.dropdown-menu {
|
||||
/*offset dropdown menu to be above menu button*/
|
||||
left: 40px;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .settings-menu.dropdown-menu {
|
||||
/*offset dropdown menu to be above menu button*/
|
||||
left: 14px;
|
||||
|
@ -1 +0,0 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg"><g fill="none"><rect opacity=".95" fill="#fff" x="2" y="2" width="24" height="24" rx="40"/><path d="M2 14c0 6.629 5.373 12 12 12 6.629 0 12-5.373 12-12 0-6.629-5.373-12-12-12-6.629 0-12 5.373-12 12zm-2 0c0-7.732 6.267-14 14-14 7.732 0 14 6.267 14 14 0 7.732-6.267 14-14 14-7.732 0-14-6.267-14-14z" fill-opacity=".2" fill="#000"/><rect fill="#00A9DC" x="11" y="12" width="9" height="7" rx="1"/><path d="M17 11v-.997c0-.565-.447-1.003-.998-1.003h-7.005c-.551 0-.998.449-.998 1.003v4.994c0 .565.447 1.003.998 1.003h1.002v-3.997c0-.554.446-1.003.998-1.003h6.002z" fill="#00A9DC"/></g></svg>
|
Before Width: | Height: | Size: 670 B After Width: | Height: | Size: 0 B |
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle-1264-Copy" opacity="0.95" fill="#5CCCEE" x="2" y="2" width="24" height="24" rx="40"></rect>
|
||||
<path d="M2,14 L2,14 C2,20.6288742 7.372583,26 14,26 L14,26 C20.6288742,26 26,20.627417 26,14 L26,14 C26,7.37112582 20.627417,2 14,2 L14,2 C7.37112582,2 2,7.372583 2,14 L2,14 Z M0,14 L0,14 C0,6.26754774 6.26702203,0 14,0 C21.7324523,0 28,6.26702203 28,14 C28,21.7324523 21.732978,28 14,28 C6.26754774,28 0,21.732978 0,14 L0,14 Z" id="Shape" fill-opacity="0.2" fill="#000000"></path>
|
||||
<rect id="Rectangle-170-Copy-4" fill="#FFFFFF" x="11" y="12" width="9" height="7" rx="1"></rect>
|
||||
<path d="M17,11 L17,10.0029293 C17,9.43788135 16.553384,9 16.0024554,9 L8.99754465,9 C8.4463114,9 8,9.44902676 8,10.0029293 L8,14.9970707 C8,15.5621186 8.44661595,16 8.99754465,16 L10,16 L10,12.0029293 C10,11.4490268 10.4463114,11 10.9975446,11 L17,11 Z" id="Rectangle-170-Copy" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 0 B |
@ -1 +0,0 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg"><g fill="none"><rect opacity=".95" fill="#999999" x="2" y="2" width="24" height="24" rx="40"/><path d="M2 14c0 6.629 5.373 12 12 12 6.629 0 12-5.373 12-12 0-6.629-5.373-12-12-12-6.629 0-12 5.373-12 12zm-2 0c0-7.732 6.267-14 14-14 7.732 0 14 6.267 14 14 0 7.732-6.267 14-14 14-7.732 0-14-6.267-14-14z" fill-opacity=".2" fill="#000"/><rect fill="#4A4A4A" x="11" y="12" width="9" height="7" rx="1"/><path d="M17 11v-.997c0-.565-.447-1.003-.998-1.003h-7.005c-.551 0-.998.449-.998 1.003v4.994c0 .565.447 1.003.998 1.003h1.002v-3.997c0-.554.446-1.003.998-1.003h6.002z" fill="#4A4A4A"/></g></svg>
|
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 0 B |
@ -1 +0,0 @@
|
||||
<svg width="28" height="28" viewBox="0 0 28 28" xmlns="http://www.w3.org/2000/svg"><g fill="none"><rect opacity=".95" fill="#fff" x="2" y="2" width="24" height="24" rx="40"/><path d="M2 14c0 6.629 5.373 12 12 12 6.629 0 12-5.373 12-12 0-6.629-5.373-12-12-12-6.629 0-12 5.373-12 12zm-2 0c0-7.732 6.267-14 14-14 7.732 0 14 6.267 14 14 0 7.732-6.267 14-14 14-7.732 0-14-6.267-14-14z" fill-opacity=".2" fill="#000"/><rect fill="#4A4A4A" x="11" y="12" width="9" height="7" rx="1"/><path d="M17 11v-.997c0-.565-.447-1.003-.998-1.003h-7.005c-.551 0-.998.449-.998 1.003v4.994c0 .565.447 1.003.998 1.003h1.002v-3.997c0-.554.446-1.003.998-1.003h6.002z" fill="#4A4A4A"/></g></svg>
|
Before Width: | Height: | Size: 669 B After Width: | Height: | Size: 0 B |
@ -204,14 +204,6 @@ loop.shared.actions = (function() {
|
||||
enabled: Boolean
|
||||
}),
|
||||
|
||||
/**
|
||||
* Used to start a screen share.
|
||||
*/
|
||||
StartScreenShare: Action.define("startScreenShare", {
|
||||
// The part of the screen to share, e.g. "window" or "browser".
|
||||
type: String
|
||||
}),
|
||||
|
||||
/**
|
||||
* Used to start a browser tab share.
|
||||
*/
|
||||
|
@ -257,7 +257,6 @@ loop.store.ActiveRoomStore = (function() {
|
||||
"mediaStreamDestroyed",
|
||||
"remoteVideoStatus",
|
||||
"videoDimensionsChanged",
|
||||
"startScreenShare",
|
||||
"startBrowserShare",
|
||||
"endScreenShare",
|
||||
"updateSocialShareInfo",
|
||||
@ -921,11 +920,11 @@ loop.store.ActiveRoomStore = (function() {
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiates a screen sharing publisher.
|
||||
* Initiates a browser tab sharing publisher.
|
||||
*
|
||||
* @param {sharedActions.StartScreenShare} actionData
|
||||
* @param {sharedActions.StartBrowserShare} actionData
|
||||
*/
|
||||
startScreenShare: function(actionData) {
|
||||
startBrowserShare: function(actionData) {
|
||||
// For the unit test we already set the state here, instead of indirectly
|
||||
// via an action, because actions are queued thus depending on the
|
||||
// asynchronous nature of `loop.request`.
|
||||
@ -935,28 +934,16 @@ loop.store.ActiveRoomStore = (function() {
|
||||
}));
|
||||
|
||||
var options = {
|
||||
videoSource: actionData.type
|
||||
videoSource: "browser"
|
||||
};
|
||||
if (options.videoSource === "browser") {
|
||||
this._browserSharingListener = this._handleSwitchBrowserShare.bind(this);
|
||||
this._browserSharingListener = this._handleSwitchBrowserShare.bind(this);
|
||||
|
||||
// Set up a listener for watching screen shares. This will get notified
|
||||
// with the first windowId when it is added, so we start off the sharing
|
||||
// from within the listener.
|
||||
loop.request("AddBrowserSharingListener").then(this._browserSharingListener);
|
||||
loop.subscribe("BrowserSwitch", this._browserSharingListener);
|
||||
} else {
|
||||
this._sdkDriver.startScreenShare(options);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initiates a browser tab sharing publisher.
|
||||
*
|
||||
* @param {sharedActions.StartBrowserShare} actionData
|
||||
*/
|
||||
startBrowserShare: function(actionData) {
|
||||
this.startScreenShare({ type: "browser" });
|
||||
// Set up a listener for watching screen shares. This will get notified
|
||||
// with the first windowId when it is added, so we start off the sharing
|
||||
// from within the listener.
|
||||
loop.request("AddBrowserSharingListener", this.getStoreState().windowId)
|
||||
.then(this._browserSharingListener);
|
||||
loop.subscribe("BrowserSwitch", this._browserSharingListener);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedModels = loop.shared.models;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
|
||||
/**
|
||||
* Hang-up control button.
|
||||
@ -104,114 +103,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Screen sharing control button.
|
||||
*
|
||||
* Required props:
|
||||
* - {loop.Dispatcher} dispatcher The dispatcher instance
|
||||
* - {Boolean} visible Set to true to display the button
|
||||
* - {String} state One of the screen sharing states, see
|
||||
* loop.shared.utils.SCREEN_SHARE_STATES
|
||||
*/
|
||||
var ScreenShareControlButton = React.createClass({displayName: "ScreenShareControlButton",
|
||||
mixins: [sharedMixins.DropdownMenuMixin()],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
state: React.PropTypes.string.isRequired,
|
||||
visible: React.PropTypes.bool.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var os = loop.shared.utils.getOS();
|
||||
var osVersion = loop.shared.utils.getOSVersion();
|
||||
// Disable screensharing on older OSX and Windows versions.
|
||||
if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
|
||||
(os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
|
||||
return { windowSharingDisabled: true };
|
||||
}
|
||||
return { windowSharingDisabled: false };
|
||||
},
|
||||
|
||||
handleClick: function() {
|
||||
if (this.props.state === SCREEN_SHARE_STATES.ACTIVE) {
|
||||
this.props.dispatcher.dispatch(
|
||||
new sharedActions.EndScreenShare({}));
|
||||
} else {
|
||||
this.toggleDropdownMenu();
|
||||
}
|
||||
},
|
||||
|
||||
_startScreenShare: function(type) {
|
||||
this.props.dispatcher.dispatch(new sharedActions.StartScreenShare({
|
||||
type: type
|
||||
}));
|
||||
},
|
||||
|
||||
_handleShareTabs: function() {
|
||||
this._startScreenShare("browser");
|
||||
this.hideDropdownMenu();
|
||||
},
|
||||
|
||||
_handleShareWindows: function() {
|
||||
this._startScreenShare("window");
|
||||
this.hideDropdownMenu();
|
||||
},
|
||||
|
||||
_getTitle: function() {
|
||||
var prefix = this.props.state === SCREEN_SHARE_STATES.ACTIVE ?
|
||||
"active" : "inactive";
|
||||
|
||||
return mozL10n.get(prefix + "_screenshare_button_title");
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!this.props.visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var cx = classNames;
|
||||
|
||||
var isActive = this.props.state === SCREEN_SHARE_STATES.ACTIVE;
|
||||
var screenShareClasses = cx({
|
||||
"btn": true,
|
||||
"btn-screen-share": true,
|
||||
"transparent-button": true,
|
||||
"menu-showing": this.state.showMenu,
|
||||
"active": isActive,
|
||||
"disabled": this.props.state === SCREEN_SHARE_STATES.PENDING
|
||||
});
|
||||
var dropdownMenuClasses = cx({
|
||||
"screen-share-menu": true,
|
||||
"dropdown-menu": true,
|
||||
"hide": !this.state.showMenu
|
||||
});
|
||||
var windowSharingClasses = cx({
|
||||
"dropdown-menu-item": true,
|
||||
"disabled": this.state.windowSharingDisabled
|
||||
});
|
||||
|
||||
return (
|
||||
React.createElement("div", null,
|
||||
React.createElement("button", {className: screenShareClasses,
|
||||
onClick: this.handleClick,
|
||||
ref: "anchor",
|
||||
title: this._getTitle()},
|
||||
isActive ? null : React.createElement("span", {className: "chevron"})
|
||||
),
|
||||
React.createElement("ul", {className: dropdownMenuClasses, ref: "menu"},
|
||||
React.createElement("li", {className: "dropdown-menu-item", onClick: this._handleShareTabs},
|
||||
mozL10n.get("share_tabs_button_title2")
|
||||
),
|
||||
React.createElement("li", {className: windowSharingClasses, onClick: this._handleShareWindows},
|
||||
mozL10n.get("share_windows_button_title")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Settings control button.
|
||||
*/
|
||||
@ -391,7 +282,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
return {
|
||||
video: { enabled: true, visible: true },
|
||||
audio: { enabled: true, visible: true },
|
||||
screenShare: { state: SCREEN_SHARE_STATES.INACTIVE, visible: false },
|
||||
settingsMenuItems: null,
|
||||
showHangup: true
|
||||
};
|
||||
@ -408,7 +298,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
hangup: React.PropTypes.func.isRequired,
|
||||
publishStream: React.PropTypes.func.isRequired,
|
||||
screenShare: React.PropTypes.object,
|
||||
settingsMenuItems: React.PropTypes.array,
|
||||
show: React.PropTypes.bool.isRequired,
|
||||
showHangup: React.PropTypes.bool,
|
||||
@ -525,11 +414,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
visible: this.props.audio.visible})
|
||||
)
|
||||
),
|
||||
React.createElement("li", {className: "conversation-toolbar-btn-box"},
|
||||
React.createElement(ScreenShareControlButton, {dispatcher: this.props.dispatcher,
|
||||
state: this.props.screenShare.state,
|
||||
visible: this.props.screenShare.visible})
|
||||
),
|
||||
React.createElement("li", {className: "conversation-toolbar-btn-box btn-edit-entry"},
|
||||
React.createElement(SettingsControlButton, {menuItems: this.props.settingsMenuItems})
|
||||
)
|
||||
@ -1141,7 +1025,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
MediaView: MediaView,
|
||||
LoadingView: LoadingView,
|
||||
SettingsControlButton: SettingsControlButton,
|
||||
ScreenShareControlButton: ScreenShareControlButton,
|
||||
NotificationListView: NotificationListView
|
||||
};
|
||||
})(_, navigator.mozL10n || document.mozL10n);
|
||||
|
@ -10,7 +10,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedModels = loop.shared.models;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
|
||||
/**
|
||||
* Hang-up control button.
|
||||
@ -104,114 +103,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Screen sharing control button.
|
||||
*
|
||||
* Required props:
|
||||
* - {loop.Dispatcher} dispatcher The dispatcher instance
|
||||
* - {Boolean} visible Set to true to display the button
|
||||
* - {String} state One of the screen sharing states, see
|
||||
* loop.shared.utils.SCREEN_SHARE_STATES
|
||||
*/
|
||||
var ScreenShareControlButton = React.createClass({
|
||||
mixins: [sharedMixins.DropdownMenuMixin()],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
state: React.PropTypes.string.isRequired,
|
||||
visible: React.PropTypes.bool.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var os = loop.shared.utils.getOS();
|
||||
var osVersion = loop.shared.utils.getOSVersion();
|
||||
// Disable screensharing on older OSX and Windows versions.
|
||||
if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
|
||||
(os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
|
||||
return { windowSharingDisabled: true };
|
||||
}
|
||||
return { windowSharingDisabled: false };
|
||||
},
|
||||
|
||||
handleClick: function() {
|
||||
if (this.props.state === SCREEN_SHARE_STATES.ACTIVE) {
|
||||
this.props.dispatcher.dispatch(
|
||||
new sharedActions.EndScreenShare({}));
|
||||
} else {
|
||||
this.toggleDropdownMenu();
|
||||
}
|
||||
},
|
||||
|
||||
_startScreenShare: function(type) {
|
||||
this.props.dispatcher.dispatch(new sharedActions.StartScreenShare({
|
||||
type: type
|
||||
}));
|
||||
},
|
||||
|
||||
_handleShareTabs: function() {
|
||||
this._startScreenShare("browser");
|
||||
this.hideDropdownMenu();
|
||||
},
|
||||
|
||||
_handleShareWindows: function() {
|
||||
this._startScreenShare("window");
|
||||
this.hideDropdownMenu();
|
||||
},
|
||||
|
||||
_getTitle: function() {
|
||||
var prefix = this.props.state === SCREEN_SHARE_STATES.ACTIVE ?
|
||||
"active" : "inactive";
|
||||
|
||||
return mozL10n.get(prefix + "_screenshare_button_title");
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!this.props.visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var cx = classNames;
|
||||
|
||||
var isActive = this.props.state === SCREEN_SHARE_STATES.ACTIVE;
|
||||
var screenShareClasses = cx({
|
||||
"btn": true,
|
||||
"btn-screen-share": true,
|
||||
"transparent-button": true,
|
||||
"menu-showing": this.state.showMenu,
|
||||
"active": isActive,
|
||||
"disabled": this.props.state === SCREEN_SHARE_STATES.PENDING
|
||||
});
|
||||
var dropdownMenuClasses = cx({
|
||||
"screen-share-menu": true,
|
||||
"dropdown-menu": true,
|
||||
"hide": !this.state.showMenu
|
||||
});
|
||||
var windowSharingClasses = cx({
|
||||
"dropdown-menu-item": true,
|
||||
"disabled": this.state.windowSharingDisabled
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button className={screenShareClasses}
|
||||
onClick={this.handleClick}
|
||||
ref="anchor"
|
||||
title={this._getTitle()}>
|
||||
{isActive ? null : <span className="chevron"/>}
|
||||
</button>
|
||||
<ul className={dropdownMenuClasses} ref="menu">
|
||||
<li className="dropdown-menu-item" onClick={this._handleShareTabs}>
|
||||
{mozL10n.get("share_tabs_button_title2")}
|
||||
</li>
|
||||
<li className={windowSharingClasses} onClick={this._handleShareWindows}>
|
||||
{mozL10n.get("share_windows_button_title")}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Settings control button.
|
||||
*/
|
||||
@ -391,7 +282,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
return {
|
||||
video: { enabled: true, visible: true },
|
||||
audio: { enabled: true, visible: true },
|
||||
screenShare: { state: SCREEN_SHARE_STATES.INACTIVE, visible: false },
|
||||
settingsMenuItems: null,
|
||||
showHangup: true
|
||||
};
|
||||
@ -408,7 +298,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
hangup: React.PropTypes.func.isRequired,
|
||||
publishStream: React.PropTypes.func.isRequired,
|
||||
screenShare: React.PropTypes.object,
|
||||
settingsMenuItems: React.PropTypes.array,
|
||||
show: React.PropTypes.bool.isRequired,
|
||||
showHangup: React.PropTypes.bool,
|
||||
@ -525,11 +414,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
visible={this.props.audio.visible}/>
|
||||
</div>
|
||||
</li>
|
||||
<li className="conversation-toolbar-btn-box">
|
||||
<ScreenShareControlButton dispatcher={this.props.dispatcher}
|
||||
state={this.props.screenShare.state}
|
||||
visible={this.props.screenShare.visible} />
|
||||
</li>
|
||||
<li className="conversation-toolbar-btn-box btn-edit-entry">
|
||||
<SettingsControlButton menuItems={this.props.settingsMenuItems} />
|
||||
</li>
|
||||
@ -1141,7 +1025,6 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
MediaView: MediaView,
|
||||
LoadingView: LoadingView,
|
||||
SettingsControlButton: SettingsControlButton,
|
||||
ScreenShareControlButton: ScreenShareControlButton,
|
||||
NotificationListView: NotificationListView
|
||||
};
|
||||
})(_, navigator.mozL10n || document.mozL10n);
|
||||
|
@ -12,8 +12,6 @@ mute_local_audio_button_title=Mute your audio
|
||||
unmute_local_audio_button_title=Unmute your audio
|
||||
mute_local_video_button_title2=Disable video
|
||||
unmute_local_video_button_title2=Enable video
|
||||
active_screenshare_button_title=Stop sharing
|
||||
inactive_screenshare_button_title=Share your screen
|
||||
|
||||
welcome=Welcome to the {{clientShortname}} web client.
|
||||
incompatible_browser_heading=Oops!
|
||||
|
@ -400,11 +400,9 @@ describe("loop.roomViews", function() {
|
||||
expect(muteBtn.classList.contains("muted")).eql(true);
|
||||
});
|
||||
|
||||
it("should dispatch a `StartScreenShare` action when sharing is not active and the screen share button is pressed", function() {
|
||||
it("should dispatch a `SetMute` action when the mute button is pressed", function() {
|
||||
view = mountTestComponent();
|
||||
|
||||
view.setState({ screenSharingState: SCREEN_SHARE_STATES.INACTIVE });
|
||||
|
||||
var muteBtn = view.getDOMNode().querySelector(".btn-mute-video");
|
||||
|
||||
React.addons.TestUtils.Simulate.click(muteBtn);
|
||||
|
@ -186,12 +186,6 @@ class Test1BrowserCall(MarionetteTestCase):
|
||||
self.switch_to_chatbox()
|
||||
self.check_received_message("test2")
|
||||
|
||||
def local_enable_screenshare(self):
|
||||
self.switch_to_chatbox()
|
||||
button = self.marionette.find_element(By.CLASS_NAME, "btn-screen-share")
|
||||
|
||||
button.click()
|
||||
|
||||
def standalone_check_remote_screenshare(self):
|
||||
self.switch_to_standalone()
|
||||
self.check_video(".screen-share-video")
|
||||
@ -293,10 +287,8 @@ class Test1BrowserCall(MarionetteTestCase):
|
||||
# the start time
|
||||
self.local_check_media_start_time_initialized()
|
||||
|
||||
# XXX To enable this, we either need to navigate the permissions prompt
|
||||
# or have a route where we don't need the permissions prompt.
|
||||
# self.local_enable_screenshare()
|
||||
# self.standalone_check_remote_screenshare()
|
||||
# Check that screenshare was automatically started
|
||||
self.standalone_check_remote_screenshare()
|
||||
|
||||
# We hangup on the remote (standalone) side, because this also leaves
|
||||
# the local chatbox with the local publishing media still connected,
|
||||
|
@ -199,9 +199,7 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
|
||||
it("should remove the sharing listener", function() {
|
||||
// Setup the listener.
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
// Now simulate room failure.
|
||||
store.roomFailure(new sharedActions.RoomFailure({
|
||||
@ -1257,9 +1255,7 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
|
||||
it("should remove the sharing listener", function() {
|
||||
// Setup the listener.
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
// Now simulate connection failure.
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
@ -1539,15 +1535,13 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#startScreenShare", function() {
|
||||
describe("#startBrowserShare", function() {
|
||||
afterEach(function() {
|
||||
store.endScreenShare();
|
||||
});
|
||||
|
||||
it("should set the state to 'pending'", function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "window"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWith(dispatcher.dispatch,
|
||||
@ -1556,29 +1550,14 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
}));
|
||||
});
|
||||
|
||||
it("should invoke the SDK driver with the correct options for window sharing", function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "window"
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(fakeSdkDriver.startScreenShare);
|
||||
sinon.assert.calledWith(fakeSdkDriver.startScreenShare, {
|
||||
videoSource: "window"
|
||||
});
|
||||
});
|
||||
|
||||
it("should add a browser sharing listener for tab sharing", function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
sinon.assert.calledOnce(requestStubs.AddBrowserSharingListener);
|
||||
});
|
||||
|
||||
it("should invoke the SDK driver with the correct options for tab sharing", function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
sinon.assert.calledOnce(fakeSdkDriver.startScreenShare);
|
||||
sinon.assert.calledWith(fakeSdkDriver.startScreenShare, {
|
||||
@ -1593,9 +1572,7 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
|
||||
describe("Screen share Events", function() {
|
||||
beforeEach(function() {
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
store.setStoreState({
|
||||
screenSharingState: SCREEN_SHARE_STATES.ACTIVE
|
||||
@ -1652,9 +1629,7 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
|
||||
it("should remove the sharing listener", function() {
|
||||
// Setup the listener.
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
// Now stop the screen share.
|
||||
store.endScreenShare();
|
||||
@ -1807,9 +1782,7 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
|
||||
it("should remove the sharing listener", function() {
|
||||
// Setup the listener.
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
// Now unload the window.
|
||||
store.windowUnload();
|
||||
@ -1864,9 +1837,7 @@ describe("loop.store.ActiveRoomStore", function() {
|
||||
|
||||
it("should remove the sharing listener", function() {
|
||||
// Setup the listener.
|
||||
store.startScreenShare(new sharedActions.StartScreenShare({
|
||||
type: "browser"
|
||||
}));
|
||||
store.startBrowserShare(new sharedActions.StartBrowserShare());
|
||||
|
||||
// Now leave the room.
|
||||
store.leaveRoom();
|
||||
|
@ -11,7 +11,6 @@ describe("loop.shared.views", function() {
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedModels = loop.shared.models;
|
||||
var sharedViews = loop.shared.views;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
var getReactElementByClass = TestUtils.findRenderedDOMComponentWithClass;
|
||||
var sandbox, fakeAudioXHR, dispatcher, OS, OSVersion;
|
||||
|
||||
@ -109,186 +108,6 @@ describe("loop.shared.views", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("ScreenShareControlButton", function() {
|
||||
it("should render a visible share button", function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
expect(comp.getDOMNode().classList.contains("active")).eql(false);
|
||||
expect(comp.getDOMNode().classList.contains("disabled")).eql(false);
|
||||
});
|
||||
|
||||
it("should render a disabled share button when share is pending", function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.PENDING
|
||||
}));
|
||||
|
||||
var node = comp.getDOMNode().querySelector(".btn-screen-share");
|
||||
expect(node.classList.contains("active")).eql(false);
|
||||
expect(node.classList.contains("disabled")).eql(true);
|
||||
});
|
||||
|
||||
it("should render an active share button", function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.ACTIVE
|
||||
}));
|
||||
|
||||
var node = comp.getDOMNode().querySelector(".btn-screen-share");
|
||||
expect(node.classList.contains("active")).eql(true);
|
||||
expect(node.classList.contains("disabled")).eql(false);
|
||||
});
|
||||
|
||||
it("should show the screenshare dropdown on click when the state is not active",
|
||||
function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
expect(comp.state.showMenu).eql(false);
|
||||
|
||||
TestUtils.Simulate.click(comp.getDOMNode().querySelector(".btn-screen-share"));
|
||||
|
||||
expect(comp.state.showMenu).eql(true);
|
||||
});
|
||||
|
||||
it("should dispatch a 'browser' StartScreenShare action on option click",
|
||||
function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
TestUtils.Simulate.click(comp.getDOMNode().querySelector(
|
||||
".screen-share-menu > li"));
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.StartScreenShare({ type: "browser" }));
|
||||
});
|
||||
|
||||
it("should close the dropdown on 'browser' option click", function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
sandbox.stub(comp, "hideDropdownMenu");
|
||||
|
||||
TestUtils.Simulate.click(comp.getDOMNode().querySelector(
|
||||
".screen-share-menu > li"));
|
||||
|
||||
sinon.assert.calledOnce(comp.hideDropdownMenu);
|
||||
});
|
||||
|
||||
it("should dispatch a 'window' StartScreenShare action on option click",
|
||||
function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
TestUtils.Simulate.click(comp.getDOMNode().querySelector(
|
||||
".screen-share-menu > li:last-child"));
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.StartScreenShare({ type: "window" }));
|
||||
});
|
||||
|
||||
it("should close the dropdown on 'window' option click", function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
sandbox.stub(comp, "hideDropdownMenu");
|
||||
|
||||
TestUtils.Simulate.click(comp.getDOMNode().querySelector(
|
||||
".screen-share-menu > li:last-child"));
|
||||
|
||||
sinon.assert.calledOnce(comp.hideDropdownMenu);
|
||||
});
|
||||
|
||||
it("should have the 'window' option enabled", function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
var node = comp.getDOMNode().querySelector(".screen-share-menu > li:last-child");
|
||||
expect(node.classList.contains("disabled")).eql(false);
|
||||
});
|
||||
|
||||
it("should disable the 'window' option on Windows XP", function() {
|
||||
OS = "win";
|
||||
OSVersion = { major: 5, minor: 1 };
|
||||
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
var node = comp.getDOMNode().querySelector(".screen-share-menu > li:last-child");
|
||||
expect(node.classList.contains("disabled")).eql(true);
|
||||
});
|
||||
|
||||
it("should disable the 'window' option on OSX 10.6", function() {
|
||||
OS = "mac";
|
||||
OSVersion = { major: 10, minor: 6 };
|
||||
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.INACTIVE
|
||||
}));
|
||||
|
||||
var node = comp.getDOMNode().querySelector(".screen-share-menu > li:last-child");
|
||||
expect(node.classList.contains("disabled")).eql(true);
|
||||
});
|
||||
|
||||
it("should dispatch a EndScreenShare action on click when the state is active",
|
||||
function() {
|
||||
var comp = TestUtils.renderIntoDocument(
|
||||
React.createElement(sharedViews.ScreenShareControlButton, {
|
||||
dispatcher: dispatcher,
|
||||
visible: true,
|
||||
state: SCREEN_SHARE_STATES.ACTIVE
|
||||
}));
|
||||
|
||||
TestUtils.Simulate.click(comp.getDOMNode().querySelector(".btn-screen-share"));
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.EndScreenShare({}));
|
||||
});
|
||||
});
|
||||
|
||||
describe("SettingsControlButton", function() {
|
||||
var requestStubs;
|
||||
var support_url = "https://support.com";
|
||||
|
@ -38,7 +38,6 @@
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
|
||||
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
|
||||
// Local helpers
|
||||
function returnTrue() {
|
||||
@ -743,7 +742,6 @@
|
||||
dispatcher: dispatcher,
|
||||
hangup: noop,
|
||||
publishStream: noop,
|
||||
screenShare: { state: SCREEN_SHARE_STATES.INACTIVE, visible: true},
|
||||
settingsMenuItems: [{ id: "feedback" }],
|
||||
show: true,
|
||||
video: { enabled: true, visible: true}})
|
||||
@ -751,14 +749,13 @@
|
||||
),
|
||||
React.createElement(FramedExample, {dashed: true,
|
||||
height: 56,
|
||||
summary: "Video muted, Screen share pending",
|
||||
summary: "Video muted",
|
||||
width: 300},
|
||||
React.createElement("div", {className: "fx-embedded"},
|
||||
React.createElement(ConversationToolbar, {audio: { enabled: true, visible: true},
|
||||
dispatcher: dispatcher,
|
||||
hangup: noop,
|
||||
publishStream: noop,
|
||||
screenShare: { state: SCREEN_SHARE_STATES.PENDING, visible: true},
|
||||
settingsMenuItems: [{ id: "feedback" }],
|
||||
show: true,
|
||||
video: { enabled: false, visible: true}})
|
||||
@ -766,14 +763,13 @@
|
||||
),
|
||||
React.createElement(FramedExample, {dashed: true,
|
||||
height: 56,
|
||||
summary: "Audio muted, Screen share active",
|
||||
summary: "Audio muted",
|
||||
width: 300},
|
||||
React.createElement("div", {className: "fx-embedded"},
|
||||
React.createElement(ConversationToolbar, {audio: { enabled: false, visible: true},
|
||||
dispatcher: dispatcher,
|
||||
hangup: noop,
|
||||
publishStream: noop,
|
||||
screenShare: { state: SCREEN_SHARE_STATES.ACTIVE, visible: true},
|
||||
settingsMenuItems: [{ id: "feedback" }],
|
||||
show: true,
|
||||
video: { enabled: true, visible: true}})
|
||||
|
@ -38,7 +38,6 @@
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
|
||||
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
|
||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||
|
||||
// Local helpers
|
||||
function returnTrue() {
|
||||
@ -743,7 +742,6 @@
|
||||
dispatcher={dispatcher}
|
||||
hangup={noop}
|
||||
publishStream={noop}
|
||||
screenShare={{ state: SCREEN_SHARE_STATES.INACTIVE, visible: true }}
|
||||
settingsMenuItems={[{ id: "feedback" }]}
|
||||
show={true}
|
||||
video={{ enabled: true, visible: true }} />
|
||||
@ -751,14 +749,13 @@
|
||||
</FramedExample>
|
||||
<FramedExample dashed={true}
|
||||
height={56}
|
||||
summary="Video muted, Screen share pending"
|
||||
summary="Video muted"
|
||||
width={300}>
|
||||
<div className="fx-embedded">
|
||||
<ConversationToolbar audio={{ enabled: true, visible: true }}
|
||||
dispatcher={dispatcher}
|
||||
hangup={noop}
|
||||
publishStream={noop}
|
||||
screenShare={{ state: SCREEN_SHARE_STATES.PENDING, visible: true }}
|
||||
settingsMenuItems={[{ id: "feedback" }]}
|
||||
show={true}
|
||||
video={{ enabled: false, visible: true }} />
|
||||
@ -766,14 +763,13 @@
|
||||
</FramedExample>
|
||||
<FramedExample dashed={true}
|
||||
height={56}
|
||||
summary="Audio muted, Screen share active"
|
||||
summary="Audio muted"
|
||||
width={300}>
|
||||
<div className="fx-embedded">
|
||||
<ConversationToolbar audio={{ enabled: false, visible: true }}
|
||||
dispatcher={dispatcher}
|
||||
hangup={noop}
|
||||
publishStream={noop}
|
||||
screenShare={{ state: SCREEN_SHARE_STATES.ACTIVE, visible: true }}
|
||||
settingsMenuItems={[{ id: "feedback" }]}
|
||||
show={true}
|
||||
video={{ enabled: true, visible: true }} />
|
||||
|
@ -104,10 +104,6 @@ mute_local_audio_button_title=Mute your audio
|
||||
unmute_local_audio_button_title=Unmute your audio
|
||||
mute_local_video_button_title2=Disable video
|
||||
unmute_local_video_button_title2=Enable video
|
||||
active_screenshare_button_title=Stop sharing
|
||||
inactive_screenshare_button_title=Share your screen
|
||||
share_tabs_button_title2=Share your Tabs
|
||||
share_windows_button_title=Share other Windows
|
||||
self_view_hidden_message=Self-view hidden but still being sent; resize window to show
|
||||
|
||||
|
||||
|