Merge branch 'v2.0.x-release' of github.com:bigbluebutton/bigbluebutton into synch-with-v2.0

This commit is contained in:
Richard Alam 2017-12-21 12:48:20 -08:00
commit 7637cedd4b
22 changed files with 129 additions and 64 deletions

View File

@ -60,4 +60,5 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers with SystemConfi
outGW.send(event)
}
}
}

View File

@ -154,6 +154,13 @@ class MeetingActor(
state = PresentationPodsApp.createDefaultPresentationPod(state)
log.debug("NUM Presentation Pods = " + state.presentationPodManager.getNumberOfPods())
// Initialize if the meeting is muted on start
if (props.voiceProp.muteOnStart) {
MeetingStatus2x.muteMeeting(liveMeeting.status)
} else {
MeetingStatus2x.unmuteMeeting(liveMeeting.status)
}
/*******************************************************************/
//object FakeTestData extends FakeTestData
//FakeTestData.createFakeUsers(liveMeeting)
@ -411,9 +418,7 @@ class MeetingActor(
val meetingId = liveMeeting.props.meetingProp.intId
val recordFile = VoiceApp.genRecordPath(voiceConfRecordPath, meetingId, now)
VoiceApp.startRecordingVoiceConference(liveMeeting, outGW, recordFile)
}
}
def sendRttTraceTest(): Unit = {

View File

@ -16,7 +16,7 @@ case class RecordProp(record: Boolean, autoStartRecording: Boolean, allowStartSt
case class WelcomeProp(welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String)
case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String)
case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean)
case class UsersProp(maxUsers: Int, webcamsOnlyForModerator: Boolean, guestPolicy: String)

View File

@ -275,7 +275,8 @@ public class MeetingService implements MessageListener {
m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy(), m.getWelcomeMessageTemplate(),
m.getWelcomeMessage(), m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers(),
m.getMaxInactivityTimeoutMinutes(), m.getWarnMinutesBeforeMax(),
m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getmeetingExpireWhenLastUserLeftInMinutes());
m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getmeetingExpireWhenLastUserLeftInMinutes(),
m.getMuteOnStart());
}

View File

