зеркало из https://github.com/nextcloud/spreed.git
Merge pull request #1326 from nextcloud/extract-view-for-media-controls
Extract view for media controls
This commit is contained in:
Коммит
62ec5d202c
|
@ -107,10 +107,6 @@
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.app-navigation-entry-menu li {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.participantWithList .avatar,
|
||||
#app-navigation .avatar,
|
||||
#app-navigation .icon-contacts-dark,
|
||||
|
|
306
js/app.js
306
js/app.js
|
@ -73,13 +73,7 @@
|
|||
_participants: null,
|
||||
/** @property {OCA.SpreedMe.Views.ParticipantView} _participantsView */
|
||||
_participantsView: null,
|
||||
/** @property {boolean} videoWasEnabledAtLeastOnce */
|
||||
videoWasEnabledAtLeastOnce: false,
|
||||
displayedGuestNameHint: false,
|
||||
audioDisabled: localStorage.getItem("audioDisabled"),
|
||||
audioNotFound: false,
|
||||
videoDisabled: localStorage.getItem("videoDisabled"),
|
||||
videoNotFound: false,
|
||||
fullscreenDisabled: true,
|
||||
_searchTerm: '',
|
||||
guestNick: null,
|
||||
|
@ -212,35 +206,6 @@
|
|||
},
|
||||
|
||||
registerLocalVideoButtonHandlers: function() {
|
||||
$('#hideVideo').click(function() {
|
||||
if(!OCA.SpreedMe.app.videoWasEnabledAtLeastOnce) {
|
||||
// don't allow clicking the video toggle
|
||||
// when no video ever was streamed (that
|
||||
// means that permission wasn't granted
|
||||
// yet or there is no video available at
|
||||
// all)
|
||||
console.log('video can not be enabled - there was no stream available before');
|
||||
return;
|
||||
}
|
||||
if ($(this).hasClass('video-disabled')) {
|
||||
OCA.SpreedMe.app.enableVideo();
|
||||
localStorage.removeItem("videoDisabled");
|
||||
} else {
|
||||
OCA.SpreedMe.app.disableVideo();
|
||||
localStorage.setItem("videoDisabled", true);
|
||||
}
|
||||
});
|
||||
|
||||
$('#mute').click(function() {
|
||||
if (OCA.SpreedMe.webrtc.webrtc.isAudioEnabled()) {
|
||||
OCA.SpreedMe.app.disableAudio();
|
||||
localStorage.setItem("audioDisabled", true);
|
||||
} else {
|
||||
OCA.SpreedMe.app.enableAudio();
|
||||
localStorage.removeItem("audioDisabled");
|
||||
}
|
||||
});
|
||||
|
||||
$('#video-fullscreen').click(function() {
|
||||
if (this.fullscreenDisabled) {
|
||||
this.enableFullscreen();
|
||||
|
@ -248,121 +213,6 @@
|
|||
this.disableFullscreen();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
$('#screensharing-button').click(function() {
|
||||
var webrtc = OCA.SpreedMe.webrtc;
|
||||
if (!webrtc.capabilities.supportScreenSharing) {
|
||||
if (window.location.protocol === 'https:') {
|
||||
OC.Notification.showTemporary(t('spreed', 'Screensharing is not supported by your browser.'));
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('spreed', 'Screensharing requires the page to be loaded through HTTPS.'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var splitShare = false;
|
||||
if (window.navigator.userAgent.match('Firefox')) {
|
||||
var ffver = parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1], 10);
|
||||
splitShare = (ffver >= 52);
|
||||
}
|
||||
|
||||
// The parent CSS of the menu list items is using "display:block !important",
|
||||
// so we need to also hide with "!important".
|
||||
if (webrtc.getLocalScreen()) {
|
||||
$('#share-screen-entry').attr('style','display:none !important');
|
||||
$('#share-window-entry').attr('style','display:none !important');
|
||||
$('#show-screen-entry').show();
|
||||
$('#stop-screen-entry').show();
|
||||
$('#screensharing-menu').toggleClass('open');
|
||||
} else {
|
||||
if (splitShare) {
|
||||
$('#share-screen-entry').show();
|
||||
$('#share-window-entry').show();
|
||||
$('#show-screen-entry').attr('style','display:none !important');
|
||||
$('#stop-screen-entry').attr('style','display:none !important');
|
||||
$('#screensharing-menu').toggleClass('open');
|
||||
return;
|
||||
}
|
||||
|
||||
this.startShareScreen();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
$("#share-screen-button").on('click', function() {
|
||||
var webrtc = OCA.SpreedMe.webrtc;
|
||||
if (!webrtc.getLocalScreen()) {
|
||||
this.startShareScreen('screen');
|
||||
}
|
||||
$('#screensharing-menu').toggleClass('open', false);
|
||||
}.bind(this));
|
||||
|
||||
$("#share-window-button").on('click', function() {
|
||||
var webrtc = OCA.SpreedMe.webrtc;
|
||||
if (!webrtc.getLocalScreen()) {
|
||||
this.startShareScreen('window');
|
||||
}
|
||||
$('#screensharing-menu').toggleClass('open', false);
|
||||
}.bind(this));
|
||||
|
||||
$("#show-screen-button").on('click', function() {
|
||||
var webrtc = OCA.SpreedMe.webrtc;
|
||||
if (webrtc.getLocalScreen()) {
|
||||
var currentUser = OCA.SpreedMe.webrtc.connection.getSessionid();
|
||||
OCA.SpreedMe.sharedScreens.switchScreenToId(currentUser);
|
||||
}
|
||||
$('#screensharing-menu').toggleClass('open', false);
|
||||
}.bind(this));
|
||||
|
||||
$("#stop-screen-button").on('click', function() {
|
||||
OCA.SpreedMe.webrtc.stopScreenShare();
|
||||
});
|
||||
},
|
||||
|
||||
startShareScreen: function(mode) {
|
||||
var webrtc = OCA.SpreedMe.webrtc;
|
||||
var screensharingButton = $('#screensharing-button');
|
||||
screensharingButton.prop('disabled', true);
|
||||
webrtc.shareScreen(mode, function(err) {
|
||||
screensharingButton.prop('disabled', false);
|
||||
if (!err) {
|
||||
$('#screensharing-button').attr('data-original-title', t('spreed', 'Screensharing options'))
|
||||
.removeClass('screensharing-disabled icon-screen-off')
|
||||
.addClass('icon-screen');
|
||||
return;
|
||||
}
|
||||
|
||||
switch (err.name) {
|
||||
case "HTTPS_REQUIRED":
|
||||
OC.Notification.showTemporary(t('spreed', 'Screensharing requires the page to be loaded through HTTPS.'));
|
||||
break;
|
||||
case "PERMISSION_DENIED":
|
||||
case "NotAllowedError":
|
||||
case "CEF_GETSCREENMEDIA_CANCELED": // Experimental, may go away in the future.
|
||||
break;
|
||||
case "FF52_REQUIRED":
|
||||
OC.Notification.showTemporary(t('spreed', 'Sharing your screen only works with Firefox version 52 or newer.'));
|
||||
break;
|
||||
case "EXTENSION_UNAVAILABLE":
|
||||
var extensionURL = null;
|
||||
if (!!window.chrome && !!window.chrome.webstore) {// Chrome
|
||||
extensionURL = 'https://chrome.google.com/webstore/detail/screensharing-for-nextclo/kepnpjhambipllfmgmbapncekcmabkol';
|
||||
}
|
||||
|
||||
if (extensionURL) {
|
||||
var text = t('spreed', 'Screensharing extension is required to share your screen.');
|
||||
var element = $('<a>').attr('href', extensionURL).attr('target','_blank').text(text);
|
||||
|
||||
OC.Notification.showTemporary(element, {isHTML: true});
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('spreed', 'Please use a different browser like Firefox or Chrome to share your screen.'));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
OC.Notification.showTemporary(t('spreed', 'An error occurred while starting screensharing.'));
|
||||
console.log("Could not start screensharing", err);
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_onKeyUp: function(event) {
|
||||
|
@ -380,19 +230,11 @@
|
|||
switch (key) {
|
||||
case 86: // 'v'
|
||||
event.preventDefault();
|
||||
if (this.videoDisabled) {
|
||||
this.enableVideo();
|
||||
} else {
|
||||
this.disableVideo();
|
||||
}
|
||||
this._mediaControlsView.toggleVideo();
|
||||
break;
|
||||
case 77: // 'm'
|
||||
event.preventDefault();
|
||||
if (this.audioDisabled) {
|
||||
this.enableAudio();
|
||||
} else {
|
||||
this.disableAudio();
|
||||
}
|
||||
this._mediaControlsView.toggleAudio();
|
||||
break;
|
||||
case 70: // 'f'
|
||||
event.preventDefault();
|
||||
|
@ -708,6 +550,14 @@
|
|||
$('#emptycontent').show();
|
||||
});
|
||||
|
||||
this._mediaControlsView = new OCA.SpreedMe.Views.MediaControlsView({
|
||||
app: this,
|
||||
webrtc: OCA.SpreedMe.webrtc,
|
||||
sharedScreens: OCA.SpreedMe.sharedScreens,
|
||||
});
|
||||
this._mediaControlsView.render();
|
||||
$('#localVideoContainer .nameIndicator').replaceWith(this._mediaControlsView.$el);
|
||||
|
||||
$(document).on('click', this.onDocumentClick);
|
||||
OC.Util.History.addOnPopStateHandler(_.bind(this._onPopState, this));
|
||||
},
|
||||
|
@ -771,6 +621,8 @@
|
|||
setupWebRTC: function() {
|
||||
if (!OCA.SpreedMe.webrtc) {
|
||||
OCA.SpreedMe.initWebRTC(this);
|
||||
this._mediaControlsView.setWebRtc(OCA.SpreedMe.webrtc);
|
||||
this._mediaControlsView.setSharedScreens(OCA.SpreedMe.sharedScreens);
|
||||
}
|
||||
|
||||
if (!OCA.SpreedMe.webrtc.capabilities.support) {
|
||||
|
@ -792,23 +644,14 @@
|
|||
|
||||
localMediaChannel.trigger('startLocalMedia');
|
||||
},
|
||||
startWithoutLocalMedia: function(isAudioEnabled, isVideoEnabled) {
|
||||
startWithoutLocalMedia: function(configuration) {
|
||||
if (this.callbackAfterMedia) {
|
||||
this.callbackAfterMedia(null);
|
||||
this.callbackAfterMedia = null;
|
||||
}
|
||||
|
||||
$('.videoView').removeClass('hidden');
|
||||
|
||||
this.disableAudio();
|
||||
if (!isAudioEnabled) {
|
||||
this.hasNoAudio();
|
||||
}
|
||||
|
||||
this.disableVideo();
|
||||
if (!isVideoEnabled) {
|
||||
this.hasNoVideo();
|
||||
}
|
||||
this.initAudioVideoSettings(configuration);
|
||||
|
||||
if (OCA.SpreedMe.webrtc.capabilities.support) {
|
||||
localMediaChannel.trigger('startWithoutLocalMedia');
|
||||
|
@ -825,17 +668,30 @@
|
|||
uiChannel.trigger('document:click', event);
|
||||
},
|
||||
initAudioVideoSettings: function(configuration) {
|
||||
if (this.audioDisabled) {
|
||||
this.disableAudio();
|
||||
if (configuration.audio !== false) {
|
||||
this._mediaControlsView.hasAudio();
|
||||
|
||||
if (this._mediaControlsView.audioDisabled) {
|
||||
this._mediaControlsView.disableAudio();
|
||||
} else {
|
||||
this._mediaControlsView.enableAudio();
|
||||
}
|
||||
} else {
|
||||
this._mediaControlsView.disableAudio();
|
||||
this._mediaControlsView.hasNoAudio();
|
||||
}
|
||||
|
||||
if (configuration.video !== false) {
|
||||
if (this.videoDisabled) {
|
||||
this._mediaControlsView.hasVideo();
|
||||
|
||||
if (this._mediaControlsView.videoDisabled) {
|
||||
this.disableVideo();
|
||||
} else {
|
||||
this.enableVideo();
|
||||
}
|
||||
} else {
|
||||
this.videoWasEnabledAtLeastOnce = false;
|
||||
this.disableVideo();
|
||||
this._mediaControlsView.hasNoVideo();
|
||||
}
|
||||
},
|
||||
enableFullscreen: function() {
|
||||
|
@ -869,83 +725,21 @@
|
|||
|
||||
this.fullscreenDisabled = true;
|
||||
},
|
||||
enableAudioButton: function() {
|
||||
$('#mute').attr('data-original-title', t('spreed', 'Mute audio (m)'))
|
||||
.removeClass('audio-disabled icon-audio-off')
|
||||
.addClass('icon-audio');
|
||||
},
|
||||
enableAudio: function() {
|
||||
if (this.audioNotFound || !OCA.SpreedMe.webrtc) {
|
||||
return;
|
||||
}
|
||||
OCA.SpreedMe.webrtc.unmute();
|
||||
this.enableAudioButton();
|
||||
this.audioDisabled = false;
|
||||
},
|
||||
disableAudioButton: function() {
|
||||
$('#mute').attr('data-original-title', t('spreed', 'Unmute audio (m)'))
|
||||
.addClass('audio-disabled icon-audio-off')
|
||||
.removeClass('icon-audio');
|
||||
},
|
||||
disableAudio: function() {
|
||||
if (this.audioNotFound || !OCA.SpreedMe.webrtc) {
|
||||
return;
|
||||
}
|
||||
OCA.SpreedMe.webrtc.mute();
|
||||
this.disableAudioButton();
|
||||
this.audioDisabled = true;
|
||||
},
|
||||
hasAudio: function() {
|
||||
$('#mute').removeClass('no-audio-available');
|
||||
this.enableAudioButton();
|
||||
this.audioNotFound = false;
|
||||
},
|
||||
hasNoAudio: function() {
|
||||
$('#mute').removeClass('audio-disabled icon-audio')
|
||||
.addClass('no-audio-available icon-audio-off')
|
||||
.attr('data-original-title', t('spreed', 'No audio'));
|
||||
this.audioDisabled = true;
|
||||
this.audioNotFound = true;
|
||||
},
|
||||
enableVideoUI: function() {
|
||||
var $hideVideoButton = $('#hideVideo');
|
||||
var $audioMuteButton = $('#mute');
|
||||
var $screensharingButton = $('#screensharing-button');
|
||||
var avatarContainer = $hideVideoButton.closest('.videoView').find('.avatar-container');
|
||||
var localVideo = $hideVideoButton.closest('.videoView').find('#localVideo');
|
||||
|
||||
$hideVideoButton.attr('data-original-title', t('spreed', 'Disable video (v)'))
|
||||
.removeClass('local-video-disabled video-disabled icon-video-off')
|
||||
.addClass('icon-video');
|
||||
$audioMuteButton.removeClass('local-video-disabled');
|
||||
$screensharingButton.removeClass('local-video-disabled');
|
||||
var avatarContainer = this._mediaControlsView.$el.closest('.videoView').find('.avatar-container');
|
||||
var localVideo = this._mediaControlsView.$el.closest('.videoView').find('#localVideo');
|
||||
|
||||
avatarContainer.hide();
|
||||
localVideo.show();
|
||||
},
|
||||
enableVideo: function() {
|
||||
if (this.videoNotFound || !OCA.SpreedMe.webrtc) {
|
||||
return;
|
||||
}
|
||||
|
||||
OCA.SpreedMe.webrtc.resumeVideo();
|
||||
if (this._mediaControlsView.enableVideo()) {
|
||||
this.enableVideoUI();
|
||||
this.videoDisabled = false;
|
||||
}
|
||||
},
|
||||
hideVideo: function() {
|
||||
var $hideVideoButton = $('#hideVideo');
|
||||
var $audioMuteButton = $('#mute');
|
||||
var $screensharingButton = $('#screensharing-button');
|
||||
var avatarContainer = $hideVideoButton.closest('.videoView').find('.avatar-container');
|
||||
var localVideo = $hideVideoButton.closest('.videoView').find('#localVideo');
|
||||
|
||||
if (!$hideVideoButton.hasClass('no-video-available')) {
|
||||
$hideVideoButton.attr('data-original-title', t('spreed', 'Enable video (v)'))
|
||||
.addClass('local-video-disabled video-disabled icon-video-off')
|
||||
.removeClass('icon-video');
|
||||
$audioMuteButton.addClass('local-video-disabled');
|
||||
$screensharingButton.addClass('local-video-disabled');
|
||||
}
|
||||
var avatarContainer = this._mediaControlsView.$el.closest('.videoView').find('.avatar-container');
|
||||
var localVideo = this._mediaControlsView.$el.closest('.videoView').find('#localVideo');
|
||||
|
||||
var avatar = avatarContainer.find('.avatar');
|
||||
var guestName = localStorage.getItem("nick");
|
||||
|
@ -965,31 +759,13 @@
|
|||
localVideo.hide();
|
||||
},
|
||||
disableVideo: function() {
|
||||
if (this.videoNotFound || !OCA.SpreedMe.webrtc) {
|
||||
return;
|
||||
}
|
||||
|
||||
OCA.SpreedMe.webrtc.pauseVideo();
|
||||
this._mediaControlsView.disableVideo();
|
||||
// Always hide the video, even if "disableVideo" returned "false".
|
||||
this.hideVideo();
|
||||
this.videoDisabled = true;
|
||||
},
|
||||
hasVideo: function() {
|
||||
$('#hideVideo').removeClass('no-video-available');
|
||||
this.enableVideoUI();
|
||||
this.videoNotFound = false;
|
||||
},
|
||||
hasNoVideo: function() {
|
||||
$('#hideVideo').removeClass('icon-video')
|
||||
.addClass('no-video-available icon-video-off')
|
||||
.attr('data-original-title', t('spreed', 'No Camera'));
|
||||
this.videoDisabled = true;
|
||||
this.videoNotFound = true;
|
||||
},
|
||||
// Called from webrtc.js
|
||||
disableScreensharingButton: function() {
|
||||
$('#screensharing-button').attr('data-original-title', t('spreed', 'Enable screensharing'))
|
||||
.addClass('screensharing-disabled icon-screen-off')
|
||||
.removeClass('icon-screen');
|
||||
$('#screensharing-menu').toggleClass('open', false);
|
||||
this._mediaControlsView.disableScreensharingButton();
|
||||
},
|
||||
setGuestName: function(name) {
|
||||
$.ajax({
|
||||
|
|
|
@ -74,37 +74,6 @@
|
|||
' <div class="avatar"></div>' +
|
||||
'</div>' +
|
||||
'<div class="nameIndicator">' +
|
||||
' <button id="mute" class="icon-audio icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="' + t('spreed', 'Mute audio (m)') + '"></button>' +
|
||||
' <button id="hideVideo" class="icon-video icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="' + t('spreed', 'Disable video (v)') + '"></button>' +
|
||||
' <button id="screensharing-button" class="app-navigation-entry-utils-menu-button icon-screen-off icon-white icon-shadow screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="' + t('spreed', 'Share screen') + '"></button>' +
|
||||
' <div id="screensharing-menu" class="app-navigation-entry-menu">' +
|
||||
' <ul>' +
|
||||
' <li id="share-screen-entry">' +
|
||||
' <button id="share-screen-button">' +
|
||||
' <span class="icon-screen"></span>' +
|
||||
' <span>' + t('spreed', 'Share whole screen') + '</span>' +
|
||||
' </button>' +
|
||||
' </li>' +
|
||||
' <li id="share-window-entry">' +
|
||||
' <button id="share-window-button">' +
|
||||
' <span class="icon-share-window"></span>' +
|
||||
' <span>' + t('spreed', 'Share a single window') + '</span>' +
|
||||
' </button>' +
|
||||
' </li>' +
|
||||
' <li id="show-screen-entry">' +
|
||||
' <button id="show-screen-button">' +
|
||||
' <span class="icon-screen"></span>' +
|
||||
' <span>' + t('spreed', 'Show your screen') + '</span>' +
|
||||
' </button>' +
|
||||
' </li>' +
|
||||
' <li id="stop-screen-entry">' +
|
||||
' <button id="stop-screen-button">' +
|
||||
' <span class="icon-screen-off"></span>' +
|
||||
' <span>' + t('spreed', 'Stop screensharing') + '</span>' +
|
||||
' </button>' +
|
||||
' </li>' +
|
||||
' </ul>' +
|
||||
' </div>' +
|
||||
'</div>');
|
||||
|
||||
OCA.SpreedMe.app._emptyContentView.destroy();
|
||||
|
@ -112,6 +81,8 @@
|
|||
el: '#talk-sidebar > #emptycontent'
|
||||
});
|
||||
|
||||
$('#localVideoContainer .nameIndicator').replaceWith(OCA.SpreedMe.app._mediaControlsView.$el);
|
||||
|
||||
OCA.SpreedMe.app.registerLocalVideoButtonHandlers();
|
||||
|
||||
$('body').addClass('talk-sidebar-enabled');
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
/* global Marionette, $ */
|
||||
|
||||
/**
|
||||
*
|
||||
* @copyright Copyright (c) 2018, Daniel Calviño Sánchez (danxuliu@gmail.com)
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
(function(OC, OCA, Marionette, $) {
|
||||
|
||||
'use strict';
|
||||
|
||||
OCA.SpreedMe = OCA.SpreedMe || {};
|
||||
OCA.Talk = OCA.Talk || {};
|
||||
OCA.SpreedMe.Views = OCA.SpreedMe.Views || {};
|
||||
OCA.Talk.Views = OCA.Talk.Views || {};
|
||||
|
||||
var MediaControlsView = Marionette.View.extend({
|
||||
|
||||
tagName: 'div',
|
||||
className: 'nameIndicator',
|
||||
|
||||
template: function(context) {
|
||||
// OCA.Talk.Views.Templates may not have been initialized when this
|
||||
// view is initialized, so the template can not be directly
|
||||
// assigned.
|
||||
return OCA.Talk.Views.Templates['mediacontrolsview'](context);
|
||||
},
|
||||
|
||||
templateContext: function() {
|
||||
return {
|
||||
muteAudioButtonTitle: t('spreed', 'Mute audio'),
|
||||
hideVideoButtonTitle: t('spreed', 'Disable video'),
|
||||
screensharingButtonTitle: t('spreed', 'Share screen'),
|
||||
shareScreenButtonTitle: t('spreed', 'Share whole screen'),
|
||||
shareWindowButtonTitle: t('spreed', 'Share a single window'),
|
||||
showScreenButtonTitle: t('spreed', 'Show your screen'),
|
||||
stopScreenButtonTitle: t('spreed', 'Stop screensharing')
|
||||
};
|
||||
},
|
||||
|
||||
ui: {
|
||||
'audioButton': '#mute',
|
||||
'videoButton': '#hideVideo',
|
||||
'screensharingButton': '#screensharing-button',
|
||||
'screensharingMenu': '#screensharing-menu',
|
||||
'shareScreenEntry': '#share-screen-entry',
|
||||
'shareScreenButton': '#share-screen-button',
|
||||
'shareWindowEntry': '#share-window-entry',
|
||||
'shareWindowButton': '#share-window-button',
|
||||
'showScreenEntry': '#show-screen-entry',
|
||||
'showScreenButton': '#show-screen-button',
|
||||
'stopScreenEntry': '#stop-screen-entry',
|
||||
'stopScreenButton': '#stop-screen-button',
|
||||
},
|
||||
|
||||
events: {
|
||||
'click @ui.audioButton': 'toggleAudio',
|
||||
'click @ui.videoButton': 'toggleVideo',
|
||||
'click @ui.screensharingButton': 'toggleScreensharingMenu',
|
||||
'click @ui.shareScreenButton': 'shareScreen',
|
||||
'click @ui.shareWindowButton': 'shareWindow',
|
||||
'click @ui.showScreenButton': 'showScreen',
|
||||
'click @ui.stopScreenButton': 'stopScreen',
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this._app = options.app;
|
||||
this._webrtc = options.webrtc;
|
||||
this._sharedScreens = options.sharedScreens;
|
||||
|
||||
this._audioNotFound = false;
|
||||
this._videoNotFound = false;
|
||||
|
||||
if (localStorage.getItem("audioDisabled")) {
|
||||
this.disableAudio();
|
||||
}
|
||||
|
||||
this._videoDisabled = localStorage.getItem("videoDisabled");
|
||||
},
|
||||
|
||||
setWebRtc: function(webrtc) {
|
||||
this._webrtc = webrtc;
|
||||
},
|
||||
|
||||
setSharedScreens: function(sharedScreens) {
|
||||
this._sharedScreens = sharedScreens;
|
||||
},
|
||||
|
||||
toggleAudio: function() {
|
||||
if (this.audioNotFound) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.audioDisabled) {
|
||||
this.disableAudio();
|
||||
localStorage.setItem("audioDisabled", true);
|
||||
} else {
|
||||
this.enableAudio();
|
||||
localStorage.removeItem("audioDisabled");
|
||||
}
|
||||
},
|
||||
|
||||
disableAudio: function() {
|
||||
if (this.audioNotFound || !this._webrtc) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webrtc.mute();
|
||||
|
||||
this.getUI('audioButton').attr('data-original-title', t('spreed', 'Unmute audio (m)'))
|
||||
.addClass('audio-disabled icon-audio-off')
|
||||
.removeClass('icon-audio');
|
||||
|
||||
this.audioDisabled = true;
|
||||
},
|
||||
|
||||
enableAudio: function() {
|
||||
if (this.audioNotFound || !this._webrtc) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webrtc.unmute();
|
||||
|
||||
this.getUI('audioButton').attr('data-original-title', t('spreed', 'Mute audio (m)'))
|
||||
.removeClass('audio-disabled icon-audio-off')
|
||||
.addClass('icon-audio');
|
||||
|
||||
this.audioDisabled = false;
|
||||
},
|
||||
|
||||
hasAudio: function() {
|
||||
this.getUI('audioButton').removeClass('no-audio-available');
|
||||
this.getUI('audioButton').attr('data-original-title', t('spreed', 'Mute audio (m)'))
|
||||
.removeClass('audio-disabled icon-audio-off')
|
||||
.addClass('icon-audio');
|
||||
|
||||
this.audioNotFound = false;
|
||||
},
|
||||
|
||||
hasNoAudio: function() {
|
||||
this.getUI('audioButton').removeClass('audio-disabled icon-audio')
|
||||
.addClass('no-audio-available icon-audio-off')
|
||||
.attr('data-original-title', t('spreed', 'No audio'));
|
||||
|
||||
this.audioDisabled = true;
|
||||
this.audioNotFound = true;
|
||||
},
|
||||
|
||||
toggleVideo: function() {
|
||||
if (this.videoNotFound) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.videoDisabled) {
|
||||
this._app.enableVideo();
|
||||
localStorage.removeItem("videoDisabled");
|
||||
} else {
|
||||
this._app.disableVideo();
|
||||
localStorage.setItem("videoDisabled", true);
|
||||
}
|
||||
},
|
||||
|
||||
disableVideo: function() {
|
||||
if (this.videoNotFound || !this._webrtc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._webrtc.pauseVideo();
|
||||
|
||||
if (!this.getUI('videoButton').hasClass('no-video-available')) {
|
||||
this.getUI('videoButton').attr('data-original-title', t('spreed', 'Enable video (v)'))
|
||||
.addClass('local-video-disabled video-disabled icon-video-off')
|
||||
.removeClass('icon-video');
|
||||
this.getUI('audioButton').addClass('local-video-disabled');
|
||||
this.getUI('screensharingButton').addClass('local-video-disabled');
|
||||
}
|
||||
|
||||
this.videoDisabled = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
enableVideo: function() {
|
||||
if (this.videoNotFound || !this._webrtc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._webrtc.resumeVideo();
|
||||
|
||||
this.getUI('videoButton').attr('data-original-title', t('spreed', 'Disable video (v)'))
|
||||
.removeClass('local-video-disabled video-disabled icon-video-off')
|
||||
.addClass('icon-video');
|
||||
this.getUI('audioButton').removeClass('local-video-disabled');
|
||||
this.getUI('screensharingButton').removeClass('local-video-disabled');
|
||||
|
||||
this.videoDisabled = false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
hasVideo: function() {
|
||||
this.getUI('videoButton').removeClass('no-video-available');
|
||||
|
||||
this.videoNotFound = false;
|
||||
},
|
||||
|
||||
hasNoVideo: function() {
|
||||
this.getUI('videoButton').removeClass('icon-video')
|
||||
.addClass('no-video-available icon-video-off')
|
||||
.attr('data-original-title', t('spreed', 'No Camera'));
|
||||
|
||||
this.videoDisabled = true;
|
||||
this.videoNotFound = true;
|
||||
},
|
||||
|
||||
toggleScreensharingMenu: function() {
|
||||
if (!this._webrtc.capabilities.supportScreenSharing) {
|
||||
if (window.location.protocol === 'https:') {
|
||||
OC.Notification.showTemporary(t('spreed', 'Screensharing is not supported by your browser.'));
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('spreed', 'Screensharing requires the page to be loaded through HTTPS.'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var splitShare = false;
|
||||
if (window.navigator.userAgent.match('Firefox')) {
|
||||
var ffver = parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1], 10);
|
||||
splitShare = (ffver >= 52);
|
||||
}
|
||||
|
||||
if (this._webrtc.getLocalScreen()) {
|
||||
this.getUI('shareScreenEntry').addClass('hidden');
|
||||
this.getUI('shareWindowEntry').addClass('hidden');
|
||||
this.getUI('showScreenEntry').removeClass('hidden');
|
||||
this.getUI('stopScreenEntry').removeClass('hidden');
|
||||
this.getUI('screensharingMenu').toggleClass('open');
|
||||
} else {
|
||||
if (splitShare) {
|
||||
this.getUI('shareScreenEntry').removeClass('hidden');
|
||||
this.getUI('shareWindowEntry').removeClass('hidden');
|
||||
this.getUI('showScreenEntry').addClass('hidden');
|
||||
this.getUI('stopScreenEntry').addClass('hidden');
|
||||
this.getUI('screensharingMenu').toggleClass('open');
|
||||
return;
|
||||
}
|
||||
|
||||
this.startShareScreen();
|
||||
}
|
||||
},
|
||||
|
||||
shareScreen: function() {
|
||||
if (!this._webrtc.getLocalScreen()) {
|
||||
this.startShareScreen('screen');
|
||||
}
|
||||
|
||||
this.getUI('screensharingMenu').toggleClass('open', false);
|
||||
},
|
||||
|
||||
shareWindow: function() {
|
||||
if (!this._webrtc.getLocalScreen()) {
|
||||
this.startShareScreen('window');
|
||||
}
|
||||
|
||||
this.getUI('screensharingMenu').toggleClass('open', false);
|
||||
},
|
||||
|
||||
showScreen: function() {
|
||||
if (this._webrtc.getLocalScreen()) {
|
||||
var currentUser = this._webrtc.connection.getSessionid();
|
||||
this._sharedScreens.switchScreenToId(currentUser);
|
||||
}
|
||||
|
||||
this.getUI('screensharingMenu').toggleClass('open', false);
|
||||
},
|
||||
|
||||
stopScreen: function() {
|
||||
this._webrtc.stopScreenShare();
|
||||
},
|
||||
|
||||
startShareScreen: function(mode) {
|
||||
this.getUI('screensharingButton').prop('disabled', true);
|
||||
|
||||
this._webrtc.shareScreen(mode, function(err) {
|
||||
this.getUI('screensharingButton').prop('disabled', false);
|
||||
if (!err) {
|
||||
this.getUI('screensharingButton').attr('data-original-title', t('spreed', 'Screensharing options'))
|
||||
.removeClass('screensharing-disabled icon-screen-off')
|
||||
.addClass('icon-screen');
|
||||
return;
|
||||
}
|
||||
|
||||
switch (err.name) {
|
||||
case "HTTPS_REQUIRED":
|
||||
OC.Notification.showTemporary(t('spreed', 'Screensharing requires the page to be loaded through HTTPS.'));
|
||||
break;
|
||||
case "PERMISSION_DENIED":
|
||||
case "NotAllowedError":
|
||||
case "CEF_GETSCREENMEDIA_CANCELED": // Experimental, may go away in the future.
|
||||
break;
|
||||
case "FF52_REQUIRED":
|
||||
OC.Notification.showTemporary(t('spreed', 'Sharing your screen only works with Firefox version 52 or newer.'));
|
||||
break;
|
||||
case "EXTENSION_UNAVAILABLE":
|
||||
var extensionURL = null;
|
||||
if (!!window.chrome && !!window.chrome.webstore) {// Chrome
|
||||
extensionURL = 'https://chrome.google.com/webstore/detail/screensharing-for-nextclo/kepnpjhambipllfmgmbapncekcmabkol';
|
||||
}
|
||||
|
||||
if (extensionURL) {
|
||||
var text = t('spreed', 'Screensharing extension is required to share your screen.');
|
||||
var element = $('<a>').attr('href', extensionURL).attr('target','_blank').text(text);
|
||||
|
||||
OC.Notification.showTemporary(element, {isHTML: true});
|
||||
} else {
|
||||
OC.Notification.showTemporary(t('spreed', 'Please use a different browser like Firefox or Chrome to share your screen.'));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
OC.Notification.showTemporary(t('spreed', 'An error occurred while starting screensharing.'));
|
||||
console.log("Could not start screensharing", err);
|
||||
break;
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
disableScreensharingButton: function() {
|
||||
this.getUI('screensharingButton').attr('data-original-title', t('spreed', 'Enable screensharing'))
|
||||
.addClass('screensharing-disabled icon-screen-off')
|
||||
.removeClass('icon-screen');
|
||||
this.getUI('screensharingMenu').toggleClass('open', false);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
OCA.SpreedMe.Views.MediaControlsView = MediaControlsView;
|
||||
|
||||
})(OC, OCA, Marionette, $);
|
|
@ -113,6 +113,25 @@ templates['chatview_comment'] = template({"1":function(container,depth0,helpers,
|
|||
+ ((stack1 = ((helper = (helper = helpers.formattedMessage || (depth0 != null ? depth0.formattedMessage : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"formattedMessage","hash":{},"data":data}) : helper))) != null ? stack1 : "")
|
||||
+ "</div>\n</li>\n";
|
||||
},"useData":true});
|
||||
templates['mediacontrolsview'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
|
||||
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
|
||||
|
||||
return "<button id=\"mute\" class=\"icon-audio icon-white icon-shadow\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\""
|
||||
+ alias4(((helper = (helper = helpers.muteAudioButtonTitle || (depth0 != null ? depth0.muteAudioButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"muteAudioButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "\"></button>\n<button id=\"hideVideo\" class=\"icon-video icon-white icon-shadow\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\""
|
||||
+ alias4(((helper = (helper = helpers.hideVideoButtonTitle || (depth0 != null ? depth0.hideVideoButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"hideVideoButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "\"></button>\n<button id=\"screensharing-button\" class=\"app-navigation-entry-utils-menu-button icon-screen-off icon-white icon-shadow screensharing-disabled\" data-placement=\"top\" data-toggle=\"tooltip\" data-original-title=\""
|
||||
+ alias4(((helper = (helper = helpers.screensharingButtonTitle || (depth0 != null ? depth0.screensharingButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"screensharingButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "\"></button>\n<div id=\"screensharing-menu\" class=\"app-navigation-entry-menu\">\n <ul>\n <li id=\"share-screen-entry\">\n <button id=\"share-screen-button\">\n <span class=\"icon-screen\"></span>\n <span>"
|
||||
+ alias4(((helper = (helper = helpers.shareScreenButtonTitle || (depth0 != null ? depth0.shareScreenButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareScreenButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "</span>\n </button>\n </li>\n <li id=\"share-window-entry\">\n <button id=\"share-window-button\">\n <span class=\"icon-share-window\"></span>\n <span>"
|
||||
+ alias4(((helper = (helper = helpers.shareWindowButtonTitle || (depth0 != null ? depth0.shareWindowButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareWindowButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "</span>\n </button>\n </li>\n <li id=\"show-screen-entry\">\n <button id=\"show-screen-button\">\n <span class=\"icon-screen\"></span>\n <span>"
|
||||
+ alias4(((helper = (helper = helpers.showScreenButtonTitle || (depth0 != null ? depth0.showScreenButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"showScreenButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "</span>\n </button>\n </li>\n <li id=\"stop-screen-entry\">\n <button id=\"stop-screen-button\">\n <span class=\"icon-screen-off\"></span>\n <span>"
|
||||
+ alias4(((helper = (helper = helpers.stopScreenButtonTitle || (depth0 != null ? depth0.stopScreenButtonTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"stopScreenButtonTitle","hash":{},"data":data}) : helper)))
|
||||
+ "</span>\n </button>\n </li>\n </ul>\n</div>\n";
|
||||
},"useData":true});
|
||||
templates['richobjectstringparser_filepreview'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
|
||||
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<button id="mute" class="icon-audio icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="{{muteAudioButtonTitle}}"></button>
|
||||
<button id="hideVideo" class="icon-video icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="{{hideVideoButtonTitle}}"></button>
|
||||
<button id="screensharing-button" class="app-navigation-entry-utils-menu-button icon-screen-off icon-white icon-shadow screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="{{screensharingButtonTitle}}"></button>
|
||||
<div id="screensharing-menu" class="app-navigation-entry-menu">
|
||||
<ul>
|
||||
<li id="share-screen-entry">
|
||||
<button id="share-screen-button">
|
||||
<span class="icon-screen"></span>
|
||||
<span>{{shareScreenButtonTitle}}</span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="share-window-entry">
|
||||
<button id="share-window-button">
|
||||
<span class="icon-share-window"></span>
|
||||
<span>{{shareWindowButtonTitle}}</span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="show-screen-entry">
|
||||
<button id="show-screen-button">
|
||||
<span class="icon-screen"></span>
|
||||
<span>{{showScreenButtonTitle}}</span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="stop-screen-entry">
|
||||
<button id="stop-screen-button">
|
||||
<span class="icon-screen-off"></span>
|
||||
<span>{{stopScreenButtonTitle}}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
27
js/webrtc.js
27
js/webrtc.js
|
@ -1024,7 +1024,7 @@ var spreedPeerConnectionTable = [];
|
|||
console.log('Error while accessing microphone & camera: ', error.message || error.name);
|
||||
}
|
||||
|
||||
app.startWithoutLocalMedia(webrtc.webrtc.isAudioEnabled(), webrtc.webrtc.isVideoEnabled());
|
||||
app.startWithoutLocalMedia({audio: false, video: false});
|
||||
OC.Notification.show(message, {
|
||||
type: 'error',
|
||||
timeout: 15,
|
||||
|
@ -1347,31 +1347,6 @@ var spreedPeerConnectionTable = [];
|
|||
OCA.SpreedMe.speakers.updateVideoContainerDummy(data.id);
|
||||
}
|
||||
});
|
||||
|
||||
OCA.SpreedMe.webrtc.on('localStream', function() {
|
||||
console.log('localStream');
|
||||
if (!app.videoWasEnabledAtLeastOnce) {
|
||||
app.videoWasEnabledAtLeastOnce = true;
|
||||
}
|
||||
|
||||
//Reset audio and video control panel
|
||||
app.hasAudio();
|
||||
app.hasVideo();
|
||||
|
||||
if (!app.videoDisabled) {
|
||||
app.enableVideo();
|
||||
}
|
||||
|
||||
if (!OCA.SpreedMe.webrtc.webrtc.isAudioEnabled()) {
|
||||
app.disableAudio();
|
||||
app.hasNoAudio();
|
||||
}
|
||||
|
||||
if (!OCA.SpreedMe.webrtc.webrtc.isVideoEnabled()) {
|
||||
app.disableVideo();
|
||||
app.hasNoVideo();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
OCA.SpreedMe.initWebRTC = initWebRTC;
|
||||
|
|
|
@ -95,6 +95,7 @@ class TemplateLoader {
|
|||
Util::addScript('spreed', 'views/chatview');
|
||||
Util::addScript('spreed', 'views/editabletextlabel');
|
||||
Util::addScript('spreed', 'views/emptycontentview');
|
||||
Util::addScript('spreed', 'views/mediacontrolsview');
|
||||
Util::addScript('spreed', 'views/participantlistview');
|
||||
Util::addScript('spreed', 'views/participantview');
|
||||
Util::addScript('spreed', 'views/richobjectstringparser');
|
||||
|
|
|
@ -30,6 +30,7 @@ script(
|
|||
'views/chatview',
|
||||
'views/editabletextlabel',
|
||||
'views/emptycontentview',
|
||||
'views/mediacontrolsview',
|
||||
'views/participantlistview',
|
||||
'views/participantview',
|
||||
'views/richobjectstringparser',
|
||||
|
@ -69,37 +70,6 @@ script(
|
|||
<div class="avatar"></div>
|
||||
</div>
|
||||
<div class="nameIndicator">
|
||||
<button id="mute" class="icon-audio icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Mute audio (m)')) ?>"></button>
|
||||
<button id="hideVideo" class="icon-video icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Disable video (v)')) ?>"></button>
|
||||
<button id="screensharing-button" class="app-navigation-entry-utils-menu-button icon-screen-off icon-white icon-shadow screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Share screen')) ?>"></button>
|
||||
<div id="screensharing-menu" class="app-navigation-entry-menu">
|
||||
<ul>
|
||||
<li id="share-screen-entry">
|
||||
<button id="share-screen-button">
|
||||
<span class="icon-screen"></span>
|
||||
<span><?php p($l->t('Share whole screen'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="share-window-entry">
|
||||
<button id="share-window-button">
|
||||
<span class="icon-share-window"></span>
|
||||
<span><?php p($l->t('Share a single window'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="show-screen-entry">
|
||||
<button id="show-screen-button">
|
||||
<span class="icon-screen"></span>
|
||||
<span><?php p($l->t('Show your screen'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="stop-screen-entry">
|
||||
<button id="stop-screen-button">
|
||||
<span class="icon-screen-off"></span>
|
||||
<span><?php p($l->t('Stop screensharing'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -29,6 +29,7 @@ script(
|
|||
'views/chatview',
|
||||
'views/editabletextlabel',
|
||||
'views/emptycontentview',
|
||||
'views/mediacontrolsview',
|
||||
'views/participantlistview',
|
||||
'views/participantview',
|
||||
'views/richobjectstringparser',
|
||||
|
@ -76,37 +77,6 @@ script(
|
|||
<div class="avatar"></div>
|
||||
</div>
|
||||
<div class="nameIndicator">
|
||||
<button id="mute" class="icon-audio icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Mute audio (m)')) ?>"></button>
|
||||
<button id="hideVideo" class="icon-video icon-white icon-shadow" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Disable video (v)')) ?>"></button>
|
||||
<button id="screensharing-button" class="app-navigation-entry-utils-menu-button icon-screen-off icon-white icon-shadow screensharing-disabled" data-placement="top" data-toggle="tooltip" data-original-title="<?php p($l->t('Share screen')) ?>"></button>
|
||||
<div id="screensharing-menu" class="app-navigation-entry-menu">
|
||||
<ul>
|
||||
<li id="share-screen-entry">
|
||||
<button id="share-screen-button">
|
||||
<span class="icon-screen"></span>
|
||||
<span><?php p($l->t('Share whole screen'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="share-window-entry">
|
||||
<button id="share-window-button">
|
||||
<span class="icon-share-window"></span>
|
||||
<span><?php p($l->t('Share a single window'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="show-screen-entry">
|
||||
<button id="show-screen-button">
|
||||
<span class="icon-screen"></span>
|
||||
<span><?php p($l->t('Show your screen'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
<li id="stop-screen-entry">
|
||||
<button id="stop-screen-button">
|
||||
<span class="icon-screen-off"></span>
|
||||
<span><?php p($l->t('Stop screensharing'));?></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Загрузка…
Ссылка в новой задаче