Merge branch 'bbb-2x-mconf' into next-dev

This commit is contained in:
Richard Alam 2017-09-12 10:29:44 -07:00
commit 5e318f7a0f
48 changed files with 1647 additions and 1418 deletions

View File

@ -304,7 +304,7 @@ phonecomponents|MuteMeButton {
}
.recordButtonStyleStart {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Record_On");
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Record_On");
}
.recordButtonStyleStop {
@ -437,11 +437,7 @@ users|BreakoutRoomSettings {
}
users|JoinBreakoutRoomWindow {
horizontalAlign : center;
iconRooms : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Join_Room");
paddingBottom : 24;
paddingTop : 0;
verticalGap : 18;
iconRooms : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Join_Room");
}
users|RoomActionsRenderer {
@ -495,7 +491,7 @@ users|RoomActionsRenderer {
textAlign : center;
}
.joinBreakoutRoomButton {
.joinBreakoutRoomButton, .retryUploadButton {
fillColorUp : #1070D7;
fillColorOver : #0A5EAC;
fillColorDown : #1070D7;
@ -1103,6 +1099,10 @@ mx|Panel {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Trash");
}
.presentationUploadProgressBar {
trackHeight : 12;
}
.presentationUploadButtonStyle {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Upload");
}
@ -1116,11 +1116,19 @@ mx|Panel {
disabledIcon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Left_Disabled");
}
.presentationBackButtonDisabledStyle {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Left_Disabled");
}
.presentationForwardButtonStyle {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Right");
disabledIcon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Right_Disabled");
}
.presentationForwardButtonDisabledStyle {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Arrow_Right_Disabled");
}
.presentationFitToWidthButtonStyle {
icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Fit_To_Width");
}
@ -1185,6 +1193,12 @@ mx|Panel {
color : #2A2D33;
}
.progressErrorLblStyle {
color : #DE2721;
fontSize : 16;
textAlign : center;
}
.presentationDownloadShowButtonStyle {
/* Normal state */
borderStyle : none;
@ -1378,17 +1392,14 @@ mx|Tab, .defaultTabStyle {
*/
mx|TitleWindow {
closeButtonDisabledSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Disabled");
closeButtonDownSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Down");
closeButtonOverSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Over");
closeButtonUpSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Up");
borderColor : #FFFFFF;
cornerRadius : 4;
roundedBottomCorners : true;
dropShadowEnabled : true;
shadowDistance : 0;
borderThickness : 1;
paddingTop : 5;
borderColor : #FFFFFF;
cornerRadius : 4;
roundedBottomCorners : true;
dropShadowEnabled : true;
shadowDistance : 0;
borderThickness : 1;
paddingTop : 10;
headerHeight : 0;
}
.titleWindowStyle {
@ -1398,6 +1409,13 @@ mx|TitleWindow {
paddingBottom : 8;
}
.titleWindowCloseButton {
disabledSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Disabled");
downSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Down");
overSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Over");
upSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Up");
}
/*
//------------------------------
// ToolTip

View File

@ -272,15 +272,18 @@ bbb.fileupload.uploadBtn = Upload
bbb.fileupload.uploadBtn.toolTip = Upload the selected file
bbb.fileupload.deleteBtn.toolTip = Delete Presentation
bbb.fileupload.showBtn = Show
bbb.fileupload.retry = Try another file
bbb.fileupload.showBtn.toolTip = Show Presentation
bbb.fileupload.okCancelBtn = Close
bbb.fileupload.okCancelBtn.toolTip = Close the File Upload dialog box
bbb.fileupload.close.tooltip = Close
bbb.fileupload.close.accessibilityName = Close the File Upload window
bbb.fileupload.genThumbText = Generating thumbnails..
bbb.fileupload.progBarLbl = Progress:
bbb.fileupload.fileFormatHint = Upload any office document or Portable Document Format (PDF) file. For best results upload PDF.
bbb.fileupload.letUserDownload = Enable download of presentation
bbb.fileupload.letUserDownload.tooltip = Check here if you want the other users to download your presentation
bbb.filedownload.title = Download the Presentations
bbb.filedownload.close.tooltip = Close
bbb.filedownload.close.accessibilityName = Close file download window
bbb.filedownload.fileLbl = Choose File to Download:
bbb.filedownload.downloadBtn = Download
bbb.filedownload.downloadBtn.toolTip = Download Presentation
@ -517,7 +520,9 @@ bbb.notes.saveBtn = Save
bbb.notes.saveBtn.toolTip = Save Note
bbb.sharedNotes.title = Shared notes
bbb.sharedNotes.quickLink.label = Shared notes Window
bbb.sharedNotes.name = Note name
bbb.sharedNotes.createNoteWindow.label = Note name
bbb.sharedNotes.createNoteWindow.close.tooltip = Close
bbb.sharedNotes.createNoteWindow.close.accessibilityName = Close create new note window
bbb.sharedNotes.typing.single = {0} is typing...
bbb.sharedNotes.typing.double = {0} and {1} are typing...
bbb.sharedNotes.typing.multiple = Several people are typing...
@ -821,6 +826,9 @@ bbb.users.breakout.confirm = Join A Breakout Room
bbb.users.breakout.invited = You have been invited to join <b>Breakout Room</b>
bbb.users.breakout.accept = By accepting, you will automatically leave the audio and the video conferences.
bbb.users.breakout.joinSession = Join Session
bbb.users.breakout.joinSession.accessibilityName = Join Breakout Room Session
bbb.users.breakout.joinSession.close.tooltip = Close
bbb.users.breakout.joinSession.close.accessibilityName = Close Join Breakout Room Window
bbb.users.breakout.youareinroom = You are in Breakout Room {0}
bbb.users.roomsGrid.room = Room
bbb.users.roomsGrid.users = Users

View File

@ -183,9 +183,9 @@ function createUA(username, server, callback, makeCallFunc) {
'password': data['password']
};
}) : [] );
stunsConfig['remoteIceCandidates'] = ( data['remoteIceCandidates'] ? data['remoteIceCandidates'].map(function(data) {
return data['ip'];
}) : [] );
//stunsConfig['remoteIceCandidates'] = ( data['remoteIceCandidates'] ? data['remoteIceCandidates'].map(function(data) {
// return data['ip'];
//}) : [] );
createUAWithStuns(username, server, callback, stunsConfig, makeCallFunc);
}).fail(function(data, textStatus, errorThrown) {
BBBLog.error("Could not fetch stun/turn servers", {error: textStatus, user: callerIdName, voiceBridge: conferenceVoiceBridge});
@ -211,7 +211,7 @@ function createUAWithStuns(username, server, callback, stunsConfig, makeCallFunc
userAgentString: "BigBlueButton",
stunServers: stunsConfig['stunServers'],
turnServers: stunsConfig['turnServers'],
artificialRemoteIceCandidates: stunsConfig['remoteIceCandidates']
//artificialRemoteIceCandidates: stunsConfig['remoteIceCandidates']
};
uaConnected = false;

1656
bigbluebutton-client/resources/prod/lib/sip.js Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -24,19 +24,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
initialize="init()"
creationComplete="creationCompleteHandler(event)"
layout="absolute"
close="onCancelClicked()"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
showCloseButton="true">
showCloseButton="false">
<fx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.Options;
@ -83,14 +80,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
}
private function creationCompleteHandler(event:FlexEvent):void
{
this.mx_internal::closeButton.toolTip = ResourceUtil.getInstance().getString('bbb.micSettings.cancel');
this.mx_internal::closeButton.accessibilityName = ResourceUtil.getInstance().getString('bbb.micSettings.cancel.toolTip');
tabIndexer.tabIndices.unshift(this.mx_internal::closeButton);
}
private function onMicClick():void {
LOGGER.debug("AudioSelectionWindow - Share Microphone Clicked");
var dispatcher:Dispatcher = new Dispatcher();
@ -127,14 +116,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</fx:Script>
<fx:Declarations>
<common:TabIndexer id="tabIndexer" startIndex="1" tabIndices="{[windowTitle, btnMicrophone, btnListenOnly]}"/>
<common:TabIndexer id="tabIndexer" startIndex="1" tabIndices="{[windowTitle, closeButton, btnMicrophone, btnListenOnly]}"/>
</fx:Declarations>
<mx:VBox width="100%" height="100%" paddingBottom="50" paddingLeft="80" paddingRight="80" paddingTop="0" horizontalAlign="center">
<mx:VBox width="100%" height="100%" paddingBottom="50" paddingLeft="80" paddingRight="80" paddingTop="15" horizontalAlign="center">
<common:AdvancedLabel id="windowTitle"
text="{ResourceUtil.getInstance().getString('bbb.audioSelection.title')}"
styleName="titleWindowStyle"
maxWidth="400" />
width="90%" />
<mx:Box width="100%" height="56"
verticalAlign="middle" horizontalAlign="center"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
@ -169,4 +158,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</mx:VBox>
</mx:HBox>
</mx:VBox>
<mx:Button id="closeButton" click="onCancelClicked()" styleName="titleWindowCloseButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.micSettings.cancel')}"
right="10" top="15"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.micSettings.cancel.toolTip')}" />
</mx:TitleWindow>

View File

@ -4,6 +4,7 @@
xmlns:common="org.bigbluebutton.common.*"
xmlns:mate="http://mate.asfusion.com/"
layout="vertical"
horizontalAlign="center"
showCloseButton="false"
minWidth="250"
creationComplete="init()">

View File

@ -217,10 +217,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:VBox id="webcamDisplay" width="100%" height="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5" styleName="cameraDisplaySettingsWindowBackground">
<mx:HBox width="100%" horizontalAlign="center">
<common:AdvancedLabel maxWidth="400"
text="{ResourceUtil.getInstance().getString('bbb.users.settings.webcamSettings')}"
styleName="titleWindowStyle"
id="textArea" />
<common:AdvancedLabel maxWidth="400"
text="{ResourceUtil.getInstance().getString('bbb.users.settings.webcamSettings')}"
styleName="titleWindowStyle"
id="textArea" />
</mx:HBox>
<mx:HRule width="100%"/>

View File

@ -36,8 +36,6 @@ $Id: $
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.controls.Button;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.core.model.LiveMeeting;

View File

@ -27,7 +27,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
horizontalAlign="center"
showCloseButton="false"
creationComplete="onCreationComplete()"
width="350"
minWidth="350"
title="{ResourceUtil.getInstance().getString('bbb.logout.confirm.title')}">
<fx:Script>

View File

@ -682,16 +682,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
handleExitApplicationEvent();
return;
}
var logoutWindow:LoggedOutWindow = PopUpUtil.createModalPopUp(mdiCanvas, LoggedOutWindow, false) as LoggedOutWindow;
if (logoutWindow) {
var loggedOutWindow:LoggedOutWindow = PopUpUtil.createModalPopUp(mdiCanvas, LoggedOutWindow, false) as LoggedOutWindow;
if (loggedOutWindow) {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
logoutWindow.x = point1.x - (logoutWindow.width / 2);
logoutWindow.y = point1.y - (logoutWindow.height / 2);
loggedOutWindow.x = point1.x - (loggedOutWindow.width / 2);
loggedOutWindow.y = point1.y - (loggedOutWindow.height / 2);
logoutWindow.setReason(reason);
loggedOutWindow.setReason(reason);
mdiCanvas.removeAllPopUps();
removeToolBars();
}
@ -757,9 +757,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function handleAddToolbarComponent(event:ToolbarButtonEvent):void {
if (event.location == ToolbarButtonEvent.BOTTOM_TOOLBAR) {
(event.button as UIComponent).tabIndex = tabIndexer.startIndex + addedBtns.numChildren + 10;
var newComponentTabIndex:int = tabIndexer.startIndex + addedBtns.numChildren + 10;
(event.button as UIComponent).tabIndex = newComponentTabIndex;
addedBtns.addChild(event.button as UIComponent);
//realignButtons();
//need to force the fullscreen button to be after it
fullScreenBtn.tabIndex = newComponentTabIndex + 1;
}
}
@ -888,7 +892,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<fx:Declarations>
<common:TabIndexer id="tabIndexer" startIndex="100000"
tabIndices="{[warningBtn, langSelector, logBtn]}"/>
tabIndices="{[warningBtn, langSelector, logBtn, fullScreenBtn]}"/>
</fx:Declarations>
<views:MainToolbar id="toolbar"

View File

@ -293,7 +293,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
var logoutWindow:LogoutWindow;
logoutWindow = LogoutWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, LogoutWindow, true));
var newX:Number = this.width - logoutWindow.width;
var newX:Number = this.width - logoutWindow.width - 5;
var newY:Number = btnLogout.y + btnLogout.height + 5;
PopUpManager.centerPopUp(logoutWindow);
@ -365,7 +365,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
numButtons++;
(event.button as UIComponent).tabIndex = quickLinksIndexer.startIndex + 5;
(event.button as UIComponent).tabIndex = quickLinksIndexer.startIndex + 6;
}
}
@ -486,6 +486,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function hideLogo():void {
logo.visible = logo.includeInLayout = false;
logoSperatator.visible = logo.includeInLayout = false;
}
private function addSettingsComponent(e:SettingsComponentEvent = null):void {
@ -508,7 +509,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</fx:Script>
<fx:Declarations>
<common:TabIndexer id="quickLinksIndexer" startIndex="102" tabIndices="{[usersLinkBtn, webcamLinkButton, presentationLinkBtn, chatLinkBtn, captionLinkBtn]}"/>
<common:TabIndexer id="quickLinksIndexer" startIndex="102" tabIndices="{[usersLinkBtn, webcamLinkButton, presentationLinkBtn, chatLinkBtn, captionLinkBtn, sharedNotesLinkBtn]}"/>
<common:TabIndexer id="buttonsIndexer" startIndex="{quickLinksIndexer.startIndex + numButtons + 10}"
tabIndices="{[recordBtn, webRTCAudioStatus, shortcutKeysBtn, helpBtn, btnLogout]}"/>
</fx:Declarations>
@ -528,7 +529,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:HBox id="topBox" width="100%" verticalAlign="middle" horizontalScrollPolicy="off" styleName="topBoxStyle">
<mx:HBox id="titleBox" width="40%" horizontalAlign="left" verticalAlign="middle" horizontalScrollPolicy="off">
<mx:Image id="logo" right="20" maxHeight="35" ioError="hideLogo()" />
<mx:VRule styleName="toolbarSeparator" height="10" />
<mx:VRule id="logoSperatator" styleName="toolbarSeparator" height="10" />
<mx:Label id="meetingNameLbl" minWidth="1" styleName="meetingNameLabelStyle" width="100%" truncateToFit="true"/>
</mx:HBox>
<mx:HBox id="actionBox" width="30%" horizontalAlign="center" verticalAlign="middle" horizontalScrollPolicy="off">

View File

@ -196,7 +196,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</fx:Script>
<fx:Declarations>
<common:TabIndexer id="tabIndexer" startIndex="1" tabIndices="{[usersList, cmbFontSize, chatNoiseCheckBox]}"/>
<common:TabIndexer id="tabIndexer" startIndex="1" tabIndices="{[usersList, cmbFontSize, chatNoiseCheckBox, saveBtn, copyBtn, clearBtn]}"/>
</fx:Declarations>
<mx:Label id="lblSelect" styleName="chatOptionsLabel"
@ -220,7 +220,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Label styleName="chatOptionsLabel"
text="{ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatwindow.audibleChatNotification')}"
width="100%"/>
<mx:CheckBox id="chatNoiseCheckBox" change="changeChatNoise()" />
<mx:CheckBox id="chatNoiseCheckBox" change="changeChatNoise()" accessibilityName="{ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatwindow.audibleChatNotification')}" />
</mx:HBox>
<mx:HBox width="100%">
<mx:Label styleName="chatOptionsLabel"

View File

@ -22,8 +22,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="350" layout="vertical"
showCloseButton="true"
close="PopUpUtil.removePopUp(this)"
close="onCloseClicked()"
show="{focusManager.setFocus(choiceFirst)}" xmlns:common="org.bigbluebutton.common.*">
<fx:Script>
<![CDATA[
@ -62,6 +61,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
return result;
}
private function onCloseClicked():void {
PopUpUtil.removePopUp(this);
}
]]>
</fx:Script>
@ -88,6 +90,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:HBox width="100%" horizontalGap="10" horizontalAlign="right">
<mx:Button id="publishButton" click="publishButton_clickHandler(event)"
label="{ResourceUtil.getInstance().getString('bbb.polling.startButton.label')}"/>
<mx:Button id="closeButton" click="onCloseClicked()"
label="{ResourceUtil.getInstance().getString('bbb.polling.closeButton.label')}"/>
</mx:HBox>
</mx:TitleWindow>

View File

@ -27,8 +27,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
layout="absolute"
width="580"
height="410"
showCloseButton="true"
close="{globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW))}"
close="onCancelClicked()"
initialize="initData();" >
<fx:Declarations>
@ -38,7 +37,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import org.bigbluebutton.modules.present.events.DownloadEvent;
import org.bigbluebutton.modules.present.model.PresentationModel;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -53,16 +52,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function initData():void {
downloadablePresentations = PresentationModel.getInstance().getDownloadablePresentations();
}
private function onCancelClicked():void {
globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW));
}
]]>
</fx:Script>
<mx:VBox width="100%"
height="100%"
horizontalAlign="center">
<common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.filedownload.title')}"
styleName="titleWindowStyle"
maxWidth="450" />
horizontalAlign="center"
paddingTop="15">
<mx:HBox width="100%">
<common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.filedownload.title')}"
styleName="titleWindowStyle"
width="100%" />
</mx:HBox>
<mx:List id="presentationNamesList"
allowMultipleSelection="false"
width="100%"
@ -76,4 +82,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
dataProvider="{downloadablePresentations}">
</mx:List>
</mx:VBox>
<mx:Button id="closeButton" click="onCancelClicked()" styleName="titleWindowCloseButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.filedownload.close.tooltip')}"
top="15" right="10"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.filedownload.close.accessibilityName')}" />
</mx:TitleWindow>

View File

@ -1,386 +1,412 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:TitleWindow xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mate="http://mate.asfusion.com/"
width="580"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
layout="absolute"
close="onCancelClicked()"
initialize="initData()"
creationComplete="onCreationComplete(event)" xmlns:common="org.bigbluebutton.common.*" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<mate:Dispatcher id="globalDispatch" />
<mate:Listener type="{UploadProgressEvent.UPLOAD_PROGRESS_UPDATE}" method="handleUploadProgressUpdate" />
<mate:Listener type="{UploadCompletedEvent.UPLOAD_COMPLETED}" method="handleUploadCompletedEvent" />
<mate:Listener type="{UploadIoErrorEvent.UPLOAD_IO_ERROR}" method="handleUploadIoError" />
<mate:Listener type="{UploadSecurityErrorEvent.UPLOAD_SECURITY_ERROR}" method="handleUploadSecurityError" />
<mate:Listener type="{ConversionCompletedEvent.CONVERSION_COMPLETED}" method="handleConversionCompleted" />
<mate:Listener type="{ConversionUpdateEvent.CONVERSION_UPDATE}" method="handleConvertUpdate" />
<mate:Listener type="{CreatingThumbnailsEvent.CREATING_THUMBNAILS}" method="handleThumbnailsProgressEvent" />
<mate:Listener type="{OfficeDocConvertFailedEvent.OFFICE_DOC_CONVERT_FAILED}" method="handleOfficeDocumentConversionFailed"/>
<mate:Listener type="{OfficeDocConvertInvalidEvent.OFFICE_DOC_CONVERT_INVALID}" method="handleOfficeDocumentConversionInvalid"/>
<mate:Listener type="{OfficeDocConvertSuccessEvent.OFFICE_DOC_CONVERT_SUCCESS}" method="handleOfficeDocumentConversionSuccess"/>
<mate:Listener type="{ConversionSupportedDocEvent.SUPPORTED_DOC}" method="handleSupportedDocument"/>
<mate:Listener type="{ConversionUnsupportedDocEvent.UNSUPPORTED_DOC}" method="handleUnsupportedDocument"/>
<mate:Listener type="{ConversionPageCountError.PAGE_COUNT_ERROR}" method="handlePageCountFailed"/>
<mate:Listener type="{ConversionPageCountMaxed.PAGE_COUNT_MAXED}" method="handlePageCountExceeded"/>
<mate:Listener type="{RemovePresentationEvent.PRESENTATION_REMOVED_EVENT}" method="handlePresentationRemoved" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import flash.utils.setTimeout;
import mx.collections.ArrayCollection;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.ListEvent;
import mx.utils.StringUtil;
import org.as3commons.lang.StringUtils;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.modules.present.commands.ChangePresentationCommand;
import org.bigbluebutton.modules.present.commands.UploadFileCommand;
import org.bigbluebutton.modules.present.events.ConversionCompletedEvent;
import org.bigbluebutton.modules.present.events.ConversionPageCountError;
import org.bigbluebutton.modules.present.events.ConversionPageCountMaxed;
import org.bigbluebutton.modules.present.events.ConversionSupportedDocEvent;
import org.bigbluebutton.modules.present.events.ConversionUnsupportedDocEvent;
import org.bigbluebutton.modules.present.events.ConversionUpdateEvent;
import org.bigbluebutton.modules.present.events.CreatingThumbnailsEvent;
import org.bigbluebutton.modules.present.events.OfficeDocConvertFailedEvent;
import org.bigbluebutton.modules.present.events.OfficeDocConvertInvalidEvent;
import org.bigbluebutton.modules.present.events.OfficeDocConvertSuccessEvent;
import org.bigbluebutton.modules.present.events.PresentationRollEvent;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.UploadCompletedEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.events.UploadIoErrorEvent;
import org.bigbluebutton.modules.present.events.UploadProgressEvent;
import org.bigbluebutton.modules.present.events.UploadSecurityErrorEvent;
import org.bigbluebutton.modules.present.model.PresentOptions;
import org.bigbluebutton.modules.present.model.Presentation;
import org.bigbluebutton.modules.present.model.PresentationModel;
import org.bigbluebutton.util.i18n.ResourceUtil;
use namespace mx_internal;
private static const LOGGER:ILogger = getClassLogger(FileUploadWindow);
[Bindable] private var presentationNamesAC:ArrayCollection;
[BIndable] public var maxFileSize:Number;
private var dispatcher:Dispatcher;
private var thumbnailTimer:Timer = new Timer(5000);
private var genThumbText:String = ResourceUtil.getInstance().getString('bbb.fileupload.genThumbText');
private var genThumbDots:String = ".";
private var fileToUpload:FileReference = new FileReference();
[Bindable] private var presentOptions:PresentOptions;
override public function move(x:Number, y:Number):void{
return;
}
protected function onCreationComplete(event:FlexEvent):void
{
dispatcher = new Dispatcher();
}
private function initData():void {
presentOptions = Options.getOptions(PresentOptions) as PresentOptions;
presentationNamesAC = PresentationModel.getInstance().getPresentations();
if (presentationNamesAC.length <= 0) {
selectFile();
}
}
private function handleThumbnailsProgressEvent(event:CreatingThumbnailsEvent):void {
genThumbDots = ".";
thumbnailTimer.repeatCount = 20;
thumbnailTimer.addEventListener(TimerEvent.TIMER, timerHandler);
thumbnailTimer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
thumbnailTimer.start();
}
private function handleConvertSuccessEvent(event:Event):void {
thumbnailTimer.stop();
}
private function timerHandler(e:TimerEvent):void{
displayGeneratingThumbnailsMessage();
}
private function completeHandler(e:TimerEvent):void {
displayGeneratingThumbnailsMessage();
thumbnailTimer.stop();
}
private function displayGeneratingThumbnailsMessage():void {
genThumbDots += ".";
buildProgressLabel(genThumbText + genThumbDots);
}
private function selectFile():void{
fileToUpload.addEventListener(Event.SELECT, onSelectFile);
fileToUpload.browse([
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.presentationfile'), "*.pdf;*.doc;*.docx;*.xls;*.xlsx;*.ppt;*.pptx;*.txt;*.rtf;*.odt;*.ods;*.odp;*.odg;*.odc;*.odi;*.jpg;*.png"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.pdf'), "*.pdf"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.word'), "*.doc;*.docx;*.odt;*.rtf;*.txt"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.excel'), "*.xls;*.xlsx;*.ods"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.powerpoint'), "*.ppt;*.pptx;*.odp"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.image'), "*.jpg;*.jpeg;*.png")]);
}
private function onSelectFile(e:Event):void{
lblFileName.text = fileToUpload.name;
uploadBtn.enabled = true;
}
private function startUpload():void {
currentState = "uploading";
var fileSize:Number = fileToUpload.size;
var maxFileSizeBytes:Number = maxFileSize * 1000000;
uploadedFilesList.enabled = false;
progressReportBox.visible = true;
progressBar.visible = true;
disableClosing();
selectBtn.enabled = false;
uploadBtn.enabled = false;
if (fileSize > maxFileSizeBytes) {
// Hardcode for now to 30M limit.
// This should be configurable to match what's allowed in nginx. (ralam feb 23, 2010)
var logData:Object = UsersUtil.initLogData();
logData.tags = ["presentation"];
logData.message = "File exceeds max limit.";
logData.fileSizeBytes = fileSize;
logData.maxFileSizeBytes = maxFileSizeBytes;
LOGGER.error(JSON.stringify(logData));
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert'));
} else {
var presentationName:String = StringUtil.trim(fileToUpload.name);
lblFileName.enabled = false;
var isDownloadable:Boolean = new Boolean(letUserDownload.selected);
var uploadCmd:UploadFileCommand = new UploadFileCommand();
uploadCmd.filename = presentationName;
uploadCmd.file = fileToUpload;
uploadCmd.isDownloadable = isDownloadable;
globalDispatch.dispatchEvent(uploadCmd);
letUserDownload.visible = false;
}
}
private function handleUploadProgressUpdate(e:UploadProgressEvent):void{
var progress:Number = e.percentUploaded;
buildProgressLabel(progress + "% " + ResourceUtil.getInstance().getString('bbb.presentation.uploaded'));
progressBar.setProgress(progress, 100);
progressBar.validateNow();
}
private function handleUploadCompletedEvent(e:UploadCompletedEvent):void{
buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.uploadcomplete'));
progressBar.setProgress(0, 100);
progressBar.validateNow();
selectBtn.visible = false;
uploadBtn.visible = false;
selectBtn.enabled = false;
uploadBtn.enabled = false;
lblFileName.visible = false;
}
private function handleOfficeDocumentConversionFailed(e:OfficeDocConvertFailedEvent):void {
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.failed'));
}
private function handleOfficeDocumentConversionInvalid(e:OfficeDocConvertInvalidEvent):void {
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.invalid'));
}
private function handleOfficeDocumentConversionSuccess(e:OfficeDocConvertSuccessEvent):void {
buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.document.converted'));
progressBar.setProgress(0, 100);
progressBar.validateNow();
}
private function handleSupportedDocument(e:ConversionSupportedDocEvent):void {
LOGGER.debug("handleSupportedDocument");
buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.document.supported'));
progressBar.setProgress(0, 100);
progressBar.validateNow();
}
private function handleUnsupportedDocument(e:ConversionUnsupportedDocEvent):void {
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.notsupported'));
}
private function handlePageCountFailed(e:ConversionPageCountError):void {
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.nbpage'));
}
private function handlePageCountExceeded(e:ConversionPageCountMaxed):void {
LOGGER.debug("handlePageCountExceeded");
enableClosing();
var message:String = " Maximum supported is " + e.maxPages;
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.maxnbpagereach'), message);
}
private function handleUploadIoError(e:UploadIoErrorEvent):void{
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.io'));
}
private function handleUploadSecurityError(e:UploadSecurityErrorEvent):void{
enableClosing();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.security'));
}
private function displayAlert(error:String, message:String = null):void {
currentState = "error";
progressErrorLbl.text = error;
if (!StringUtils.isEmpty(message)) {
progressErrorLbl.text += message;
}
}
private function handleConvertUpdate(e:ConversionUpdateEvent):void{
buildProgressLabel(ResourceUtil.getInstance().getString('bbb.presentation.converted',[e.numPagesDone, e.totalPages]));
progressBar.setProgress(e.numPagesDone, e.totalPages);
progressBar.validateNow();
}
private function buildProgressLabel(value:String) : void {
progressBar.label = ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl') + " " + value;
}
private function handleConversionCompleted(e:ConversionCompletedEvent):void{
enableClosing();
globalDispatch.dispatchEvent(new ChangePresentationCommand(e.presId));
globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW));
}
private function disableClosing():void {
this.closeButton2.enabled = false;
}
private function enableClosing():void {
uploadedFilesList.enabled = true;
this.closeButton2.enabled = true;
}
private function handlePresentationRemoved(e:RemovePresentationEvent):void {
for(var i:int = 0; i < presentationNamesAC.length; i++) {
if(e.presentationName == presentationNamesAC.getItemAt(i).id) {
presentationNamesAC.removeItemAt(i);
return;
}
}
}
private function onItemRollOver(event:ListEvent):void {
var item:IListItemRenderer = event.itemRenderer;
var presentation:Presentation = item.data as Presentation;
var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OVER, presentation.id);
dispatcher.dispatchEvent(rollEvent);
}
private function onItemRollOut(event:ListEvent):void {
var item:IListItemRenderer = event.itemRenderer;
var presentation:Presentation = item.data as Presentation;
var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OUT, presentation.id);
dispatcher.dispatchEvent(rollEvent);
}
private function onCancelClicked():void {
globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW));
}
private function retryButtonClikcHandler(event:MouseEvent):void {
globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW))
setTimeout(function():void {
globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.OPEN_UPLOAD_WINDOW))
}, 100);
}
]]>
</fx:Script>
<mx:states>
<s:State name="normal" />
<s:State name="uploading" />
<s:State name="error" />
</mx:states>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:TitleWindow xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mate="http://mate.asfusion.com/"
layout="absolute"
width="580"
height="410"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
showCloseButton="true"
close="globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW))"
initialize="initData()"
creationComplete="onCreationComplete(event)" xmlns:common="org.bigbluebutton.common.*">
<fx:Declarations>
<mate:Dispatcher id="globalDispatch" />
<mate:Listener type="{UploadProgressEvent.UPLOAD_PROGRESS_UPDATE}" method="handleUploadProgressUpdate" />
<mate:Listener type="{UploadCompletedEvent.UPLOAD_COMPLETED}" method="handleUploadCompletedEvent" />
<mate:Listener type="{UploadIoErrorEvent.UPLOAD_IO_ERROR}" method="handleUploadIoError" />
<mate:Listener type="{UploadSecurityErrorEvent.UPLOAD_SECURITY_ERROR}" method="handleUploadSecurityError" />
<mate:Listener type="{ConversionCompletedEvent.CONVERSION_COMPLETED}" method="handleConversionCompleted" />
<mate:Listener type="{ConversionUpdateEvent.CONVERSION_UPDATE}" method="handleConvertUpdate" />
<mate:Listener type="{CreatingThumbnailsEvent.CREATING_THUMBNAILS}" method="handleThumbnailsProgressEvent" />
<mate:Listener type="{OfficeDocConvertFailedEvent.OFFICE_DOC_CONVERT_FAILED}" method="handleOfficeDocumentConversionFailed"/>
<mate:Listener type="{OfficeDocConvertInvalidEvent.OFFICE_DOC_CONVERT_INVALID}" method="handleOfficeDocumentConversionInvalid"/>
<mate:Listener type="{OfficeDocConvertSuccessEvent.OFFICE_DOC_CONVERT_SUCCESS}" method="handleOfficeDocumentConversionSuccess"/>
<mate:Listener type="{ConversionSupportedDocEvent.SUPPORTED_DOC}" method="handleSupportedDocument"/>
<mate:Listener type="{ConversionUnsupportedDocEvent.UNSUPPORTED_DOC}" method="handleUnsupportedDocument"/>
<mate:Listener type="{ConversionPageCountError.PAGE_COUNT_ERROR}" method="handlePageCountFailed"/>
<mate:Listener type="{ConversionPageCountMaxed.PAGE_COUNT_MAXED}" method="handlePageCountExceeded"/>
<mate:Listener type="{RemovePresentationEvent.PRESENTATION_REMOVED_EVENT}" method="handlePresentationRemoved" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.ListEvent;
import mx.utils.StringUtil;
import org.as3commons.lang.StringUtils;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.modules.present.commands.ChangePresentationCommand;
import org.bigbluebutton.modules.present.commands.UploadFileCommand;
import org.bigbluebutton.modules.present.events.ConversionCompletedEvent;
import org.bigbluebutton.modules.present.events.ConversionPageCountError;
import org.bigbluebutton.modules.present.events.ConversionPageCountMaxed;
import org.bigbluebutton.modules.present.events.ConversionSupportedDocEvent;
import org.bigbluebutton.modules.present.events.ConversionUnsupportedDocEvent;
import org.bigbluebutton.modules.present.events.ConversionUpdateEvent;
import org.bigbluebutton.modules.present.events.CreatingThumbnailsEvent;
import org.bigbluebutton.modules.present.events.OfficeDocConvertFailedEvent;
import org.bigbluebutton.modules.present.events.OfficeDocConvertInvalidEvent;
import org.bigbluebutton.modules.present.events.OfficeDocConvertSuccessEvent;
import org.bigbluebutton.modules.present.events.PresentationRollEvent;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.UploadCompletedEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.events.UploadIoErrorEvent;
import org.bigbluebutton.modules.present.events.UploadProgressEvent;
import org.bigbluebutton.modules.present.events.UploadSecurityErrorEvent;
import org.bigbluebutton.modules.present.model.PresentOptions;
import org.bigbluebutton.modules.present.model.Presentation;
import org.bigbluebutton.modules.present.model.PresentationModel;
import org.bigbluebutton.util.i18n.ResourceUtil;
use namespace mx_internal;
private static const LOGGER:ILogger = getClassLogger(FileUploadWindow);
[Bindable] private var presentationNamesAC:ArrayCollection;
[BIndable] public var maxFileSize:Number;
private var dispatcher:Dispatcher;
private var thumbnailTimer:Timer = new Timer(5000);
private var genThumbText:String = ResourceUtil.getInstance().getString('bbb.fileupload.genThumbText');
private var genThumbDots:String = ".";
private var fileToUpload:FileReference = new FileReference();
[Bindable] private var presentOptions:PresentOptions;
override public function move(x:Number, y:Number):void{
return;
}
protected function onCreationComplete(event:FlexEvent):void
{
dispatcher = new Dispatcher();
this.mx_internal::closeButton.toolTip = ResourceUtil.getInstance().getString('bbb.fileupload.okCancelBtn.toolTip');
}
private function initData():void {
presentOptions = Options.getOptions(PresentOptions) as PresentOptions;
presentationNamesAC = PresentationModel.getInstance().getPresentations();
if (presentationNamesAC.length <= 0) {
selectFile();
}
}
private function handleThumbnailsProgressEvent(event:CreatingThumbnailsEvent):void {
genThumbDots = ".";
thumbnailTimer.repeatCount = 20;
thumbnailTimer.addEventListener(TimerEvent.TIMER, timerHandler);
thumbnailTimer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
thumbnailTimer.start();
}
private function handleConvertSuccessEvent(event:Event):void {
thumbnailTimer.stop();
}
private function timerHandler(e:TimerEvent):void{
displayGeneratingThumbnailsMessage();
}
private function completeHandler(e:TimerEvent):void {
displayGeneratingThumbnailsMessage();
thumbnailTimer.stop();
}
private function displayGeneratingThumbnailsMessage():void {
genThumbDots += ".";
progressBar.label = genThumbText + genThumbDots;
}
private function selectFile():void{
fileToUpload.addEventListener(Event.SELECT, onSelectFile);
fileToUpload.browse([
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.presentationfile'), "*.pdf;*.doc;*.docx;*.xls;*.xlsx;*.ppt;*.pptx;*.txt;*.rtf;*.odt;*.ods;*.odp;*.odg;*.odc;*.odi;*.jpg;*.png"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.pdf'), "*.pdf"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.word'), "*.doc;*.docx;*.odt;*.rtf;*.txt"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.excel'), "*.xls;*.xlsx;*.ods"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.powerpoint'), "*.ppt;*.pptx;*.odp"),
new FileFilter(ResourceUtil.getInstance().getString('bbb.presentation.uploadwindow.image'), "*.jpg;*.jpeg;*.png")]);
}
private function onSelectFile(e:Event):void{
lblFileName.text = fileToUpload.name;
uploadBtn.enabled = true;
}
private function startUpload():void {
var fileSize:Number = fileToUpload.size;
var maxFileSizeBytes:Number = maxFileSize * 1000000;
fileFormatHintLbl.visible = false;
fileFormatHintLbl.includeInLayout = false;
uploadedFilesList.enabled = false;
progressReportBox.visible = true;
progressBar.visible = true;
disableClosing();
selectBtn.enabled = false;
uploadBtn.enabled = false;
if (fileSize > maxFileSizeBytes) {
// Hardcode for now to 30M limit.
// This should be configurable to match what's allowed in nginx. (ralam feb 23, 2010)
var logData:Object = UsersUtil.initLogData();
logData.tags = ["presentation"];
logData.message = "File exceeds max limit.";
logData.fileSizeBytes = fileSize;
logData.maxFileSizeBytes = maxFileSizeBytes;
LOGGER.error(JSON.stringify(logData));
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert'));
} else {
var presentationName:String = StringUtil.trim(fileToUpload.name);
progBarLbl.visible = true;
lblFileName.enabled = false;
var isDownloadable:Boolean = new Boolean(letUserDownload.selected);
var uploadCmd:UploadFileCommand = new UploadFileCommand();
uploadCmd.filename = presentationName;
uploadCmd.file = fileToUpload;
uploadCmd.isDownloadable = isDownloadable;
globalDispatch.dispatchEvent(uploadCmd);
letUserDownload.visible = false;
}
}
private function handleUploadProgressUpdate(e:UploadProgressEvent):void{
var progress:Number = e.percentUploaded;
progressBar.label = progress + "% " + ResourceUtil.getInstance().getString('bbb.presentation.uploaded');
progressBar.setProgress(progress, 100);
progressBar.validateNow();
}
private function handleUploadCompletedEvent(e:UploadCompletedEvent):void{
progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.uploadcomplete');
progressBar.setProgress(0, 100);
progressBar.validateNow();
selectBtn.visible = false;
uploadBtn.visible = false;
selectBtn.enabled = false;
uploadBtn.enabled = false;
lblFileName.visible = false;
}
private function handleOfficeDocumentConversionFailed(e:OfficeDocConvertFailedEvent):void {
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.failed'));
}
private function handleOfficeDocumentConversionInvalid(e:OfficeDocConvertInvalidEvent):void {
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.document.convert.invalid'));
}
private function handleOfficeDocumentConversionSuccess(e:OfficeDocConvertSuccessEvent):void {
progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.document.converted');
progressBar.setProgress(0, 100);
progressBar.validateNow();
}
private function handleSupportedDocument(e:ConversionSupportedDocEvent):void {
LOGGER.debug("handleSupportedDocument");
progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.document.supported');
progressBar.setProgress(0, 100);
progressBar.validateNow();
}
private function handleUnsupportedDocument(e:ConversionUnsupportedDocEvent):void {
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.notsupported'));
}
private function handlePageCountFailed(e:ConversionPageCountError):void {
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.nbpage'));
}
private function handlePageCountExceeded(e:ConversionPageCountMaxed):void {
LOGGER.debug("handlePageCountExceeded");
enableControls();
var message:String = " Maximum supported is " + e.maxPages;
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.convert.maxnbpagereach'), message);
}
private function handleUploadIoError(e:UploadIoErrorEvent):void{
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.io'));
}
private function handleUploadSecurityError(e:UploadSecurityErrorEvent):void{
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.error.security'));
}
private function displayAlert(error:String, message:String = null):void {
progressBar.setStyle("color", 0xFF0000);
progressBar.label = error;
if (!StringUtils.isEmpty(message)) {
progressBar.label += message;
}
}
private function enableControls():void {
enableClosing();
selectBtn.enabled = true;
uploadBtn.enabled = true;
lblFileName.enabled = true;
letUserDownload.visible = true;
}
private function handleConvertUpdate(e:ConversionUpdateEvent):void{
progressBar.label = ResourceUtil.getInstance().getString('bbb.presentation.converted',[e.numPagesDone, e.totalPages]);
progressBar.setProgress(e.numPagesDone, e.totalPages);
progressBar.validateNow();
}
private function handleConversionCompleted(e:ConversionCompletedEvent):void{
enableClosing();
globalDispatch.dispatchEvent(new ChangePresentationCommand(e.presId));
globalDispatch.dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW));
}
private function disableClosing():void {
this.closeButton.enabled = false;
}
private function enableClosing():void {
this.closeButton.enabled = true;
}
private function handlePresentationRemoved(e:RemovePresentationEvent):void {
for(var i:int = 0; i < presentationNamesAC.length; i++) {
if(e.presentationName == presentationNamesAC.getItemAt(i).id) {
presentationNamesAC.removeItemAt(i);
return;
}
}
}
private function onItemRollOver(event:ListEvent):void {
var item:IListItemRenderer = event.itemRenderer;
var presentation:Presentation = item.data as Presentation;
var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OVER, presentation.id);
dispatcher.dispatchEvent(rollEvent);
}
private function onItemRollOut(event:ListEvent):void {
var item:IListItemRenderer = event.itemRenderer;
var presentation:Presentation = item.data as Presentation;
var rollEvent:PresentationRollEvent = new PresentationRollEvent(PresentationRollEvent.PRESENTATION_ROLL_OUT, presentation.id);
dispatcher.dispatchEvent(rollEvent);
}
]]>
</fx:Script>
<mx:VBox width="100%" height="100%" verticalAlign="top" horizontalAlign="center">
<common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.fileupload.title')}"
styleName="titleWindowStyle"
maxWidth="450" />
<mx:Box width="100%" height="100%" paddingLeft="5" paddingRight="5">
<mx:Box width="100%" height="100%" verticalAlign="middle" horizontalAlign="center" styleName="presentationUploadFileFormatHintBoxStyle">
<mx:Text width="100%" id="fileFormatHintLbl" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.fileupload.fileFormatHint')}" styleName="presentationUploadFileFormatHintTextStyle"/>
</mx:Box>
</mx:Box>
<mx:HBox id="fileUploadBox" width="100%" paddingLeft="5" paddingRight="5" paddingTop="5" verticalAlign="middle">
<mx:Label id="lblFileName" truncateToFit="true" width="{fileUploadBox.width-selectBtn.width-uploadBtn.width-30}" selectable="false" click="selectFile()" text="{ResourceUtil.getInstance().getString('bbb.fileupload.lblFileName.defaultText')}" />
<mx:Button id="selectBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.selectBtn.label')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.selectBtn.toolTip')}"
click="selectFile()" styleName="presentationUploadChooseFileButtonStyle"/>
<mx:Button id="uploadBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn')}"
styleName="uploadFileButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn.toolTip')}" click="startUpload()"
enabled="false"/>
</mx:HBox>
<mx:Box paddingLeft="5" paddingTop="5" visible="{presentOptions.enableDownload}" includeInLayout="{presentOptions.enableDownload}" >
<mx:CheckBox id="letUserDownload" label="{ResourceUtil.getInstance().getString('bbb.fileupload.letUserDownload')}" selected="false" toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.letUserDownload.tooltip')}"/>
</mx:Box>
<mx:HBox id="progressReportBox" width="100%" paddingLeft="10" paddingRight="10" paddingTop="5" paddingBottom="5" includeInLayout="true" visible="false">
<mx:Label id="progBarLbl" text="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"
styleName="presentationUploadProgressBarLabelStyle" visible="false"/>
<mx:ProgressBar id="progressBar" mode="manual" label="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"
styleName="presentationUploadProgressBarStyle" labelPlacement="center" width="100%" visible="false"/>
</mx:HBox>
<mx:Canvas width="100%" height="145" verticalScrollPolicy="off">
<mx:List height="142" left="5" top="5" right="5" bottom="5" id="uploadedFilesList" allowMultipleSelection="false"
itemRenderer="org.bigbluebutton.modules.present.ui.views.UploadedPresentationRenderer"
itemRollOver="onItemRollOver(event)" itemRollOut="onItemRollOut(event)"
dragEnabled="false" dataProvider="{presentationNamesAC}">
</mx:List>
</mx:Canvas>
</mx:VBox>
</mx:TitleWindow>
<mx:VBox width="100%" height="100%" verticalAlign="top" horizontalAlign="center" top="15">
<mx:HBox width="100%">
<common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.fileupload.title')}"
styleName="titleWindowStyle"
width="100%" />
</mx:HBox>
<mx:Box width="100%" height="100%" paddingLeft="5" paddingRight="5" includeIn="normal">
<mx:Box width="100%" height="100%" verticalAlign="middle" horizontalAlign="center" styleName="presentationUploadFileFormatHintBoxStyle">
<mx:Text width="100%" id="fileFormatHintLbl" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.fileupload.fileFormatHint')}" styleName="presentationUploadFileFormatHintTextStyle"/>
</mx:Box>
</mx:Box>
<mx:HBox id="fileUploadBox" width="100%" paddingLeft="5" paddingRight="5" paddingTop="5" verticalAlign="middle" includeIn="normal">
<mx:Label id="lblFileName" truncateToFit="true" width="{fileUploadBox.width-selectBtn.width-uploadBtn.width-30}" selectable="false" click="selectFile()" text="{ResourceUtil.getInstance().getString('bbb.fileupload.lblFileName.defaultText')}" />
<mx:Button id="selectBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.selectBtn.label')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.selectBtn.toolTip')}"
click="selectFile()" styleName="presentationUploadChooseFileButtonStyle"/>
<mx:Button id="uploadBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn')}"
styleName="uploadFileButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn.toolTip')}" click="startUpload()"
enabled="false"/>
</mx:HBox>
<mx:CheckBox id="letUserDownload" label="{ResourceUtil.getInstance().getString('bbb.fileupload.letUserDownload')}" selected="false" excludeFrom="error"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.letUserDownload.tooltip')}"
paddingLeft="5" paddingTop="5" visible="{presentOptions.enableDownload}" includeInLayout="{presentOptions.enableDownload}"/>
<mx:HBox id="progressReportBox" width="100%" paddingLeft="10" paddingRight="10" paddingTop="5" paddingBottom="5" verticalAlign="middle"
includeInLayout="true" visible="false" excludeFrom="error">
<mx:ProgressBar id="progressBar" mode="manual" label="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"
styleName="presentationUploadProgressBar" labelPlacement="top" width="100%" visible="false"/>
</mx:HBox>
<mx:VBox id="errorBox" paddingTop="5" paddingBottom="5" width="100%" horizontalAlign="center" includeIn="error">
<s:Label id="progressErrorLbl" styleName="progressErrorLblStyle" width="540"/>
<mx:Button id="retryButton" styleName="retryUploadButton"
label="{ResourceUtil.getInstance().getString('bbb.fileupload.retry')}" click="retryButtonClikcHandler(event)"/>
</mx:VBox>
<mx:Canvas width="100%" height="145" verticalScrollPolicy="off">
<mx:List height="160" left="5" top="5" right="5" bottom="5" id="uploadedFilesList" allowMultipleSelection="false"
itemRenderer="org.bigbluebutton.modules.present.ui.views.UploadedPresentationRenderer"
itemRollOver="onItemRollOver(event)" itemRollOut="onItemRollOut(event)"
dragEnabled="false" dataProvider="{presentationNamesAC}">
</mx:List>
</mx:Canvas>
</mx:VBox>
<mx:Button id="closeButton2" click="onCancelClicked()" styleName="titleWindowCloseButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.close.tooltip')}"
top="15" right="10"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.fileupload.close.accessibilityName')}" />
</mx:TitleWindow>

View File

@ -393,11 +393,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function disableSlideNavigationButtons(pageNumber:int):void {
backButton.mouseEnabled = pageNumber != 1;
forwardButton.mouseEnabled = pageNumber < PresentationModel.getInstance().getNumberOfPages();
// We use mouseEnabled here instead of enabled because the tab position gets lost when going through
//the pages. Please don't change this if you don't know why this is.
if (pageNumber != 1) {
backButton.mouseEnabled = true;
backButton.styleName = "presentationBackButtonStyle";
} else {
backButton.mouseEnabled = false;
backButton.styleName = "presentationBackButtonDisabledStyle";
}
backButton.enabled = pageNumber != 1;
forwardButton.enabled = pageNumber < PresentationModel.getInstance().getNumberOfPages();
if (pageNumber < PresentationModel.getInstance().getNumberOfPages()) {
forwardButton.mouseEnabled = true;
forwardButton.styleName = "presentationForwardButtonStyle";
} else {
forwardButton.mouseEnabled = false;
forwardButton.styleName = "presentationForwardButtonDisabledStyle";
}
}
private function displaySlideNumber(currentSlide:int):void {
@ -428,11 +440,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function goToPreviousSlide():void {
dispatchEvent(new GoToPrevPageCommand());
if (PresentationModel.getInstance().getCurrentPage().num > 1) {
dispatchEvent(new GoToPrevPageCommand());
}
}
private function goToNextSlide():void {
dispatchEvent(new GoToNextPageCommand());
if (PresentationModel.getInstance().getCurrentPage().num < PresentationModel.getInstance().getNumberOfPages()) {
dispatchEvent(new GoToNextPageCommand());
}
}
private function showPercentageInDataTip(val:String):String {
@ -502,7 +518,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function remotePrevious(e:ShortcutEvent):void{
if (backButton.visible && backButton.enabled){
if (backButton.visible){
//backButton.setFocus();
goToPreviousSlide();
}
@ -516,7 +532,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function remoteNext(e:ShortcutEvent):void{
if (forwardButton.visible && forwardButton.enabled){
if (forwardButton.visible){
//forwardButton.setFocus();
goToNextSlide();
}
@ -792,7 +808,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<fx:Declarations>
<pres:TabIndexer startIndex="{presentOptions.baseTabIndex + 1}"
tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, slideView.slideLoader, pollStartBtn, quickPollBtn, uploadPres, backButton, btnSlideNum, forwardButton, zoomSlider, btnFitToWidth, btnFitToPage]}"/>
tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, slideView.slideLoader, uploadPres, pollStartBtn, quickPollBtn, downloadPres, backButton, btnSlideNum, forwardButton, zoomSlider, btnFitToWidth, btnFitToPage]}"/>
<mx:Fade id="thumbFadeIn" alphaFrom="1" alphaTo="0" duration="100" />
<mx:Fade id="thumbFadeOut" alphaFrom="0" alphaTo="1" duration="100" />

View File

@ -26,12 +26,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
horizontalAlign="center"
showCloseButton="true"
close="onCancelClicked()"
layout="absolute"
creationComplete="onCreationComplete()"
keyUp="keyUpHandler(event)"
width="250"
title="{ResourceUtil.getInstance().getString('bbb.sharedNotes.name')}">
width="250" xmlns:common="org.bigbluebutton.common.*">
<fx:Script>
<![CDATA[
@ -80,19 +79,30 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
]]>
</fx:Script>
<mx:VBox width="100%" height="100%" paddingTop="15">
<common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.sharedNotes.createNoteWindow.label')}"
styleName="titleWindowStyle"
width="100%" />
<mx:HBox width="100%"
height="100%"
verticalAlign="middle">
<mx:TextInput id="textInput"
restrict="a-zA-Z0-9 "
maxChars="20"
width="100%"
text="{sharedNoteTitle}" />
<mx:Button id="btnNew"
click="btnNew_clickHandler(event)"
height="30"
label="{ResourceUtil.getInstance().getString('bbb.sharedNotes.new.label')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.sharedNotes.new.toolTip')}" />
</mx:HBox>
</mx:VBox>
<mx:Button id="closeButton" click="onCancelClicked()" styleName="titleWindowCloseButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.sharedNotes.createNoteWindow.close.tooltip')}"
top="15" right="10"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.sharedNotes.createNoteWindow.close.accessibilityName')}" />
<mx:HBox width="100%"
height="100%"
verticalAlign="middle">
<mx:TextInput id="textInput"
restrict="a-zA-Z0-9 "
maxChars="20"
width="100%"
text="{sharedNoteTitle}" />
<mx:Button id="btnNew"
click="btnNew_clickHandler(event)"
height="30"
label="{ResourceUtil.getInstance().getString('bbb.sharedNotes.new.label')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.sharedNotes.new.toolTip')}" />
</mx:HBox>
</mx:TitleWindow>

View File

@ -23,10 +23,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
layout="vertical"
showCloseButton="true"
close="PopUpUtil.removePopUp(this)"
width="600">
close="onCloseClick()"
layout="absolute"
width="600" xmlns:common="org.bigbluebutton.common.*">
<fx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
@ -53,29 +52,41 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
navigateToURL(new URLRequest(this.joinUrl), "_blank");
PopUpUtil.removePopUp(this);
}
private function onCloseClick():void {
PopUpUtil.removePopUp(this);
}
]]>
</fx:Script>
<s:Label styleName="titleWindowStyle"
maxWidth="500"
text="{ResourceUtil.getInstance().getString('bbb.users.breakout.confirm')}" />
<mx:Label htmlText="{ResourceUtil.getInstance().getString('bbb.users.breakout.invited')}" />
<mx:Canvas>
<mx:Image source="{getStyle('iconRooms')}" />
<mx:Canvas x="16"
y="47"
height="38"
width="70">
<s:Label id="sequenceLabel"
styleName="roomNumberStyle"
verticalCenter="0"
horizontalCenter="0" />
<mx:VBox height="100%" width="100%" paddingTop="15" paddingBottom="15" verticalGap="15" horizontalAlign="center">
<common:AdvancedLabel styleName="titleWindowStyle"
width="100%"
text="{ResourceUtil.getInstance().getString('bbb.users.breakout.confirm')}" />
<mx:Label htmlText="{ResourceUtil.getInstance().getString('bbb.users.breakout.invited')}" paddingTop="4" />
<mx:Canvas>
<mx:Image source="{getStyle('iconRooms')}" />
<mx:Canvas x="16"
y="47"
height="38"
width="70">
<s:Label id="sequenceLabel"
styleName="roomNumberStyle"
verticalCenter="0"
horizontalCenter="0" />
</mx:Canvas>
</mx:Canvas>
</mx:Canvas>
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.users.breakout.accept')}" />
<mx:Button id="joinButton"
label="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession')}"
click="joinButtonClickHandler(event)"
styleName="joinBreakoutRoomButton" />
<s:Label width="100%" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.users.breakout.accept')}" />
<mx:Button id="joinButton"
label="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession')}"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession.accessibilityName')}"
click="joinButtonClickHandler(event)"
styleName="joinBreakoutRoomButton" />
</mx:VBox>
<mx:Button id="closeButton" click="onCloseClick()" styleName="titleWindowCloseButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession.close.tooltip')}"
top="15" right="10"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession.close.accessibilityName')}" />
</mx:TitleWindow>

View File

@ -1 +1 @@
BIGBLUEBUTTON_RELEASE=2.0.0-dev
BIGBLUEBUTTON_RELEASE=2.0.0-beta

View File

@ -13,6 +13,16 @@ function AutoClose() {
window.close();
}
function escapeHTML(text) {
if (text != null) {
return text.replace(/&/g, '').
replace(/</g, '').
replace(/"/g, '').
replace(/]/g, '').
replace(/'/g, '');
}
}
$(document).ready(function() {
var sClose = GetURLParameter('close');
var sErrors = GetURLParameter('errors');
@ -27,6 +37,7 @@ $(document).ready(function() {
// Render error messages
$.each(errors, function( index, error ) {
error.message = escapeHTML(error.message);
$("#messages").append("<div class='alert alert-danger fade in' style='margin-top:18px;'><a href='#' class='close' data-dismiss='alert' aria-label='close' title='close'>&times;</a><strong><span id='error-key'>Error:</span></strong>&nbsp;<span id='error-message'>"+error.message+"</span></div>");
});
$('#messages').removeClass('hidden');

View File

@ -13,13 +13,7 @@ export default function clearPublicChatHistory(credentials) {
const eventName = 'ClearPublicChatHistoryPubMsg';
const header = {
meetingId,
name: eventName,
userId: requesterUserId,
};
const payload = {};
const body = {};
return RedisPubSub.publish(CHANNEL, eventName, meetingId, body, header);
return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, { userId: requesterUserId });
}

View File

@ -50,11 +50,5 @@ export default function sendChat(credentials, message) {
eventName = 'SendPublicMessagePubMsg';
}
const header = {
meetingId,
name: eventName,
userId: requesterUserId,
};
return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, header);
return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, { userId: requesterUserId });
}

View File

@ -2,7 +2,11 @@ import RedisPubSub from '/imports/startup/server/redis2x';
import handleMeetingCreation from './handlers/meetingCreation';
import handleGetAllMeetings from './handlers/getAllMeetings';
import handleMeetingEnd from './handlers/meetingEnd';
import handleMeetingLocksChange from './handlers/meetingLockChange';
import handleUserLockChange from './handlers/userLockChange';
RedisPubSub.on('MeetingCreatedEvtMsg', handleMeetingCreation);
RedisPubSub.on('SyncGetMeetingInfoRespMsg', handleGetAllMeetings);
RedisPubSub.on('MeetingEndingEvtMsg', handleMeetingEnd);
RedisPubSub.on('LockSettingsInMeetingChangedEvtMsg', handleMeetingLocksChange);
RedisPubSub.on('UserLockedInMeetingEvtMsg', handleUserLockChange);

View File

@ -0,0 +1,6 @@
import changeLockSettings from '../modifiers/changeLockSettings';
export default function handleLockSettingsInMeeting({ body }, meetingId) {
return changeLockSettings(meetingId, body);
}

View File

@ -0,0 +1,6 @@
import changeUserLock from '../modifiers/changeUserLock';
export default function handleLockSettingsInMeeting({ body }, meetingId) {
return changeUserLock(meetingId, body);
}

View File

@ -0,0 +1,35 @@
import Logger from '/imports/startup/server/logger';
import Meetings from '/imports/api/2.0/meetings';
import { check } from 'meteor/check';
export default function changeLockSettings(meetingId, payload) {
check(meetingId, String);
check(payload, {
disableCam: Boolean,
disableMic: Boolean,
disablePrivChat: Boolean,
disablePubChat: Boolean,
lockedLayout: Boolean,
lockOnJoin: Boolean,
lockOnJoinConfigurable: Boolean,
setBy: String,
});
const selector = {
meetingId
};
const modifier = {
$set: {
lockSettingsProp: payload,
},
};
const cb = (err) => {
if (err) {
return Logger.error(`Changing meeting={${meetingId}} lock settings: ${err}`);
}
};
return Meetings.upsert(selector, modifier, cb);
};

View File

@ -0,0 +1,30 @@
import Logger from '/imports/startup/server/logger';
import Users from '/imports/api/2.0/users';
import { check } from 'meteor/check';
export default function changeUserLock(meetingId, payload) {
check(meetingId, String);
check(payload, {
userId: String,
locked: Boolean,
lockedBy: String,
});
const selector = {
userId: payload.userId,
};
const modifier = {
$set: {
locked: payload.locked,
},
};
const cb = (err) => {
if (err) {
return Logger.error(`Changing user lock setting: ${err}`);
}
};
return Users.upsert(selector, modifier, cb);
};

View File

@ -29,12 +29,6 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis
answerId: pollAnswerId,
};
const header = {
meetingId,
name: EVENT_NAME,
userId: requesterUserId,
};
const selector = {
users: requesterUserId,
meetingId,
@ -57,5 +51,6 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis
};
Polls.update(selector, modifier, cb);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId });
}

View File

@ -40,12 +40,10 @@ export default function switchSlide(credentials, slideNumber) {
'slide-not-found', `Slide number ${slideNumber} not found in the current presentation`);
}
const header = { name: EVENT_NAME, meetingId, userId: requesterUserId };
const payload = {
pageId: Slide.id,
presentationId: Presentation.id,
};
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId });
}

View File

@ -12,13 +12,11 @@ const requestWhiteboardHistory = (meetingId, slideId) => {
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
const EVENT_NAME = 'GetWhiteboardAnnotationsReqMsg';
const header = { name: EVENT_NAME, meetingId, userId: 'nodeJSapp' };
const payload = {
whiteboardId: slideId,
};
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: 'nodeJSapp' });
};
const SUPPORTED_TYPES = [SVG, PNG];

View File

@ -25,12 +25,6 @@ export default function assignPresenter(credentials, userId) {
'user-not-found', 'You need a valid user to be able to set presenter');
}
const header = {
name: EVENT_NAME,
meetingId,
userId,
};
const payload = {
newPresenterId: userId,
newPresenterName: User.name,
@ -41,5 +35,5 @@ export default function assignPresenter(credentials, userId) {
Logger.verbose(`User '${userId}' setted as presenter by '${
requesterUserId}' from meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: User.userId });
}

View File

@ -18,5 +18,5 @@ export default function requestStunTurn(meetingId, requesterUserId) {
Logger.verbose(`User '${requesterUserId}' requested stun/turn from meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload);
}

View File

@ -19,14 +19,8 @@ export default function setEmojiStatus(credentials, userId, status) {
userId,
};
const header = {
meetingId,
name: EVENT_NAME,
userId: requesterUserId,
};
Logger.verbose(`User '${userId}' emoji status updated to '${status}' by '${
requesterUserId}' from meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId });
}

View File

@ -17,13 +17,7 @@ export default function userJoin(meetingId, userId, authToken) {
authToken,
};
const header = {
name: EVENT_NAME,
meetingId,
userId,
};
Logger.info(`User '${userId}' is joining meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId });
}

View File

@ -50,12 +50,6 @@ export default function userLeaving(credentials, userId) {
Users.update(selector, modifier, cb);
}
const header = {
name: EVENT_NAME,
meetingId,
userId: requesterUserId,
};
const payload = {
userId,
sessionId: meetingId,
@ -63,5 +57,5 @@ export default function userLeaving(credentials, userId) {
Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId });
}

View File

@ -3,7 +3,6 @@ import { check } from 'meteor/check';
import RedisPubSub from '/imports/startup/server/redis2x';
import Logger from '/imports/startup/server/logger';
import Users from '/imports/api/2.0/users';
import createDummyUser2x from '../modifiers/createDummyUser';
import setConnectionStatus from '../modifiers/setConnectionStatus';
@ -36,15 +35,9 @@ export default function validateAuthToken(credentials) {
authToken: requesterToken,
};
const header = {
name: EVENT_NAME,
meetingId,
userId: requesterUserId,
};
Logger.info(`User '${
requesterUserId
}' is trying to validate auth tokenfor meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId: requesterUserId });
}

View File

@ -36,11 +36,6 @@ export default function listenOnlyToggle(credentials, isJoining = true) {
// check(User.user.name, String);
const header = {
name: EVENT_NAME,
voiceConf: Meeting.voiceProp.voiceConf,
};
const payload = {
userId: requesterUserId,
name: VoiceUser.callerName,
@ -49,5 +44,5 @@ export default function listenOnlyToggle(credentials, isJoining = true) {
Logger.verbose(`VoiceUser '${requesterUserId}' ${isJoining
? 'joined' : 'left'} global audio from meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { voiceConf: Meeting.voiceProp.voiceConf });
}

View File

@ -12,16 +12,10 @@ export default function muteToggle(credentials, userId) {
check(meetingId, String);
check(requesterUserId, String);
const header = {
name: EVENT_NAME,
meetingId,
userId,
};
const payload = {
userId,
mutedBy: requesterUserId,
};
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, { userId });
}

View File

View File

@ -41,28 +41,24 @@ class RedisPubSub2x {
}
publish(channel, eventName, meetingId, payload = {}, header = {}) {
const header2x = {
name: eventName,
meetingId,
};
const msgHeader = header === {} ? header2x : header;
const envelope = {
envelope: {
name: eventName,
routing: {
sender: 'bbb-apps-akka',
// sender: 'html5-server', // TODO
},
}
},
core: {
header: msgHeader,
header: Object.assign({
name: eventName,
meetingId,
}, header),
body: payload,
},
}
};
Logger.warn(`<<<<<<Publishing 2.0 ${eventName} to ${channel} ${JSON.stringify(envelope)}`);
Logger.warn(`<<<<<<Publishing 2.0 ${eventName} to ${channel} ${JSON.stringify(envelope)}`);
return this.pub.publish(channel, JSON.stringify(envelope), (err) => {
if (err) {
Logger.error('Tried to publish to %s', channel, envelope);

View File

@ -1,5 +1,6 @@
import Chats from '/imports/api/2.0/chat';
import Users from '/imports/api/2.0/users';
import Meetings from '/imports/api/2.0/meetings';
import Auth from '/imports/ui/services/auth';
import UnreadMessages from '/imports/ui/services/unread-messages';
import Storage from '/imports/ui/services/storage/session';
@ -102,21 +103,19 @@ const getPrivateMessages = (userID) => {
const isChatLocked = (receiverID) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
const currentUser = getUser(Auth.userID);
const lockSettings = false;
const meeting = Meetings.findOne({});
const user = Users.findOne({});
// FIX ME
/* meeting.roomLockSettings || {
disablePublicChat: false,
disablePrivateChat: false,
}; */
if (!currentUser.isLocked || currentUser.isPresenter) {
return false;
if (meeting.lockSettingsProp !== 'undefined') {
const isPubChatLocked = meeting.lockSettingsProp.disablePubChat;
const isPrivChatLocked = meeting.lockSettingsProp.disablePrivChat;
const isViewer = user.role === "VIEWER";
return ((isPublic && isPubChatLocked && isViewer && user.locked) || (!isPublic && isPrivChatLocked && isViewer && user.locked));
}
return isPublic ? lockSettings.disablePublicChat : lockSettings.disablePrivateChat;
return false;
};
const hasUnreadMessages = (receiverID) => {

View File

@ -255,6 +255,7 @@ class UserList extends Component {
intl,
makeCall,
meeting,
isMeetingLocked,
} = this.props;
const userActions = {
@ -326,6 +327,7 @@ class UserList extends Component {
currentUser={currentUser}
userActions={userActions}
meeting={meeting}
isMeetingLocked={isMeetingLocked}
/>
))
}

View File

@ -2,7 +2,7 @@ import React from 'react';
import { createContainer } from 'meteor/react-meteor-data';
import { meetingIsBreakout } from '/imports/ui/components/app/service';
import { makeCall } from '/imports/ui/services/api';
import Meetings from '/imports/api/1.1/meetings';
import Meetings from '/imports/api/2.0/meetings';
import Service from './service';
import UserList from './component';
@ -16,6 +16,7 @@ const UserListContainer = (props) => {
isBreakoutRoom,
children,
meeting,
isMeetingLocked,
} = props;
return (
@ -28,6 +29,7 @@ const UserListContainer = (props) => {
isBreakoutRoom={isBreakoutRoom}
makeCall={makeCall}
userActions={userActions}
isMeetingLocked={isMeetingLocked}
>
{children}
</UserList>
@ -42,4 +44,5 @@ export default createContainer(({ params }) => ({
openChat: params.chatID,
userActions: Service.userActions,
isBreakoutRoom: meetingIsBreakout(),
isMeetingLocked: Service.isMeetingLocked,
}), UserListContainer);

View File

@ -1,5 +1,6 @@
import Users from '/imports/api/2.0/users';
import Chat from '/imports/api/2.0/chat';
import Meetings from '/imports/api/2.0/meetings';
import Auth from '/imports/ui/services/auth';
import UnreadMessages from '/imports/ui/services/unread-messages';
import Storage from '/imports/ui/services/storage/session';
@ -210,8 +211,27 @@ const getCurrentUser = () => {
return (currentUser) ? mapUser(currentUser) : null;
};
const isMeetingLocked = (id) => {
const meeting = Meetings.findOne({ meetingId: id });
let isLocked = false;
if (meeting.lockSettingsProp !== undefined) {
const lockSettings = meeting.lockSettingsProp;
if (lockSettings.disableCam
|| lockSettings.disableMic
|| lockSettings.disablePrivChat
|| lockSettings.disablePubChat ) {
isLocked = true;
}
}
return isLocked;
}
export default {
getUsers,
getOpenChats,
getCurrentUser,
isMeetingLocked
};

View File

@ -239,6 +239,8 @@ class UserListItem extends Component {
user,
intl,
compact,
isMeetingLocked,
meeting,
} = this.props;
if (compact) {
@ -246,8 +248,9 @@ class UserListItem extends Component {
}
const userNameSub = [];
const isViewer = (!user.isPresenter && !user.isModerator) ? true : false;
if (user.isLocked) {
if (isMeetingLocked(meeting.meetingId) && isViewer && user.isLocked) {
userNameSub.push(<span>
<Icon iconName="lock" />
{intl.formatMessage(messages.locked)}

View File

@ -19,8 +19,13 @@ describe('Landing page', function () {
function () {
LandingPage.open();
chromeBrowser.setValue(LandingPage.usernameInputSelector, 'Maxim');
firefoxBrowser.setValue(LandingPage.usernameInputSelector, 'Anton');
utils.setUsername(new Map([
['chromeBrowser', 'Alex'],
['chromeDevBrowser', 'Anton'],
['firefoxBrowser', 'Danny'],
['firefoxNightlyBrowser', 'Maxim'],
['chromeMobileBrowser', 'Oswaldo']
]));
LandingPage.joinWithButtonClick();
LandingPage.loadedHomePageElement.waitForExist(5000);

View File

@ -1,6 +1,7 @@
'use strict';
let chai = require('chai');
let LandingPage = require('./pageobjects/landing.page');
class Utils {
assertTitle(title) {
@ -13,6 +14,9 @@ class Utils {
chai.expect(browser.getUrl()[browserName]).to.equal(url);
});
}
setUsername(map) {
map.forEach((v, k) => browser.select(k).setValue(LandingPage.usernameInputSelector, v));
}
}
module.exports = new Utils();

View File

@ -2,14 +2,38 @@ exports.config = {
specs: ['tests/webdriverio/specs/**/*.spec.js'],
capabilities: {
chromeBrowser: {
desiredCapabilities: {
browserName: 'chrome'
}
},
chromeDevBrowser: {
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
binary: '/opt/google/chrome-unstable/google-chrome-unstable'
}
}
},
firefoxBrowser: {
desiredCapabilities: {
browserName: 'firefox'
}
},
firefoxNightlyBrowser: {
desiredCapabilities: {
browserName: 'firefox',
firefox_binary: '/usr/lib/firefox-trunk/firefox-trunk'
}
},
chromeMobileBrowser: {
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
mobileEmulation: {
deviceName: 'Apple iPhone 6'
}
}
}
}
},
baseUrl: 'http://localhost:8080',