@ -82,6 +82,7 @@ public class ParamsProcessorUtil {
private boolean autoStartRecording;
private boolean allowStartStopRecording;
private boolean webcamsOnlyForModerator;
private boolean defaultMuteOnStart = false;
private String defaultConfigXML = null;
@ -472,7 +473,9 @@ public class ParamsProcessorUtil {
meeting.storeConfig(true, configXML);
if (!StringUtils.isEmpty(params.get("moderatorOnlyMessage"))) {
String moderatorOnlyMessage = params.get("moderatorOnlyMessage");
String moderatorOnlyMessageTemplate = params.get("moderatorOnlyMessage");
String moderatorOnlyMessage = substituteKeywords(moderatorOnlyMessageTemplate,
dialNumber, telVoice, meetingName);
meeting.setModeratorOnlyMessage(moderatorOnlyMessage);
}
@ -487,6 +490,19 @@ public class ParamsProcessorUtil {
meeting.setParentMeetingId(parentMeetingId);
}
if (!StringUtils.isEmpty(params.get("logo"))) {
meeting.setCustomLogoURL(params.get("logo"));
}
if (!StringUtils.isEmpty(params.get("copyright"))) {
meeting.setCustomCopyright(params.get("copyright"));
}
Boolean muteOnStart = defaultMuteOnStart;
if (!StringUtils.isEmpty(params.get("muteOnStart"))) {
muteOnStart = Boolean.parseBoolean(params.get("muteOnStart"));
meeting.setMuteOnStart(muteOnStart);
}
return meeting;
}
@ -946,6 +962,15 @@ public class ParamsProcessorUtil {
return maxPresentationFileUpload;
}
public void setMuteOnStart(Boolean mute) {
defaultMuteOnStart = mute;
}
public Boolean getMuteOnStart() {
return defaultMuteOnStart;
}
public ArrayList<String> decodeIds(String encodeid) {
ArrayList<String> ids=new ArrayList<String>();
try {

View File

@ -68,6 +68,9 @@ public class Meeting {
private final ConcurrentMap<String, Config> configs;
private final Boolean isBreakout;
private final List<String> breakoutRooms = new ArrayList<String>();
private String customLogoURL = "";
private String customCopyright = "";
private Boolean muteOnStart = false;
private Integer maxInactivityTimeoutMinutes = 120;
private Integer warnMinutesBeforeMax = 5;
@ -366,6 +369,30 @@ public class Meeting {
return userHasJoined;
}
public String getCustomLogoURL() {
return customLogoURL;
}
public void setCustomLogoURL(String url) {
customLogoURL = url;
}
public void setCustomCopyright(String copyright) {
customCopyright = copyright;
}
public String getCustomCopyright() {
return customCopyright;
}
public void setMuteOnStart(Boolean mute) {
muteOnStart = mute;
}
public Boolean getMuteOnStart() {
return muteOnStart;
}
public void userJoined(User user) {
userHasJoined = true;
this.users.put(user.getInternalUserId(), user);

View File

@ -18,7 +18,8 @@ public interface IBbbWebApiGWApp {
String dialNumber, Integer maxUsers,
Integer maxInactivityTimeoutMinutes, Integer warnMinutesBeforeMax,
Integer meetingExpireIfNoUserJoinedInMinutes,
Integer meetingExpireWhenLastUserLeftInMinutes);
Integer meetingExpireWhenLastUserLeftInMinutes,
Boolean muteOnStart);
void registerUser(String meetingID, String internalUserId, String fullname, String role,
String externUserID, String authToken, String avatarURL,

View File

@ -86,7 +86,8 @@ class BbbWebApiGWApp(val oldMessageReceivedGW: OldMessageReceivedGW,
dialNumber: String, maxUsers: java.lang.Integer, maxInactivityTimeoutMinutes: java.lang.Integer,
warnMinutesBeforeMax: java.lang.Integer,
meetingExpireIfNoUserJoinedInMinutes: java.lang.Integer,
meetingExpireWhenLastUserLeftInMinutes: java.lang.Integer): Unit = {
meetingExpireWhenLastUserLeftInMinutes: java.lang.Integer,
muteOnStart: java.lang.Boolean): Unit = {
val meetingProp = MeetingProp(name = meetingName, extId = extMeetingId, intId = meetingId,
isBreakout = isBreakout.booleanValue())
@ -103,7 +104,7 @@ class BbbWebApiGWApp(val oldMessageReceivedGW: OldMessageReceivedGW,
val breakoutProps = BreakoutProps(parentId = parentMeetingId, sequence = sequence.intValue(), breakoutRooms = Vector())
val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg,
modOnlyMessage = modOnlyMessage)
val voiceProp = VoiceProp(telVoice = voiceBridge, voiceConf = voiceBridge, dialNumber = dialNumber)
val voiceProp = VoiceProp(telVoice = voiceBridge, voiceConf = voiceBridge, dialNumber = dialNumber, muteOnStart = muteOnStart.booleanValue())
val usersProp = UsersProp(maxUsers = maxUsers.intValue(), webcamsOnlyForModerator = webcamsOnlyForModerator.booleanValue(),
guestPolicy = guestPolicy)
val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap)

View File

@ -222,9 +222,9 @@ bbb.users.usersGrid.mediaItemRenderer.pushToTalk = Unmute {0}
bbb.users.usersGrid.mediaItemRenderer.pushToMute = Mute {0}
bbb.users.usersGrid.mediaItemRenderer.pushToLock = Lock {0}
bbb.users.usersGrid.mediaItemRenderer.pushToUnlock = Unlock {0}
bbb.users.usersGrid.mediaItemRenderer.kickUser = Kick {0}
bbb.users.usersGrid.mediaItemRenderer.addUserToPresenterGroup = Add {0} to presenter group
bbb.users.usersGrid.mediaItemRenderer.removeUserFromPresenterGroup = Remove {0} from presenter group
bbb.users.usersGrid.mediaItemRenderer.kickUser = Remove {0}
bbb.users.usersGrid.mediaItemRenderer.webcam = Webcam shared
bbb.users.usersGrid.mediaItemRenderer.micOff = Microphone off
bbb.users.usersGrid.mediaItemRenderer.micOn = Microphone on
@ -549,10 +549,10 @@ bbb.logout.unknown = Your client has lost connection with the server
bbb.logout.guestkickedout = The moderator didn't allow you to join this meeting
bbb.logout.usercommand = You have logged out of the conference
bbb.logout.breakoutRoomClose = Your browser window will be closed
bbb.logout.ejectedFromMeeting = A moderator has kicked you out of the meeting.
bbb.logout.duplicateUserEjectReason = Duplicate user trying to join meeting.
bbb.logout.permissionEjectReason = Ejected due to permission violation.
bbb.logout.validateTokenFailedEjectReason = Failed to validate authorization token.
bbb.logout.ejectedFromMeeting = You have been removed from the meeting.
bbb.logout.refresh.message = If this logout was unexpected click the button below to reconnect.
bbb.logout.refresh.label = Reconnect
bbb.guest.settings.ok = OK
@ -748,7 +748,7 @@ bbb.shortcutkey.present.fitPage.function = Fit slides to page
bbb.shortcutkey.users.makePresenter = 89
bbb.shortcutkey.users.makePresenter.function = Make selected person presenter
bbb.shortcutkey.users.kick = 69
bbb.shortcutkey.users.kick.function = Kick selected person from the meeting
bbb.shortcutkey.users.kick.function = Remove selected person from the meeting
bbb.shortcutkey.users.mute = 83
bbb.shortcutkey.users.mute.function = Mute or unmute selected person
bbb.shortcutkey.users.muteall = 65

View File

@ -18,7 +18,6 @@
showToolbar="true" showFooter="true" showMeetingName="true" showHelpButton="true"
showLogoutWindow="true" showLayoutTools="true" confirmLogout="true" showNetworkMonitor="false"
showRecordingNotification="true" logoutOnStopRecording="false"/>
<meeting muteOnStart="false" />
<breakoutRooms enabled="true" record="false" />
<logging enabled="true" logTarget="trace" level="info" format="{dateUTC} {time} :: {name} :: [{logLevel}] {message}" uri="http://HOST/log" logPattern=".*"/>
<lock disableCam="false" disableMic="false" disablePrivateChat="false"

View File

@ -20,5 +20,7 @@ package org.bigbluebutton.core.model
public var logoutTimer:int=0;
public var bannerColor:String = "";
public var bannerText:String = "";
public var customLogo:String = "";
public var customCopyright:String = "";
}
}

View File

@ -1,31 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 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/>.
*
*/
package org.bigbluebutton.main.model.options {
import org.bigbluebutton.core.Options;
public class MeetingOptions extends Options {
[Bindable]
public var muteOnStart:Boolean = false;
public function MeetingOptions() {
name = "meeting";
}
}
}

View File

@ -11,7 +11,7 @@ package org.bigbluebutton.main.model.users
public var authToken: String;
public var customdata:Object = new Object();
public var logoutUrl: String;
public var logoutTimer : int;
public var logoutTimer : int;
public var defaultLayout: String;
public var avatarURL: String;
public var bannerText: String;
@ -19,7 +19,8 @@ package org.bigbluebutton.main.model.users
public var dialnumber: String;
public var voiceConf: String;
public var welcome: String;
public var customLogo:String;
public var customCopyright:String;
public var meetingName: String;
public var extMeetingId: String;
public var intMeetingId: String;
@ -30,5 +31,6 @@ package org.bigbluebutton.main.model.users
public var webcamsOnlyForModerator: Boolean;
public var metadata: Object = new Object();
public var modOnlyMessage: String;
public var muteOnStart:Boolean = false;
}
}

View File

@ -160,9 +160,10 @@ package org.bigbluebutton.main.model.users
apiResponse.welcome = result.response.welcome;
apiResponse.logoutUrl = processLogoutUrl(result.response);
apiResponse.logoutTimer = result.response.logoutTimer;
apiResponse.logoutTimer = result.response.logoutTimer;
apiResponse.defaultLayout = result.response.defaultLayout;
apiResponse.avatarURL = result.response.avatarURL
apiResponse.avatarURL = result.response.avatarURL;
apiResponse.customdata = new Object();
if (result.response.customdata) {
@ -181,6 +182,10 @@ package org.bigbluebutton.main.model.users
apiResponse.modOnlyMessage = result.response.modOnlyMessage;
}
apiResponse.customLogo = result.response.customLogoURL;
apiResponse.customCopyright = result.response.customCopyright;
apiResponse.muteOnStart = result.response.muteOnStart as Boolean;
if (_resultListener != null) _resultListener(true, apiResponse);
}

View File

@ -22,6 +22,7 @@ package org.bigbluebutton.main.model.users
import flash.external.ExternalInterface;
import flash.net.NetConnection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
@ -40,7 +41,6 @@ package org.bigbluebutton.main.model.users
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.main.events.UserServicesEvent;
import org.bigbluebutton.main.model.options.ApplicationOptions;
import org.bigbluebutton.main.model.options.MeetingOptions;
import org.bigbluebutton.main.model.users.events.BroadcastStartedEvent;
import org.bigbluebutton.main.model.users.events.BroadcastStoppedEvent;
import org.bigbluebutton.main.model.users.events.ChangeRoleEvent;
@ -52,7 +52,7 @@ package org.bigbluebutton.main.model.users
import org.bigbluebutton.main.model.users.events.AddUserToPresenterGroupEvent;
import org.bigbluebutton.main.model.users.events.RemoveUserFromPresenterGroupEvent;
import org.bigbluebutton.main.model.users.events.RequestPresenterGroupEvent;
import org.bigbluebutton.modules.users.events.MeetingMutedEvent;
import org.bigbluebutton.modules.users.services.MessageReceiver;
import org.bigbluebutton.modules.users.services.MessageSender;
@ -102,7 +102,6 @@ package org.bigbluebutton.main.model.users
private function joinListener(success:Boolean, result: EnterApiResponse):void {
if (success) {
var meetingOptions : MeetingOptions = Options.getOptions(MeetingOptions) as MeetingOptions;
LiveMeeting.inst().me.id = result.intUserId
LiveMeeting.inst().me.name = result.username;
@ -133,19 +132,25 @@ package org.bigbluebutton.main.model.users
LiveMeeting.inst().meeting.allowStartStopRecording = result.allowStartStopRecording;
LiveMeeting.inst().meeting.webcamsOnlyForModerator = result.webcamsOnlyForModerator;
LiveMeeting.inst().meeting.metadata = result.metadata;
LiveMeeting.inst().meeting.muteOnStart = meetingOptions.muteOnStart;
LiveMeeting.inst().meeting.logoutTimer = result.logoutTimer;
LiveMeeting.inst().meeting.bannerColor = result.bannerColor;
LiveMeeting.inst().meeting.bannerText = result.bannerText;
LiveMeeting.inst().meeting.muteOnStart = result.muteOnStart;
LiveMeeting.inst().meetingStatus.isMeetingMuted = result.muteOnStart;
LiveMeeting.inst().meeting.customLogo = result.customLogo;
LiveMeeting.inst().meeting.customCopyright = result.customCopyright;
// assign the meeting name to the document title
ExternalInterface.call("setTitle", result.meetingName);
var e:ConferenceCreatedEvent = new ConferenceCreatedEvent(ConferenceCreatedEvent.CONFERENCE_CREATED_EVENT);
dispatcher.dispatchEvent(e);
// Send event to trigger meeting muted initialization of meeting (ralam dec 21, 2017)
dispatcher.dispatchEvent(new MeetingMutedEvent());
connect();
}
}

View File

@ -74,6 +74,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{BBBEvent.RECONNECT_DISCONNECTED_EVENT}" method="closeWaitWindow"/>
<mate:Listener type="{RoundTripLatencyReceivedEvent.ROUND_TRIP_LATENCY_RECEIVED}" method="handleRoundTripLatencyReceivedEvent"/>
<mate:Listener type="{ClosePendingGuestWindow.CLOSE_PENDING_GUEST_WINDOW}" method="handleClosePendingGuestWindow" />
<mate:Listener type="{ConferenceCreatedEvent.CONFERENCE_CREATED_EVENT}" method="handleConferenceCreatedEvent" />
</fx:Declarations>
<fx:Script>
<![CDATA[
@ -111,6 +113,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.core.events.NewGuestWaitingEvent;
import org.bigbluebutton.core.events.RoundTripLatencyReceivedEvent;
import org.bigbluebutton.core.events.SwitchedLayoutEvent;
import org.bigbluebutton.core.model.LiveMeeting;
import org.bigbluebutton.core.vo.LockSettingsVO;
import org.bigbluebutton.main.events.AppVersionEvent;
import org.bigbluebutton.main.events.BBBEvent;
@ -127,6 +130,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.main.model.options.BrowserVersionsOptions;
import org.bigbluebutton.main.model.options.LanguageOptions;
import org.bigbluebutton.main.model.options.LayoutOptions;
import org.bigbluebutton.main.model.users.events.ConferenceCreatedEvent;
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
import org.bigbluebutton.modules.phone.events.FlashMicSettingsEvent;
import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
@ -222,6 +227,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
_respTimer.start();
}
private function handleConferenceCreatedEvent(event:ConferenceCreatedEvent):void {
updateCopyrightText();
}
private function updateCopyrightText():void {
brandingOptions = Options.getOptions(BrandingOptions) as BrandingOptions;
@ -230,6 +239,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} else {
copyrightText = String(brandingOptions.copyright).replace("{0}", appVersion);
}
if (!StringUtils.isEmpty(LiveMeeting.inst().meeting.customCopyright)) {
copyrightText = LiveMeeting.inst().meeting.customCopyright;
}
}
private function initQuote() : void {

View File

@ -206,6 +206,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
}
var customLogo: String = LiveMeeting.inst().meeting.customLogo;
if (customLogo != "") {
logo.source = LiveMeeting.inst().meeting.customLogo;
}
if (UsersUtil.isBreakout()) {
breakoutRibbon.visible = breakoutRibbon.includeInLayout = true;
var sequence:String = StringUtils.substringAfterLast(UsersUtil.getMeetingName(), " ");

View File

@ -161,6 +161,9 @@ allowStartStopRecording=true
# Allow webcams streaming reception only to and from moderators
webcamsOnlyForModerator=false
# Mute the meeting on start
muteOnStart=false
#----------------------------------------------------
# This URL is where the BBB client is accessible. When a user sucessfully
# enters a name and password, she is redirected here to load the client.

View File

@ -140,6 +140,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<property name="meetingExpireWhenLastUserLeftInMinutes" value="${meetingExpireWhenLastUserLeftInMinutes}"/>
<property name="maxPresentationFileUpload" value="${maxFileSizeUpload}"/>
<property name="clientLogoutTimerInMinutes" value="${clientLogoutTimerInMinutes}"/>
<property name="muteOnStart" value="${muteOnStart}"/>
</bean>
<import resource="doc-conversion.xml"/>

View File

@ -161,10 +161,6 @@ class ApiController {
Meeting newMeeting = paramsProcessorUtil.processCreateParams(params);
if (! StringUtils.isEmpty(params.moderatorOnlyMessage)) {
newMeeting.setModeratorOnlyMessage(params.moderatorOnlyMessage);
}
if (meetingService.createMeeting(newMeeting)) {
// See if the request came with pre-uploading of presentation.
uploadDocuments(newMeeting); //
@ -1541,6 +1537,9 @@ class ApiController {
bannerText = meeting.getBannerText()
bannerColor = meeting.getBannerColor()
}
customLogoURL = meeting.getCustomLogoURL()
customCopyright = meeting.getCustomCopyright()
muteOnStart = meeting.getMuteOnStart()
logoutUrl = us.logoutUrl
defaultLayout = us.defaultLayout
avatarURL = us.avatarURL

View File

@ -27,7 +27,7 @@
<attendees>
<#list meeting.getUsers() as att>
<attendee>
<userID>${att.getInternalUserId()}</userID>
<userID>${att.getExternalUserId()}</userID>
<fullName>${att.getFullname()?html}</fullName>
<role>${att.getRole()}</role>
<isPresenter>${att.isPresenter()?c}</isPresenter>

View File

@ -32,7 +32,7 @@
<attendees>
<#list meetingDetail.meeting.getUsers() as att>
<attendee>
<userID>${att.getInternalUserId()}</userID>
<userID>${att.getExternalUserId()}</userID>
<fullName>${att.getFullname()?html}</fullName>
<role>${att.getRole()}</role>
<isPresenter>${att.isPresenter()?c}</isPresenter>