Merge branch 'master' of github.com:bigbluebutton/bigbluebutton into pods_vol4

This commit is contained in:
Anton Georgiev 2017-10-21 08:50:25 -04:00
commit 6f8abff77c
129 changed files with 1518 additions and 711 deletions

View File

@ -290,3 +290,104 @@ Handle the message in [MeestingActor](https://github.com/bigbluebutton/bigbluebu
A complete example would be the `ValidateAuthTokenReqMsg`.
## Installing Flex SDK 4.16.0 and Playerglobal 23.0 for version 2.1 development
In the next step, you need to get the Apache Flex 4.16.0 SDK package.
Next, you need to make a directory to hold the tools needed for BigBlueButton development.
~~~
mkdir -p ~/dev/tools
cd ~/dev/tools
~~~
First, you need to download the SDK tarball from an Apache mirror site and then unpack it.
~~~
wget https://archive.apache.org/dist/flex/4.16.0/binaries/apache-flex-sdk-4.16.0-bin.tar.gz
tar xvfz apache-flex-sdk-4.16.0-bin.tar.gz
~~~
Next, create a linked directory with a shortened name for easier referencing.
~~~
ln -s ~/dev/tools/apache-flex-sdk-4.16.0-bin ~/dev/tools/flex
~~~
Once the Apache Flex SDK is unpacked, you need to download one of the dependencies manually because the file was moved from its original URL.
~~~
wget --content-disposition https://github.com/swfobject/swfobject/archive/2.2.tar.gz
tar xvfz swfobject-2.2.tar.gz
cp -r swfobject-2.2/swfobject flex/templates/
~~~
Now that we've finished with the first dependency we need to download the Adobe Flex SDK. We'll do this step manually in case the download fails (if it does, remove the incomplete file and issue the `wget` command again).
~~~
cd flex/
mkdir -p in/
wget http://download.macromedia.com/pub/flex/sdk/builds/flex4.6/flex_sdk_4.6.0.23201B.zip -P in/
~~~
Once the supplementary SDK has downloaded, we can use its `build.xml` script to automatically download the remaining third-party tools.
~~~
ant -f frameworks/build.xml thirdparty-downloads
~~~
After Flex downloads the remaining third-party tools, you need to modify their permissions.
~~~
find ~/dev/tools/flex -type d -exec chmod o+rx '{}' \;
chmod 755 ~/dev/tools/flex/bin/*
chmod -R +r ~/dev/tools/flex
~~~
The next step in setting up the Flex SDK environment is to download a Flex library for video.
~~~
mkdir -p ~/dev/tools/flex/frameworks/libs/player/23.0
cd ~/dev/tools/flex/frameworks/libs/player/23.0
wget http://fpdownload.macromedia.com/get/flashplayer/installers/archive/playerglobal/playerglobal23_0.swc
mv -f playerglobal23_0.swc playerglobal.swc
~~~
The last step to have a working Flex SDK is to configure it to work with playerglobal 23.0
~~~
cd ~/dev/tools/flex
sed -i "s/11.1/23.0/g" frameworks/flex-config.xml
sed -i "s/<swf-version>14<\/swf-version>/<swf-version>34<\/swf-version>/g" frameworks/flex-config.xml
sed -i "s/{playerglobalHome}\/{targetPlayerMajorVersion}.{targetPlayerMinorVersion}/libs\/player\/23.0/g" frameworks/flex-config.xml
~~~
With the tools installed, you need to add a set of environment variables to your `.profile` to access these tools.
~~~
vi ~/.profile
~~~
Copy-and-paste the following text at bottom of `.profile`.
~~~
export FLEX_HOME=$HOME/dev/tools/flex
export PATH=$PATH:$FLEX_HOME/bin
export ANT_OPTS="-Xmx512m -XX:MaxPermSize=512m"
~~~
Reload your profile to use these tools (this will happen automatically when you next login).
~~~
source ~/.profile
~~~
Check that the tools are now in your path by running the following command.
~~~
$ mxmlc -version
Version 4.16.0 build 20170305
~~~

View File

@ -79,3 +79,7 @@ services {
telizeHost = "www.telize.com"
telizePort = 80
}
apps {
checkPermissions = true
}

View File

@ -59,4 +59,6 @@ trait SystemConfiguration {
lazy val httpPort = Try(config.getInt("http.port")).getOrElse(9090)
lazy val telizeHost = Try(config.getString("services.telizeHost")).getOrElse("")
lazy val telizePort = Try(config.getInt("services.telizePort")).getOrElse(80)
lazy val applyPermissionCheck = Try(config.getBoolean("apps.checkPermissions")).getOrElse(false)
}

View File

@ -1,10 +1,63 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.common2.domain.UserVO
import org.bigbluebutton.core.models.{ Roles, UserState, Users2x }
import org.bigbluebutton.core.running.OutMsgRouter
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender }
trait PermisssionCheck {
object PermisssionCheck {
def isAllowed(permission: String, role: String, user: UserVO): Boolean = {
true
val MOD_LEVEL = 100
val AUTHED_LEVEL = 50
val GUEST_LEVEL = 0
val PRESENTER_LEVEL = 100
val VIEWER_LEVEL = 0
private def permissionToLevel(user: UserState): Int = {
if (user.role == Roles.MODERATOR_ROLE) {
MOD_LEVEL
} else if (user.authed) {
AUTHED_LEVEL
} else {
GUEST_LEVEL
}
}
private def roleToLevel(user: UserState): Int = {
if (user.presenter) PRESENTER_LEVEL else VIEWER_LEVEL
}
/**
* This method will check if the user that issued the command has the correct permissions.
*
* Example of the permissions level are "AUTHENTICATED", "MODERATOR" and "GUEST". Example of roles
* are "VIEWER" and "PRESENTER".
*
* @param permissionLevel Lowest permission needed to have access.
* @param roleLevel Lowest role needed to have access.
* @return true allows API to execute, false denies executing API
*/
def isAllowed(permissionLevel: Int, roleLevel: Int, users: Users2x, userId: String): Boolean = {
Users2x.findWithIntId(users, userId) match {
case Some(user) =>
println("permissionToLevel = " + permissionToLevel(user) + " permissionLevel=" + permissionLevel)
val permLevelCheck = permissionToLevel(user) >= permissionLevel
println("roleToLevel = " + roleToLevel(user) + " roleLevel=" + roleLevel)
val roleLevelCheck = roleToLevel(user) >= roleLevel
println("PERMLEVELCHECK = " + permLevelCheck + " ROLELEVELCHECK=" + roleLevelCheck)
permLevelCheck && roleLevelCheck
false
case None => false
}
}
def ejectUserForFailedPermission(meetingId: String, userId: String, reason: String, outGW: OutMsgRouter): Unit = {
val ejectedBy = "SYSTEM"
Sender.sendUserEjectedFromMeetingClientEvtMsg(meetingId, userId, ejectedBy, reason, outGW)
// send a system message to force disconnection
Sender.sendUserEjectedFromMeetingSystemMsg(meetingId, userId, ejectedBy, outGW)
}
}

View File

@ -1,17 +1,45 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.api.Permissions
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core.apps.PermisssionCheck
import org.bigbluebutton.core.running.{ OutMsgRouter }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait ChangeLockSettingsInMeetingCmdMsgHdlr {
trait ChangeLockSettingsInMeetingCmdMsgHdlrDefault {
def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {}
}
trait ChangeLockSettingsInMeetingCmdMsgHdlrCheckPerm
extends ChangeLockSettingsInMeetingCmdMsgHdlrDefault with SystemConfiguration {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
override def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
val isAllowed = PermisssionCheck.isAllowed(
PermisssionCheck.MOD_LEVEL,
PermisssionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.body.setBy
)
if (applyPermissionCheck && !isAllowed) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to change lock settings"
PermisssionCheck.ejectUserForFailedPermission(meetingId, msg.body.setBy, reason, outGW)
} else {
super.handleSetLockSettings(msg)
}
}
}
trait ChangeLockSettingsInMeetingCmdMsgHdlr extends ChangeLockSettingsInMeetingCmdMsgHdlrCheckPerm {
this: MeetingActor =>
val outGW: OutMsgRouter
override def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
val settings = Permissions(
disableCam = msg.body.disableCam,
disableMic = msg.body.disableMic,

View File

@ -3,7 +3,7 @@ package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender }
trait EjectUserFromMeetingCmdMsgHdlr {
this: UsersApp =>
@ -16,22 +16,22 @@ trait EjectUserFromMeetingCmdMsgHdlr {
user <- Users2x.ejectFromMeeting(liveMeeting.users2x, msg.body.userId)
} yield {
RegisteredUsers.remove(msg.body.userId, liveMeeting.registeredUsers)
val reason = "user ejected by another user"
// send a message to client
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(
Sender.sendUserEjectedFromMeetingClientEvtMsg(
liveMeeting.props.meetingProp.intId,
user.intId, msg.body.ejectedBy
user.intId, msg.body.ejectedBy, reason, outGW
)
outGW.send(ejectFromMeetingClientEvent)
log.info("Ejecting user from meeting (client msg). meetingId=" + liveMeeting.props.meetingProp.intId +
" userId=" + msg.body.userId)
// send a system message to force disconnection
val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(
Sender.sendUserEjectedFromMeetingSystemMsg(
liveMeeting.props.meetingProp.intId,
user.intId, "eject-user"
user.intId, msg.body.ejectedBy, outGW
)
outGW.send(ejectFromMeetingSystemEvent)
log.info("Ejecting user from meeting (system msg). meetingId=" + liveMeeting.props.meetingProp.intId +
" userId=" + msg.body.userId)

View File

@ -1,23 +1,61 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs.MuteUserCmdMsg
import org.bigbluebutton.core.apps.PermisssionCheck
import org.bigbluebutton.core.models.VoiceUsers
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait MuteUserCmdMsgHdlr {
this: MeetingActor =>
trait MuteUserCmdMsgHdlrDefault {
def handleMuteUserCmdMsg(msg: MuteUserCmdMsg): Unit = {
println("**************** MuteUserCmdMsgHdlrDefault ")
}
}
trait MuteUserCmdMsgHdlrPermCheck extends MuteUserCmdMsgHdlrDefault with SystemConfiguration {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
def handleMuteUserCmdMsg(msg: MuteUserCmdMsg) {
log.info("Received mute user request. meetingId=" + props.meetingProp.intId + " userId="
override def handleMuteUserCmdMsg(msg: MuteUserCmdMsg): Unit = {
println("**************** MuteUserCmdMsgHdlrPermCheck ")
val isAllowed = PermisssionCheck.isAllowed(
PermisssionCheck.MOD_LEVEL,
PermisssionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.body.mutedBy
)
if (applyPermissionCheck && !isAllowed) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to mute user in meeting."
PermisssionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW)
} else {
super.handleMuteUserCmdMsg(msg)
}
}
}
trait MuteUserCmdMsgHdlr extends MuteUserCmdMsgHdlrDefault {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
override def handleMuteUserCmdMsg(msg: MuteUserCmdMsg) {
println("**************** MuteUserCmdMsgHdlr ")
val meetingId = liveMeeting.props.meetingProp.intId
val voiceConf = liveMeeting.props.voiceProp.voiceConf
log.info("Received mute user request. meetingId=" + meetingId + " userId="
+ msg.body.userId)
for {
u <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
} yield {
log.info("Send mute user request. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg(props.meetingProp.intId, props.voiceProp.voiceConf,
log.info("Send mute user request. meetingId=" + meetingId + " userId=" + u.intId + " user=" + u)
val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg(meetingId, voiceConf,
u.voiceUserId, !u.muted)
outGW.send(event)
}

View File

@ -29,6 +29,7 @@ trait UserConnectedToGlobalAudioMsgHdlr {
for {
user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId)
} yield {
val vu = VoiceUserState(intId = user.intId, voiceUserId = user.intId, callingWith = "flash", callerName = user.name,
callerNum = user.name, muted = true, talking = false, listenOnly = true)
VoiceUsers.add(liveMeeting.voiceUsers, vu)

View File

@ -14,20 +14,24 @@ trait UserJoinMeetingAfterReconnectReqMsgHdlr extends HandlerHelpers with Breako
val outGW: OutMsgRouter
def handleUserJoinMeetingAfterReconnectReqMsg(msg: UserJoinMeetingAfterReconnectReqMsg, state: MeetingState2x): MeetingState2x = {
val newState = userJoinMeeting(outGW, msg.body.authToken, liveMeeting, state)
/**
* val newState = userJoinMeeting(outGW, msg.body.authToken, liveMeeting, state)
*
* if (liveMeeting.props.meetingProp.isBreakout) {
* updateParentMeetingWithUsers()
* }
*
* // recover voice user
* for {
* vu <- VoiceUsers.recoverVoiceUser(liveMeeting.voiceUsers, msg.body.userId)
* } yield {
* handleUserJoinedVoiceConfEvtMsg(liveMeeting.props.voiceProp.voiceConf, vu.intId, vu.voiceUserId, vu.callingWith, vu.callerName, vu.callerNum, vu.muted, vu.talking)
* }
*
* newState
*/
if (liveMeeting.props.meetingProp.isBreakout) {
updateParentMeetingWithUsers()
}
// recover voice user
for {
vu <- VoiceUsers.recoverVoiceUser(liveMeeting.voiceUsers, msg.body.userId)
} yield {
handleUserJoinedVoiceConfEvtMsg(liveMeeting.props.voiceProp.voiceConf, vu.intId, vu.voiceUserId, vu.callingWith, vu.callerName, vu.callerNum, vu.muted, vu.talking)
}
newState
state
}
}

View File

@ -23,7 +23,9 @@ class UsersApp(
with AssignPresenterReqMsgHdlr
with AddUserToPresenterGroupCmdMsgHdlr
with RemoveUserFromPresenterGroupCmdMsgHdlr
with EjectUserFromMeetingCmdMsgHdlr {
with EjectUserFromMeetingCmdMsgHdlr
with MuteUserCmdMsgHdlr
with MuteUserCmdMsgHdlrPermCheck {
val log = Logging(context.system, getClass)
}

View File

@ -41,8 +41,9 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers {
outGW.send(msgEvent)
}
val voiceUserState = VoiceUserState(intId, voiceUserId, callingWith, callerIdName, callerIdNum, muted, talking, listenOnly = false)
val isListenOnly = if (callerIdName.startsWith("LISTENONLY")) true else false
val voiceUserState = VoiceUserState(intId, voiceUserId, callingWith, callerIdName, callerIdNum, muted, talking, listenOnly = isListenOnly)
VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState)
broadcastEvent(voiceUserState)

View File

@ -8,7 +8,8 @@ trait VoiceApp2x extends UserJoinedVoiceConfEvtMsgHdlr
with UserLeftVoiceConfEvtMsgHdlr
with UserMutedInVoiceConfEvtMsgHdlr
with UserTalkingInVoiceConfEvtMsgHdlr
with RecordingStartedVoiceConfEvtMsgHdlr {
with RecordingStartedVoiceConfEvtMsgHdlr
with VoiceConfRunningEvtMsgHdlr {
this: MeetingActor =>
}

View File

@ -0,0 +1,15 @@
package org.bigbluebutton.core.apps.voice
import org.bigbluebutton.common2.msgs.VoiceConfRunningEvtMsg
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter }
trait VoiceConfRunningEvtMsgHdlr {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
def handleVoiceConfRunningEvtMsg(msg: VoiceConfRunningEvtMsg): Unit = {
log.info("Received VoiceConfRunningEvtMsg " + msg.body.running)
}
}

View File

@ -192,4 +192,5 @@ object Roles {
val PRESENTER_ROLE = "PRESENTER"
val VIEWER_ROLE = "VIEWER"
val GUEST_ROLE = "GUEST"
val AUTHENTICATED_ROLE = "AUTHENTICATED"
}

View File

@ -37,7 +37,6 @@ object VoiceUsers {
} yield {
val vu = u.modify(_.muted).setTo(muted)
.modify(_.talking).setTo(false)
.modify(_.listenOnly).setTo(false)
users.save(vu)
vu
}
@ -49,7 +48,6 @@ object VoiceUsers {
} yield {
val vu = u.modify(_.muted).setTo(false)
.modify(_.talking).setTo(talkng)
.modify(_.listenOnly).setTo(false)
users.save(vu)
vu
}
@ -61,7 +59,6 @@ object VoiceUsers {
} yield {
val vu = u.modify(_.muted).setTo(true)
.modify(_.talking).setTo(false)
.modify(_.listenOnly).setTo(true)
users.save(vu)
vu
}
@ -73,7 +70,6 @@ object VoiceUsers {
} yield {
val vu = u.modify(_.muted).setTo(false)
.modify(_.talking).setTo(false)
.modify(_.listenOnly).setTo(false)
users.save(vu)
vu
}

View File

@ -112,6 +112,8 @@ class ReceivedJsonMsgHandlerActor(
// Voice
case RecordingStartedVoiceConfEvtMsg.NAME =>
routeVoiceMsg[RecordingStartedVoiceConfEvtMsg](envelope, jsonNode)
case VoiceConfRunningEvtMsg.NAME =>
routeVoiceMsg[VoiceConfRunningEvtMsg](envelope, jsonNode)
case UserJoinedVoiceConfEvtMsg.NAME =>
routeVoiceMsg[UserJoinedVoiceConfEvtMsg](envelope, jsonNode)
case UserLeftVoiceConfEvtMsg.NAME =>

View File

@ -62,7 +62,6 @@ class MeetingActor(
with BreakoutApp2x
with UsersApp2x
with PermisssionCheck
with UserBroadcastCamStartMsgHdlr
with UserJoinMeetingReqMsgHdlr
with UserJoinMeetingAfterReconnectReqMsgHdlr
@ -71,8 +70,9 @@ class MeetingActor(
with UserDisconnectedFromGlobalAudioMsgHdlr
with MuteAllExceptPresentersCmdMsgHdlr
with MuteMeetingCmdMsgHdlr
with MuteMeetingCmdMsgHdlrCheckPerm
with IsMeetingMutedReqMsgHdlr
with MuteUserCmdMsgHdlr
with EjectUserFromVoiceCmdMsgHdlr
with EndMeetingSysCmdMsgHdlr
with DestroyMeetingSysCmdMsgHdlr
@ -268,13 +268,14 @@ class MeetingActor(
case m: UserMutedInVoiceConfEvtMsg => handleUserMutedInVoiceConfEvtMsg(m)
case m: UserTalkingInVoiceConfEvtMsg => handleUserTalkingInVoiceConfEvtMsg(m)
case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m)
case m: MuteUserCmdMsg => handleMuteUserCmdMsg(m)
case m: MuteUserCmdMsg => usersApp.handleMuteUserCmdMsg(m)
case m: MuteAllExceptPresentersCmdMsg => handleMuteAllExceptPresentersCmdMsg(m)
case m: EjectUserFromVoiceCmdMsg => handleEjectUserFromVoiceCmdMsg(m)
case m: IsMeetingMutedReqMsg => handleIsMeetingMutedReqMsg(m)
case m: MuteMeetingCmdMsg => handleMuteMeetingCmdMsg(m)
case m: UserConnectedToGlobalAudioMsg => handleUserConnectedToGlobalAudioMsg(m)
case m: UserDisconnectedFromGlobalAudioMsg => handleUserDisconnectedFromGlobalAudioMsg(m)
case m: VoiceConfRunningEvtMsg => handleVoiceConfRunningEvtMsg(m)
// Layout
case m: GetCurrentLayoutReqMsg => handleGetCurrentLayoutReqMsg(m)

View File

@ -1,17 +1,43 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.apps.PermisssionCheck
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core2.MeetingStatus2x
trait MuteMeetingCmdMsgHdlr {
trait MuteMeetingCmdMsgHdlrDefault {
def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {}
}
trait MuteMeetingCmdMsgHdlrCheckPerm extends MuteMeetingCmdMsgHdlrDefault with SystemConfiguration {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg) {
override def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {
val isAllowed = PermisssionCheck.isAllowed(
PermisssionCheck.MOD_LEVEL,
PermisssionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.body.mutedBy
)
if (applyPermissionCheck && !isAllowed) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to mute meeting."
PermisssionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW)
} else {
super.handleMuteMeetingCmdMsg(msg)
}
}
}
trait MuteMeetingCmdMsgHdlr extends MuteMeetingCmdMsgHdlrDefault {
this: MeetingActor =>
val outGW: OutMsgRouter
override def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {
def build(meetingId: String, userId: String, muted: Boolean, mutedBy: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)

View File

@ -166,11 +166,12 @@ object MsgBuilder {
BbbCommonEnvCoreMsg(envelope, event)
}
def buildUserEjectedFromMeetingEvtMsg(meetingId: String, userId: String, ejectedBy: String): BbbCommonEnvCoreMsg = {
def buildUserEjectedFromMeetingEvtMsg(meetingId: String, userId: String,
ejectedBy: String, reason: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
val envelope = BbbCoreEnvelope(UserEjectedFromMeetingEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserEjectedFromMeetingEvtMsg.NAME, meetingId, userId)
val body = UserEjectedFromMeetingEvtMsgBody(userId, ejectedBy)
val body = UserEjectedFromMeetingEvtMsgBody(userId, ejectedBy, reason)
val event = UserEjectedFromMeetingEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)

View File

@ -1,8 +1,22 @@
package org.bigbluebutton.core2.message.senders
import org.bigbluebutton.common2.msgs.BbbCommonEnvCoreMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.OutMsgRouter
trait Sender {
object Sender {
def sendUserEjectedFromMeetingClientEvtMsg(meetingId: String, userId: String,
ejectedBy: String, reason: String, outGW: OutMsgRouter): Unit = {
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(
meetingId, userId, ejectedBy, reason
)
outGW.send(ejectFromMeetingClientEvent)
}
def sendUserEjectedFromMeetingSystemMsg(meetingId: String, userId: String,
ejectedBy: String, outGW: OutMsgRouter): Unit = {
val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(
meetingId, userId, ejectedBy
)
outGW.send(ejectFromMeetingSystemEvent)
}
}

View File

@ -53,7 +53,7 @@ libraryDependencies ++= {
libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT"
libraryDependencies += "org.bigbluebutton" % "bbb-fsesl-client" % "0.0.5"
libraryDependencies += "org.bigbluebutton" % "bbb-fsesl-client" % "0.0.6"
// https://mvnrepository.com/artifact/org.scala-lang/scala-library
libraryDependencies += "org.scala-lang" % "scala-library" % "2.12.2"

View File

@ -1,20 +1,19 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* <p>
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.freeswitch.voice;
@ -24,16 +23,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.bigbluebutton.freeswitch.voice.events.ScreenshareStartedEvent;
import org.bigbluebutton.freeswitch.voice.events.DeskShareEndedEvent;
import org.bigbluebutton.freeswitch.voice.events.ConferenceEventListener;
import org.bigbluebutton.freeswitch.voice.events.ScreenshareRTMPBroadcastEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceConferenceEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceStartRecordingEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserJoinedEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserLeftEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserMutedEvent;
import org.bigbluebutton.freeswitch.voice.events.VoiceUserTalkingEvent;
import org.bigbluebutton.freeswitch.voice.events.*;
public class FreeswitchConferenceEventListener implements ConferenceEventListener {
private static final int SENDERTHREADS = 1;
@ -64,6 +54,9 @@ public class FreeswitchConferenceEventListener implements ConferenceEventListene
VoiceUserJoinedEvent evt = (VoiceUserJoinedEvent) event;
vcs.userJoinedVoiceConf(evt.getRoom(), evt.getVoiceUserId(), evt.getUserId(), evt.getCallerIdName(),
evt.getCallerIdNum(), evt.getMuted(), evt.getSpeaking(), evt.getAvatarURL());
} else if (event instanceof VoiceConfRunningEvent) {
VoiceConfRunningEvent evt = (VoiceConfRunningEvent) event;
vcs.voiceConfRunning(evt.getRoom(), evt.isRunning());
} else if (event instanceof VoiceUserLeftEvent) {
VoiceUserLeftEvent evt = (VoiceUserLeftEvent) event;
vcs.userLeftVoiceConf(evt.getRoom(), evt.getUserId());

View File

@ -2,15 +2,26 @@ package org.bigbluebutton.freeswitch.voice;
public interface IVoiceConferenceService {
void voiceConfRecordingStarted(String voiceConfId, String recordStream, Boolean recording, String timestamp);
void voiceConfRunning(String voiceConfId, Boolean running);
void userJoinedVoiceConf(String voiceConfId, String voiceUserId, String userId, String callerIdName,
String callerIdNum, Boolean muted, Boolean speaking, String avatarURL);
void userLeftVoiceConf(String voiceConfId, String voiceUserId);
void userLockedInVoiceConf(String voiceConfId, String voiceUserId, Boolean locked);
void userMutedInVoiceConf(String voiceConfId, String voiceUserId, Boolean muted);
void userTalkingInVoiceConf(String voiceConfId, String voiceUserId, Boolean talking);
void deskShareStarted(String voiceConfId, String callerIdNum, String callerIdName);
void deskShareEnded(String voiceConfId, String callerIdNum, String callerIdName);
void deskShareRTMPBroadcastStarted(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp);
void deskShareRTMPBroadcastStopped(String room, String streamname, Integer videoWidth, Integer videoHeight, String timestamp);
}

View File

@ -0,0 +1,32 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
* <p>
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.freeswitch.voice.events;
public class VoiceConfRunningEvent extends VoiceConferenceEvent {
private boolean running;
public VoiceConfRunningEvent(String room, boolean running) {
super(room);
this.running = running;
}
public boolean isRunning() {
return running;
}
}

View File

@ -18,6 +18,8 @@ public class ESLEventListener implements IEslEventListener {
private static final String STOP_TALKING_EVENT = "stop-talking";
private static final String START_RECORDING_EVENT = "start-recording";
private static final String STOP_RECORDING_EVENT = "stop-recording";
private static final String CONFERENCE_CREATED_EVENT = "conference-create";
private static final String CONFERENCE_DESTROYED_EVENT = "conference-destroy";
private static final String SCREENSHARE_CONFERENCE_NAME_SUFFIX = "-SCREENSHARE";
@ -119,18 +121,23 @@ public class ESLEventListener implements IEslEventListener {
@Override
public void conferenceEventAction(String uniqueId, String confName, int confSize, String action, EslEvent event) {
Integer memberId = this.getMemberIdFromEvent(event);
VoiceUserTalkingEvent pt;
if (action == null) {
return;
}
if (action.equals(START_TALKING_EVENT)) {
pt = new VoiceUserTalkingEvent(memberId.toString(), confName, true);
Integer memberId = this.getMemberIdFromEvent(event);
VoiceUserTalkingEvent pt = new VoiceUserTalkingEvent(memberId.toString(), confName, true);
conferenceEventListener.handleConferenceEvent(pt);
} else if (action.equals(STOP_TALKING_EVENT)) {
pt = new VoiceUserTalkingEvent(memberId.toString(), confName, false);
Integer memberId = this.getMemberIdFromEvent(event);
VoiceUserTalkingEvent pt = new VoiceUserTalkingEvent(memberId.toString(), confName, false);
conferenceEventListener.handleConferenceEvent(pt);
} else if (action.equals(CONFERENCE_CREATED_EVENT)) {
VoiceConfRunningEvent pt = new VoiceConfRunningEvent(confName, true);
conferenceEventListener.handleConferenceEvent(pt);
} else if (action.equals(CONFERENCE_DESTROYED_EVENT)) {
VoiceConfRunningEvent pt = new VoiceConfRunningEvent(confName, false);
conferenceEventListener.handleConferenceEvent(pt);
} else {
System.out.println("Unknown conference Action [" + action + "]");

View File

@ -23,6 +23,19 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
}
def voiceConfRunning(voiceConfId: String, running: java.lang.Boolean): Unit = {
println("*************######## Conference voiceConfId=" + voiceConfId + " running=" + running)
val header = BbbCoreVoiceConfHeader(VoiceConfRunningEvtMsg.NAME, voiceConfId)
val body = VoiceConfRunningEvtMsgBody(voiceConfId, running.booleanValue())
val envelope = BbbCoreEnvelope(VoiceConfRunningEvtMsg.NAME, Map("voiceConf" -> voiceConfId))
val msg = new VoiceConfRunningEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, msg)
val json = JsonUtil.toJson(msgEvent)
sender.publish(fromVoiceConfRedisChannel, json)
}
def userJoinedVoiceConf(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
callerIdNum: String, muted: java.lang.Boolean, talking: java.lang.Boolean, avatarURL: String) {

View File

@ -127,7 +127,7 @@ case class UserEmojiChangedEvtMsgBody(userId: String, emoji: String)
*/
object UserEjectedFromMeetingEvtMsg { val NAME = "UserEjectedFromMeetingEvtMsg" }
case class UserEjectedFromMeetingEvtMsg(header: BbbClientMsgHeader, body: UserEjectedFromMeetingEvtMsgBody) extends StandardMsg
case class UserEjectedFromMeetingEvtMsgBody(userId: String, ejectedBy: String)
case class UserEjectedFromMeetingEvtMsgBody(userId: String, ejectedBy: String, reason: String)
object AssignPresenterReqMsg { val NAME = "AssignPresenterReqMsg"}
case class AssignPresenterReqMsg(header: BbbClientMsgHeader, body: AssignPresenterReqMsgBody) extends StandardMsg

View File

@ -228,6 +228,15 @@ case class MeetingMutedEvtMsgBody(muted: Boolean, mutedBy: String)
callerNum: String, muted: Boolean,
talking: Boolean, callingWith: String, listenOnly: Boolean)
/**
* Received from FS about the conference is running (created, destroyed).
*/
object VoiceConfRunningEvtMsg { val NAME = "VoiceConfRunningEvtMsg" }
case class VoiceConfRunningEvtMsg(header: BbbCoreVoiceConfHeader,
body: VoiceConfRunningEvtMsgBody) extends VoiceStandardMsg
case class VoiceConfRunningEvtMsgBody(voiceConf: String, running: Boolean)
/**
* Received from FS that user has left the voice conference.
*/

View File

@ -6,7 +6,7 @@ description := "BigBlueButton custom FS-ESL client built on top of FS-ESL Java l
organization := "org.bigbluebutton"
version := "0.0.5"
version := "0.0.6"
// We want to have our jar files in lib_managed dir.
// This way we'll have the right path when we import

View File

@ -25,7 +25,7 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Iterator;
import org.freeswitch.esl.client.IEslEventListener;
import org.freeswitch.esl.client.internal.IEslProtocolListener;
import org.freeswitch.esl.client.transport.CommandResponse;
@ -461,12 +461,30 @@ public class Client
String eventFunc = eventHeaders.get("Event-Calling-Function");
String uniqueId = eventHeaders.get("Caller-Unique-ID");
String confName = eventHeaders.get("Conference-Name");
String eventAction = eventHeaders.get("Action");
int confSize = Integer.parseInt(eventHeaders.get("Conference-Size"));
/**
StringBuilder sb = new StringBuilder("");
sb.append("\n");
for (Iterator it = eventHeaders.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
sb.append(entry.getKey());
sb.append(" => '");
sb.append(entry.getValue());
sb.append("'\n");
}
//FIXME: all by Action eventHeader really.... maybe?
// But this way we filter whole sections of Action events
if (eventFunc == null) {
System.out.println("##### Received Event for " + confName);
System.out.println("##### " + sb.toString());
**/
if (eventFunc == null || eventAction == null) {
//Noop...
} else if (eventAction.equals("conference-create")) {
listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event);
return;
} else if (eventAction.equals("conference-destroy")) {
listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event);
return;
} else if (eventFunc.equals("conference_thread_run")) {
System.out.println("##### Client conference_thread_run");
listener.conferenceEventThreadRun(uniqueId, confName, confSize, event);
@ -498,13 +516,14 @@ public class Client
listener.conferenceEventRecord(uniqueId, confName, confSize, event);
return;
} else if (eventFunc.equals("conference_loop_input")) {
listener.conferenceEventAction(uniqueId, confName, confSize, eventHeaders.get("Action"), event);
listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event);
return;
} else if (eventFunc.equals("stop_talking_handler")) {
listener.conferenceEventAction(uniqueId, confName, confSize, eventHeaders.get("Action"), event);
listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event);
return;
} else {
/* StringBuilder sb = new StringBuilder("");
/**
StringBuilder sb = new StringBuilder("");
sb.append("\n");
for (Iterator it = eventHeaders.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry)it.next();
@ -514,11 +533,11 @@ public class Client
sb.append("'\n");
}
log.info ("Unknown Conference Event [{}] [{}]", confName, sb.toString());
*/
System.out.println("##### unhandled Event for " + confName);
System.out.println("##### " + sb.toString());
**/
}
}
listener.eventReceived( event );
} catch ( Throwable t ) {
log.error( "Error caught notifying listener of event [" + event + ']', t );

View File

@ -144,8 +144,7 @@ phonecomponents|MuteMeButton {
.toolbarMainBox {
backgroundColor : #FFFFFF;
paddingTop : 0;
paddingBottom : 0;
verticalGap : 0;
paddingBottom : 6;
}
.breakoutRoomRibbon {
@ -164,7 +163,7 @@ phonecomponents|MuteMeButton {
}
.topBoxStyle {
paddingTop : 0;
paddingTop : 6;
paddingBottom : 0;
paddingLeft : 8;
paddingRight : 8;
@ -437,7 +436,7 @@ mx|Button {
borderAlphaUp : 1;
borderAlphaOver : 1;
borderAlphaDown : 1;
borderAlphaDisabled : 1;
borderAlphaDisabled : 0.25;
borderThickness : 1;
@ -554,6 +553,10 @@ views|BrowserPermissionHelper {
//------------------------------
*/
views|ClientStatusWindow {
horizontalAlign : right;
}
views|ClientStatusItemRenderer {
iconSuccess : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Success");
iconWarning : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Warning");
@ -771,10 +774,6 @@ mx|DataGrid {
//------------------------------
*/
.deskshareControlButtonStyle {
cornerRadius : 18;
}
.deskshareWarningLabelStyle {
fontWeight : bold;
fontSize : 18;
@ -937,6 +936,7 @@ views|LockSettings {
*/
views|MainApplicationShell {
borderStyle : none;
paddingBottom : 0;
verticalGap : 0;
}
@ -1089,6 +1089,35 @@ views|NetworkStatsWindow {
iconRefresh : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Refresh");
}
/*
//------------------------------
// NumericStepper
//------------------------------
*/
mx|NumericStepper {
/* Normal state */
fillColorUp : #FFFFFF;
fillColorOver : #CDD4DB;
fillColorDown : #ACB2B7;
fillColorDisabled : #F0F2F6;
borderColorUp : #CDD4DB;
borderColorOver : #1070D7;
borderColorDown : #0A5EAC;
borderColorDisabled : #CDD4DB;
/* Icon states */
iconColor : #4E5A66;
iconColorOver : #1070D7;
iconColorDown : #4E5A66;
borderThickness : 1;
/* Skins */
downArrowSkin : ClassReference("org.bigbluebutton.skins.NumericStepperDownSkin");
upArrowSkin : ClassReference("org.bigbluebutton.skins.NumericStepperUpSkin");
}
/*
//------------------------------
// PopUpButton

View File

@ -22,24 +22,6 @@ package org.bigbluebutton.skins {
public class ButtonSkin extends Border {
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function ButtonSkin() {
super();
}
//--------------------------------------------------------------------------
//
// Overridden properties

View File

@ -0,0 +1,166 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2017 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/>.
*
*/
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.bigbluebutton.skins {
import flash.display.Graphics;
import mx.skins.Border;
public class NumericStepperDownSkin extends Border {
//--------------------------------------------------------------------------
//
// Overridden properties
//
//--------------------------------------------------------------------------
//----------------------------------
// measuredWidth
//----------------------------------
/**
* @private
*/
override public function get measuredWidth():Number {
return 19;
}
//----------------------------------
// measuredHeight
//----------------------------------
/**
* @private
*/
override public function get measuredHeight():Number {
return 11;
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
var borderColorUp:uint = getStyle("borderColorUp");
var borderColorOver:uint = getStyle("borderColorOver");
var borderColorDown:uint = getStyle("borderColorDown");
var borderColorDisabled:uint = getStyle("borderColorDisabled");
var borderThickness:uint = getStyle("borderThickness");
var fillColorUp:uint = getStyle("fillColorUp");
var fillColorOver:uint = getStyle("fillColorOver");
var fillColorDown:uint = getStyle("fillColorDown");
var fillColorDisabled:uint = getStyle("fillColorDisabled");
// User-defined styles.
var arrowColor:uint = getStyle("iconColor");
var arrowColorOver:uint = getStyle("iconColorOver");
var arrowColorDown:uint = getStyle("iconColorDown");
var cornerRadius:Number = getStyle("cornerRadius");
var cr:Object = {tl: 0, tr: 0, bl: 0, br: cornerRadius};
var cr1:Object = {tl: 0, tr: 0, bl: 0, br: Math.max(cornerRadius - 1, 0)};
// Draw the background and border.
var g:Graphics = graphics;
g.clear();
switch (name) {
case "downArrowUpSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorUp, 1, null, null, null, {x: 1, y: 0, w: w - 2, h: h - 1, r: cr1});
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorUp, 1);
break;
}
case "downArrowOverSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorOver, 1, null, null, null, {x: 1, y: 0, w: w - 2, h: h - 1, r: cr1});
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorOver, 1, null);
break;
}
case "downArrowDownSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorDown, 1);
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDown, 1);
break;
}
case "downArrowDisabledSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorDisabled, 0.5, null, null, null, {x: 1, y: 0, w: w - 2, h: h - 1, r: cr1});
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDisabled, 0.5, null);
arrowColor = getStyle("disabledIconColor");
break;
}
}
// Draw the arrow.
g.beginFill(arrowColor);
g.moveTo(w / 2, h / 2 + 1.5);
g.lineTo(w / 2 - 3.5, h / 2 - 2.5);
g.lineTo(w / 2 + 3.5, h / 2 - 2.5);
g.lineTo(w / 2, h / 2 + 1.5);
g.endFill();
}
}
}

View File

@ -0,0 +1,165 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2017 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/>.
*
*/
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.bigbluebutton.skins {
import flash.display.Graphics;
import mx.skins.Border;
public class NumericStepperUpSkin extends Border {
//--------------------------------------------------------------------------
//
// Overridden properties
//
//--------------------------------------------------------------------------
//----------------------------------
// measuredWidth
//----------------------------------
/**
* @private
*/
override public function get measuredWidth():Number {
return 19;
}
//----------------------------------
// measuredHeight
//----------------------------------
/**
* @private
*/
override public function get measuredHeight():Number {
return 11;
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
var borderColorUp:uint = getStyle("borderColorUp");
var borderColorOver:uint = getStyle("borderColorOver");
var borderColorDown:uint = getStyle("borderColorDown");
var borderColorDisabled:uint = getStyle("borderColorDisabled");
var borderThickness:uint = getStyle("borderThickness");
var fillColorUp:uint = getStyle("fillColorUp");
var fillColorOver:uint = getStyle("fillColorOver");
var fillColorDown:uint = getStyle("fillColorDown");
var fillColorDisabled:uint = getStyle("fillColorDisabled");
// User-defined styles.
var arrowColor:uint = getStyle("iconColor");
var arrowColorOver:uint = getStyle("iconColorOver");
var arrowColorDown:uint = getStyle("iconColorDown");
var cornerRadius:Number = getStyle("cornerRadius");
var cr:Object = {tl: 0, tr: cornerRadius, bl: 0, br: 0};
var cr1:Object = {tl: 0, tr: Math.max(cornerRadius - 1, 0), bl: 0, br: 0};
// Draw the background and border.
var g:Graphics = graphics;
g.clear();
switch (name) {
case "upArrowUpSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorUp, 1, null, null, null, {x: 1, y: 1, w: w - 2, h: h - 2, r: cr1});
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorUp, 1);
break;
}
case "upArrowOverSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorOver, 1, null, null, null, {x: 1, y: 1, w: w - 2, h: h - 2, r: cr1});
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorOver, 1, null);
break;
}
case "upArrowDownSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorDown, 1);
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDown, 1);
break;
}
case "upArrowDisabledSkin": {
// border
drawRoundRect(0, 0, w, h, cr, borderColorDisabled, 0.5, null, null, null, {x: 1, y: 1, w: w - 2, h: h - 2, r: cr1});
// button fill
drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDisabled, 0.5, null);
arrowColor = getStyle("disabledIconColor");
break;
}
}
// Draw the arrow.
g.beginFill(arrowColor);
g.moveTo(w / 2, h / 2 - 2.5);
g.lineTo(w / 2 - 3.5, h / 2 + 1.5);
g.lineTo(w / 2 + 3.5, h / 2 + 1.5);
g.lineTo(w / 2, h / 2 - 2.5);
g.endFill();
}
}
}

View File

@ -48,17 +48,6 @@ package org.bigbluebutton.skins {
public class TabSkin extends Border {
//--------------------------------------------------------------------------
//
// Class variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private static var cache:Object = {};
//--------------------------------------------------------------------------
//
// Overridden properties

View File

@ -385,6 +385,7 @@ bbb.video.publish.closeBtn.accessName = Close the webcam settings dialog box
bbb.video.publish.closeBtn.label = Cancel
bbb.video.publish.titleBar = Publish Webcam Window
bbb.video.streamClose.toolTip = Close stream for: {0}
bbb.video.message.browserhttp = This server is not configured with SSL. As a result, {0} disables sharing of your webcam.
bbb.screensharePublish.title = Screen Sharing: Presenter's Preview
bbb.screensharePublish.pause.tooltip = Pause screen share
bbb.screensharePublish.pause.label = Pause
@ -464,6 +465,7 @@ bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Screen
bbb.toolbar.sharednotes.toolTip = Open Shared Notes
bbb.toolbar.video.toolTip.start = Share Your Webcam
bbb.toolbar.video.toolTip.stop = Stop Sharing Your Webcam
bbb.layout.addButton.label = Add
bbb.layout.addButton.toolTip = Add the custom layout to the list
bbb.layout.overwriteLayoutName.title = Overwrite layout
bbb.layout.overwriteLayoutName.text = Name already in use. Do you want to overwrite?
@ -477,6 +479,8 @@ bbb.layout.combo.custom = * Custom layout
bbb.layout.combo.customName = Custom layout
bbb.layout.combo.remote = Remote
bbb.layout.window.name = Layout name
bbb.layout.window.close.tooltip = Close
bbb.layout.window.close.accessibilityName = Close add new layout window
bbb.layout.save.complete = Layouts were successfully saved
bbb.layout.save.ioerror = Layouts were not saved. Try saving again.
bbb.layout.load.complete = Layouts were successfully loaded

View File

@ -8,10 +8,10 @@
<bwMon server="HOST" application="video/bwTest"/>
<application uri="rtmp://HOST/bigbluebutton" host="http://HOST/bigbluebutton/api/enter"/>
<language userSelectionEnabled="true" rtlEnabled="false"/>
<skinning enabled="true" url="http://HOST/client/branding/css/V2Theme.css.swf?v=VERSION" />
<skinning url="http://HOST/client/branding/css/V2Theme.css.swf?v=VERSION" />
<branding logo="logo.swf" copyright="&#169; 2017 &lt;u&gt;&lt;a href=&quot;http://HOST/home.html&quot; target=&quot;_blank&quot;&gt;BigBlueButton Inc.&lt;/a&gt;&lt;/u&gt; (build {0})" background="" toolbarColor="" showQuote="true"/>
<shortcutKeys showButton="true" />
<browserVersions chrome="CHROME_VERSION" firefox="FIREFOX_VERSION" flash="FLASH_VERSION" java="1.7.0_51" />
<browserVersions chrome="CHROME_VERSION" firefox="FIREFOX_VERSION" flash="FLASH_VERSION"/>
<layout showLogButton="false" defaultLayout="bbb.layout.name.defaultlayout"
showToolbar="true" showFooter="true" showMeetingName="true" showHelpButton="true"
showLogoutWindow="true" showLayoutTools="true" confirmLogout="true" showNetworkMonitor="false"

View File

@ -97,11 +97,9 @@ function determineBrowser()
var nameOffset,verOffset,ix;
// In Opera, the true version is after "Opera" or after "Version"
if ((verOffset=nAgt.indexOf("Opera"))!=-1) {
if ((verOffset=nAgt.indexOf("OPR/"))!=-1) {
browserName = "Opera";
fullVersion = nAgt.substring(verOffset+6);
if ((verOffset=nAgt.indexOf("Version"))!=-1)
fullVersion = nAgt.substring(verOffset+8);
fullVersion = nAgt.substring(verOffset+4);
}
// In MSIE, the true version is after "MSIE" in userAgent
else if ((verOffset=nAgt.indexOf("MSIE"))!=-1) {

View File

@ -0,0 +1,26 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2017 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.common {
/**
* Add it to popup classes to add the Keyboard.ESCAPE close behaviour
*/
public interface IKeyboardClose {
}
}

View File

@ -18,6 +18,8 @@
*/
package org.bigbluebutton.core {
import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
@ -30,6 +32,7 @@ package org.bigbluebutton.core {
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IKeyboardClose;
public final class PopUpUtil {
@ -37,7 +40,7 @@ package org.bigbluebutton.core {
private static var popUpDict:Dictionary = new Dictionary(true);
public static function createNonModelPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
public static function createNonModalPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
if (!checkPopUpExists(className)) {
return addPopUpToStage(parent, className, false, center);
}
@ -84,9 +87,20 @@ package org.bigbluebutton.core {
}
popUpDict[getQualifiedClassName(className)] = popUp;
if (popUp is IKeyboardClose) {
popUp.addEventListener(KeyboardEvent.KEY_DOWN, escapeKeyDownHandler);
}
LOGGER.debug("Created PopUp with type [{0}]", [className]);
return popUp;
}
private static function escapeKeyDownHandler(event:KeyboardEvent):void {
if (event.charCode == Keyboard.ESCAPE) {
event.currentTarget.removeEventListener(KeyboardEvent.KEY_DOWN, escapeKeyDownHandler);
removePopUp(event.currentTarget);
}
}
}
}

View File

@ -51,6 +51,7 @@ package org.bigbluebutton.core.model
public var authTokenValid: Boolean = false;
public var waitingForApproval: Boolean;
public var breakoutEjectFromAudio : Boolean = false;
private var _role:String = "viewer";
public function get role():String {

View File

@ -44,12 +44,6 @@ package org.bigbluebutton.main.api
return false;
}
public function getBrowserInfo():Array {
if (ExternalInterface.available) {
return ExternalInterface.call("determineBrowser");
}
return ["unknown", 0, 0];
}
}
}

View File

@ -1,30 +0,0 @@
/**
* 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/>.
*
*/
package org.bigbluebutton.main.model.modules
{
import mx.modules.ModuleLoader;
public class BigBlueButtonModuleLoader extends ModuleLoader
{
public function BigBlueButtonModuleLoader()
{
super();
}
}
}

View File

@ -38,7 +38,7 @@ package org.bigbluebutton.main.model.modules
private static const LOGGER:ILogger = getClassLogger(ModuleDescriptor);
private var _attributes:Object;
private var _loader:BigBlueButtonModuleLoader;
private var _loader:ModuleLoader;
private var _module:IBigBlueButtonModule;
private var _loaded:Boolean = false;
private var _connected:Boolean = false;
@ -53,7 +53,7 @@ package org.bigbluebutton.main.model.modules
{
unresolvedDependancies = new ArrayCollection();
_attributes = new Object();
_loader = new BigBlueButtonModuleLoader();
_loader = new ModuleLoader();
parseAttributes(attributes);
}

View File

@ -30,9 +30,6 @@ package org.bigbluebutton.main.model.options {
[Bindable]
public var flash:String = "";
[Bindable]
public var java:String = "";
public function BrowserVersionsOptions() {
name = "browserVersions";
}

View File

@ -21,9 +21,6 @@ package org.bigbluebutton.main.model.options {
public class SkinningOptions extends Options {
[Bindable]
public var enabled:Boolean = true;
[Bindable]
public var url:String = "";

View File

@ -62,6 +62,15 @@ package org.bigbluebutton.main.model.users {
users.addItem(user);
}
public function hasUserWithId(userId:String) : Boolean {
for (var i : int = 0; i < users.length; i++) {
if (BreakoutUser(users.getItemAt(i)).id.indexOf(userId) > -1 ) {
return true;
}
}
return false;
}
public function removeUser(id: String): void {
for (var i: int = 0; i < users.length; i++) {
var user: BreakoutUser = users[i] as BreakoutUser;

View File

@ -23,9 +23,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
implements="org.bigbluebutton.common.IKeyboardClose"
show="this.setFocus()"
initialize="init()"
layout="absolute"
close="onCancelClicked()"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
showCloseButton="false">
@ -44,18 +45,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.phone.events.JoinVoiceConferenceCommand;
import org.bigbluebutton.modules.phone.events.UseFlashModeCommand;
import org.bigbluebutton.modules.phone.models.PhoneOptions;
import org.bigbluebutton.util.browser.BrowserCheck;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(AudioSelectionWindow);
private var phoneOptions:PhoneOptions;
private var browserInfo:Array;
private function init():void {
phoneOptions = Options.getOptions(PhoneOptions) as PhoneOptions;
browserInfo = JSAPI.getInstance().getBrowserInfo();
if (!phoneOptions.listenOnlyMode)
btnListenOnly.enabled = false;
@ -75,7 +74,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
// If Puffin browser is deteted and version is less than 4.6
if (browserInfo[0] == "Puffin" && String(browserInfo[2]).substr(0, 3) < "4.6") {
if (BrowserCheck.isPuffinBelow46()) {
vboxListen.percentWidth = 100;
}
}
@ -83,10 +82,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function onMicClick():void {
LOGGER.debug("AudioSelectionWindow - Share Microphone Clicked");
var dispatcher:Dispatcher = new Dispatcher();
if (browserInfo[0] == "Puffin" && String(browserInfo[2]).substr(0, 3) >= "4.6") {
if (BrowserCheck.isPuffin46AndAbove() || (!BrowserCheck.isHttps() && ((BrowserCheck.isChrome() && BrowserCheck.browserMajorVersion >= "60") || (BrowserCheck.isOpera() && BrowserCheck.browserMajorVersion >= "47")))) {
dispatcher.dispatchEvent(new UseFlashModeCommand());
}
else {
} else {
var command:JoinVoiceConferenceCommand = new JoinVoiceConferenceCommand();
command.mic = true;
dispatcher.dispatchEvent(command);
@ -106,7 +104,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onCancelClicked():void {
LOGGER.debug("AudioSelectionWindow - Cancel clicked");
LOGGER.debug("AudioSelectionWindow - Close clicked");
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.CLOSED_AUDIO_SELECTION));

View File

@ -3,6 +3,8 @@
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:common="org.bigbluebutton.common.*"
xmlns:mate="http://mate.asfusion.com/"
implements="org.bigbluebutton.common.IKeyboardClose"
show="this.setFocus()"
layout="vertical"
horizontalAlign="center"
showCloseButton="false"
@ -14,6 +16,7 @@
import mx.core.UIComponent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.IKeyboardClose;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;

View File

@ -25,7 +25,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
layout="absolute"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
width="630" height="450" creationComplete="onCreationComplete()" styleName="cameraDisplaySettingsWindowStyle"
showCloseButton="false" close="onCancelClicked()" keyDown="handleKeyDown(event)">
showCloseButton="false" keyDown="handleKeyDown(event)">
<fx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
@ -34,7 +34,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.events.CloseEvent;
import org.bigbluebutton.common.Media;
import org.bigbluebutton.core.BBB;
@ -188,8 +187,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function handleKeyDown(event:KeyboardEvent):void {
if (event.charCode == Keyboard.ESCAPE) {
disableCamera();
this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
onCancelClicked();
}
}

View File

@ -23,12 +23,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:chat="org.bigbluebutton.modules.chat.views.*"
width="500" height="400"
implements="org.bigbluebutton.common.IKeyboardClose"
show="this.setFocus()"
horizontalScrollPolicy="off"
title="{ResourceUtil.getInstance().getString('bbb.clientstatus.title')}"
horizontalAlign="center"
creationComplete="onCreationComplete();">
<fx:Script>
<![CDATA[
import org.bigbluebutton.common.IKeyboardClose;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -45,6 +47,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
]]>
</fx:Script>
<chat:AdvancedList id="messageList" width="100%" dragEnabled="false" variableRowHeight="true" wordWrap="true" alternatingItemColors="[#EFEFEF, #FEFEFE]" itemRenderer="org.bigbluebutton.main.views.ClientStatusItemRenderer"/>
<chat:AdvancedList id="messageList" width="100%" height="100%" dragEnabled="false" variableRowHeight="true" wordWrap="true" itemRenderer="org.bigbluebutton.main.views.ClientStatusItemRenderer"/>
<mx:Button id="closeBtn" label="{ResourceUtil.getInstance().getString('bbb.clientstatus.close')}" click="handleCloseButtonClick();" />
</mx:TitleWindow>

View File

@ -26,7 +26,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
verticalScrollPolicy="off"
creationComplete="onCreationComplete()"
showCloseButton="false"
close="onCancelClicked()"
keyDown="handleKeyDown(event)">
<fx:Declarations>
@ -44,7 +43,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import flash.ui.Keyboard;
import mx.controls.sliderClasses.Slider;
import mx.events.CloseEvent;
import mx.events.SliderEvent;
import org.as3commons.logging.api.ILogger;
@ -184,7 +182,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
// Added by Chad to enable closing the window without clicking the X
private function handleKeyDown(event:KeyboardEvent):void {
if (event.charCode == Keyboard.ESCAPE) {
this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
onCancelClicked();
}
}

View File

@ -131,7 +131,6 @@ $Id: $
public function closeWindow():void {
this.visible = false;
PopUpManager.removePopUp(this);
//dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
}
]]>

View File

@ -21,15 +21,14 @@ 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/"
implements="org.bigbluebutton.common.IKeyboardClose"
show="this.setFocus()"
xmlns:common="org.bigbluebutton.common.*"
minWidth="340" showCloseButton="false"
close="onCancelClicked()"
keyDown="handleKeyDown(event)">
<fx:Script>
<![CDATA[
import mx.events.CloseEvent;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.events.LockControlEvent;
import org.bigbluebutton.core.vo.LockSettingsVO;
@ -49,7 +48,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function handleKeyDown(event:KeyboardEvent):void {
if (event.charCode == Keyboard.ESCAPE) {
this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
onCancelClicked();
}
}

View File

@ -22,6 +22,7 @@ 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/"
implements="org.bigbluebutton.common.IKeyboardClose"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
horizontalAlign="center"

View File

@ -153,6 +153,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.users.model.UsersOptions;
import org.bigbluebutton.modules.users.views.BreakoutRoomSettings;
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
import org.bigbluebutton.util.browser.BrowserCheck;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(MainApplicationShell);
@ -492,21 +493,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function versionCheck():void {
var browserOptions : BrowserVersionsOptions = Options.getOptions(BrowserVersionsOptions) as BrowserVersionsOptions;
if (!StringUtils.isEmpty(browserOptions.chrome) && !StringUtils.isEmpty(browserOptions.firefox) && !StringUtils.isEmpty(browserOptions.flash)) {
//find browser version
var browserVersion:Array = ExternalInterface.call("determineBrowser");
//check browser version
if ((browserVersion[0].toString().toLowerCase() == "chrome" && browserVersion[1] < browserOptions.chrome) || browserVersion[0].toString().toLowerCase() == "firefox" && browserVersion[1] < browserOptions.firefox) {
if ((BrowserCheck.isChrome() && BrowserCheck.browserMajorVersion < browserOptions.chrome) || BrowserCheck.isFirefox() && BrowserCheck.browserMajorVersion < browserOptions.firefox) {
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.title"),
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.message", [browserVersion[0]+" "+browserVersion[1]]),
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.message", [BrowserCheck.browserName+" "+BrowserCheck.browserMajorVersion]),
'bbb.clientstatus.browser.message'));
}
//find flash version
var flashVersion:Object = getFlashVersion();
//check flash version
if ((flashVersion.os == 'LNX' && browserVersion[0].toString().toLowerCase() != "chrome" && flashVersion.major < 11) ||
((flashVersion.os != 'LNX' || browserVersion[0].toString().toLowerCase() == "chrome") && flashVersion.major < browserOptions.flash)) {
if ((flashVersion.os == 'LNX' && !BrowserCheck.isChrome() && flashVersion.major < 11) ||
((flashVersion.os != 'LNX' || BrowserCheck.isChrome()) && flashVersion.major < browserOptions.flash)) {
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.flash.title"),
ResourceUtil.getInstance().getString("bbb.clientstatus.flash.message", [flashVersion.major+"."+flashVersion.minor+"."+flashVersion.build]),
@ -607,7 +606,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function wrongLocaleVersion():void {
var localeWindow:OldLocaleWarnWindow = PopUpUtil.createNonModelPopUp(mdiCanvas, OldLocaleWarnWindow, false) as OldLocaleWarnWindow;
var localeWindow:OldLocaleWarnWindow = PopUpUtil.createNonModalPopUp(mdiCanvas, OldLocaleWarnWindow, false) as OldLocaleWarnWindow;
if (localeWindow) {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
@ -629,9 +628,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function handleWebRTCMediaRequestEvent(event:WebRTCMediaEvent):void {
var options:PhoneOptions = new PhoneOptions();
if (!options.showMicrophoneHint) return;
var browser:String = ExternalInterface.call("determineBrowser")[0];
var browserPermissionHelper:BrowserPermissionHelper = PopUpUtil.createModalPopUp(mdiCanvas, BrowserPermissionHelper, false) as BrowserPermissionHelper;
if (browser == "Firefox") {
if (BrowserCheck.isFirefox()) {
if (browserPermissionHelper) {
if (Capabilities.os.indexOf("Mac") >= 0){
browserPermissionHelper.currentState = "firefoxMicMacOSX";
@ -642,7 +640,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
browserPermissionHelper.x = 50;
browserPermissionHelper.y = 200;
}
} else if (browser == "Chrome") {
} else if (BrowserCheck.isChrome()) {
if (browserPermissionHelper) {
browserPermissionHelper.currentState = "chromeMic";
browserPermissionHelper.x = 50;
@ -666,14 +664,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function handleShareCameraRequestEvent(event:ShareCameraRequestEvent):void {
if (ExternalInterface.call("determineBrowser")[0] == "Chrome") {
if (BrowserCheck.isChrome()) {
// Show browserPermissionHelper component after showing the webcam window due event listeners registration order
setTimeout(showbrowserPermissionHelper, 100);
}
}
private function showbrowserPermissionHelper() : void {
var browserPermissionHelper : BrowserPermissionHelper = PopUpUtil.createNonModelPopUp(mdiCanvas, BrowserPermissionHelper, false) as BrowserPermissionHelper;
var browserPermissionHelper : BrowserPermissionHelper = PopUpUtil.createNonModalPopUp(mdiCanvas, BrowserPermissionHelper, false) as BrowserPermissionHelper;
if (browserPermissionHelper) {
browserPermissionHelper.currentState = "chromeCam";
browserPermissionHelper.x = 20;

View File

@ -75,6 +75,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.common.events.ToolbarButtonEvent;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.TimerUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.events.MeetingTimeRemainingEvent;
@ -311,14 +312,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function confirmLogout():void {
if (toolbarOptions.confirmLogout) {
var logoutWindow:LogoutWindow;
logoutWindow = LogoutWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, LogoutWindow, true));
var logoutWindow:LogoutWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, LogoutWindow, true) as LogoutWindow;
var newX:Number = this.width - logoutWindow.width - 5;
var newY:Number = btnLogout.y + btnLogout.height + 5;
PopUpManager.centerPopUp(logoutWindow);
logoutWindow.x = newX;
logoutWindow.y = newY;
} else {
@ -528,8 +526,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onSettingsButtonClick():void {
settingsPopup = BBBSettings(PopUpManager.createPopUp(this.parent, BBBSettings, true));
settingsPopup = PopUpUtil.createModalPopUp(this.parent, BBBSettings, true) as BBBSettings;
settingsPopup.pushComponents(settingsComponents);
PopUpManager.centerPopUp(settingsPopup);
}
private function refreshRole(e:ChangeMyRole):void {

View File

@ -24,8 +24,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:common="org.bigbluebutton.common.*"
width="600" height="380"
creationComplete="onCreationComplete()"
showCloseButton="false"
close="onCancelClicked()">
showCloseButton="false">
<fx:Declarations>
<mate:Listener type="{WebRTCEchoTestStartedEvent.WEBRTC_ECHO_TEST_STARTED}" method="handleWebRTCEchoTestStartedEvent" />

View File

@ -1,3 +1,21 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2017 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.modules.caption.model {
import org.bigbluebutton.core.Options;

View File

@ -33,7 +33,6 @@ package org.bigbluebutton.modules.layout.managers
import mx.events.CloseEvent;
import mx.events.EffectEvent;
import mx.events.ResizeEvent;
import mx.managers.PopUpManager;
import flexlib.mdi.containers.MDICanvas;
import flexlib.mdi.containers.MDIWindow;
@ -43,6 +42,7 @@ package org.bigbluebutton.modules.layout.managers
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.CustomMdiWindow;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.events.SwitchedLayoutEvent;
import org.bigbluebutton.core.model.LiveMeeting;
@ -130,9 +130,8 @@ package org.bigbluebutton.modules.layout.managers
public function alertSaveCurrentLayoutFile(e:CloseEvent):void {
// Check to see if the YES button was pressed.
if (e.detail==Alert.YES) {
var layoutNameWindow:CustomLayoutNameWindow = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true) as CustomLayoutNameWindow;
var layoutNameWindow:CustomLayoutNameWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true) as CustomLayoutNameWindow;
layoutNameWindow.savingForFileDownload = true;
PopUpManager.centerPopUp(layoutNameWindow);
} else if (e.detail==Alert.NO){
saveLayoutsWindow();
}

View File

@ -34,9 +34,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import flash.events.Event;
import mx.core.FlexGlobals;
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -46,8 +45,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onClick(e:Event):void {
var layoutNameWindow:IFlexDisplayObject = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true);
PopUpManager.centerPopUp(layoutNameWindow);
PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true);
}
public function refreshRole(amIModerator:Boolean):void {

View File

@ -22,14 +22,15 @@ 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/"
xmlns:common="org.bigbluebutton.common.*"
implements="org.bigbluebutton.common.IKeyboardClose"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
horizontalAlign="center"
showCloseButton="true"
close="onCancelClicked()"
layout="absolute"
showCloseButton="false"
creationComplete="onCreationComplete()"
width="250"
title="{ResourceUtil.getInstance().getString('bbb.layout.window.name')}">
width="280">
<fx:Declarations>
<mate:Listener type="{LayoutNameInUseEvent.LAYOUT_NAME_IN_USE_EVENT}" method="handleLayoutNameInUse"/>
@ -41,10 +42,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.managers.PopUpManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.layout.events.LayoutEvent;
import org.bigbluebutton.modules.layout.events.LayoutNameInUseEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(CustomLayoutNameWindow);
public var savingForFileDownload:Boolean = false;
private function addButton_clickHandler():void {
@ -65,7 +70,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
savingForFileDownload = false;
}
} else {
trace("The name is already in use, waiting for overwrite command or rename");
LOGGER.debug("The name is already in use, waiting for overwrite command or rename");
}
}
@ -79,8 +84,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
]]>
</fx:Script>
<mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
<mx:TextInput id="textInput" maxChars="140" width="100%" text="{ResourceUtil.getInstance().getString('bbb.layout.combo.customName')}" enter="addButton_clickHandler()"/>
<mx:Button id="addButton" click="addButton_clickHandler()" enabled="{textInput.text.length > 0}" styleName="addLayoutButtonStyle" toolTip="{ResourceUtil.getInstance().getString('bbb.layout.addButton.toolTip')}"/>
</mx:HBox>
<mx:VBox width="100%"
height="100%"
paddingTop="5"
horizontalAlign="center">
<common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.layout.window.name')}"
styleName="titleWindowStyle"
width="180" />
<mx:TextInput id="textInput" height="26" maxChars="140" width="100%"
text="{ResourceUtil.getInstance().getString('bbb.layout.combo.customName')}"
enter="addButton_clickHandler()" />
<mx:Button id="addButton" height="30" width="100%" click="addButton_clickHandler()" enabled="{textInput.text.length > 0}" styleName="mainActionButton"
label="{ResourceUtil.getInstance().getString('bbb.layout.addButton.label')}" toolTip="{ResourceUtil.getInstance().getString('bbb.layout.addButton.toolTip')}" />
</mx:VBox>
<mx:Button id="closeButton" click="onCancelClicked()" styleName="titleWindowCloseButton"
toolTip="{ResourceUtil.getInstance().getString('bbb.layout.window.close.tooltip')}"
top="15" right="10"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.layout.window.accessibilityName')}" />
</mx:TitleWindow>

View File

@ -14,7 +14,6 @@ package org.bigbluebutton.modules.phone.managers
import org.as3commons.logging.util.jsonXify;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.api.JSAPI;
import org.bigbluebutton.main.events.ClientStatusEvent;
import org.bigbluebutton.main.model.users.AutoReconnect;
import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
@ -36,8 +35,6 @@ package org.bigbluebutton.modules.phone.managers
private static const LOGGER:ILogger = getClassLogger(WebRTCCallManager);
private const MAX_RETRIES:Number = 3;
private var browserType:String = "unknown";
private var browserVersion:int = 0;
private var dispatcher:Dispatcher = new Dispatcher();
private var echoTestDone:Boolean = false;
@ -50,11 +47,6 @@ package org.bigbluebutton.modules.phone.managers
private var reconnecting:Boolean = false;
public function WebRTCCallManager() {
var browserInfo:Array = JSAPI.getInstance().getBrowserInfo();
if (browserInfo != null) {
browserType = browserInfo[0];
browserVersion = browserInfo[1];
}
options = Options.getOptions(PhoneOptions) as PhoneOptions;
// only show the warning if the admin has enabled WebRTC

View File

@ -113,6 +113,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function joinAudio():void {
LiveMeeting.inst().me.breakoutEjectFromAudio = false;
if (phoneOptions.skipCheck || disableMyMic || defaultListenOnlyMode) {
var command:JoinVoiceConferenceCommand = new JoinVoiceConferenceCommand();

View File

@ -21,15 +21,17 @@ 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"
xmlns:common="org.bigbluebutton.common.*"
width="350" layout="vertical"
close="onCloseClicked()"
show="{focusManager.setFocus(choiceFirst)}" xmlns:common="org.bigbluebutton.common.*">
implements="org.bigbluebutton.common.IKeyboardClose"
show="focusManager.setFocus(choiceFirst)">
<fx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.lang.ArrayUtils;
import org.as3commons.lang.StringUtils;
import org.bigbluebutton.common.IKeyboardClose;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.modules.polling.events.StartCustomPollEvent;
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;

View File

@ -24,9 +24,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
implements="org.bigbluebutton.common.IKeyboardClose"
layout="absolute"
width="580"
height="410"
creationComplete="creationCompleteHandler(event)"
close="onCancelClicked()"
initialize="initData();" >
@ -37,6 +39,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import org.bigbluebutton.modules.present.events.DownloadEvent;
import org.bigbluebutton.modules.present.model.PresentationModel;
@ -45,6 +48,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
[Bindable]
private var downloadablePresentations:ArrayCollection;
protected function creationCompleteHandler(event:FlexEvent):void {
closeButton.setFocus()
}
override public function move(x:Number, y:Number):void {
return;
}
@ -56,6 +63,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function onCancelClicked():void {
globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW));
}
]]>
</fx:Script>

View File

@ -36,7 +36,7 @@ package org.bigbluebutton.modules.screenshare.managers {
import org.bigbluebutton.modules.screenshare.model.ScreenshareModel;
import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
import org.bigbluebutton.modules.screenshare.services.ScreenshareService;
import org.bigbluebutton.modules.screenshare.utils.BrowserCheck;
import org.bigbluebutton.util.browser.BrowserCheck;
public class ScreenshareManager {
private static const LOGGER:ILogger = getClassLogger(ScreenshareManager);

View File

@ -1,51 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2016 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.modules.screenshare.utils
{
import flash.external.ExternalInterface;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
public class BrowserCheck {
private static const LOGGER:ILogger = getClassLogger(BrowserCheck);
public static function isWebRTCSupported():Boolean {
/*LOGGER.debug("isWebRTCSupported - ExternalInterface.available=[{0}], isWebRTCAvailable=[{1}]", [ExternalInterface.available, ExternalInterface.call("isWebRTCAvailable")]);*/
return (ExternalInterface.available && ExternalInterface.call("isWebRTCAvailable"));
}
public static function isChrome():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return browser[0] == "Chrome";
}
public static function isFirefox():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return browser[0] == "Firefox";
}
public static function isHttps():Boolean {
var url:String = ExternalInterface.call("window.location.href.toString");
var httpsPattern:RegExp = /^https/;
return httpsPattern.test(url);
}
}
}

View File

@ -26,6 +26,7 @@ package org.bigbluebutton.modules.screenshare.utils
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
import org.bigbluebutton.util.browser.BrowserCheck;
public class WebRTCScreenshareUtility {
private static const LOGGER:ILogger = getClassLogger(WebRTCScreenshareUtility);

View File

@ -128,8 +128,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
os = "";
}
browser = ExternalInterface.call("determineBrowser")[0];
windowControls.maximizeRestoreBtn.enabled = false;
titleBarOverlay.tabIndex = dsOptions.baseTabIndex;
@ -343,23 +341,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
captureWidth = capWidth;
captureHeight = capHeight;
var vidW:Number = captureWidth;
var vidH:Number = captureHeight;
video = new Video(captureWidth, captureHeight);
// for some reason videoHolder's height is always '0' even when set to 100% so we have to do it manually
videoWrapper.height = this.height - controlBar.height - this.titleBar.height - pauseBtn.height - publishView.getStyle('paddingTop') - publishView.getStyle('paddingBottom') - 10;
videoWrapper.width = this.width - publishView.getStyle('paddingLeft') - publishView.getStyle('paddingRight') - 10;
vidW = videoWrapper.width;
vidH = videoWrapper.width * captureHeight / captureWidth;
if (vidH > videoWrapper.height) {
vidH = videoWrapper.height;
vidW = videoWrapper.height * captureWidth / captureHeight;
video.width=this.width - publishView.getStyle('paddingLeft') - publishView.getStyle('paddingRight') - 10;
video.scaleY=video.scaleX;
if(video.height>this.height - controlBar.height - this.titleBar.height - publishView.getStyle('paddingTop') - publishView.getStyle('paddingBottom') - 10){
video.height=this.height - controlBar.height - this.titleBar.height - publishView.getStyle('paddingTop') - publishView.getStyle('paddingBottom') - 10;
video.scaleX=video.scaleY;
}
videoWrapper.width = video.width;
videoWrapper.height = video.height;
LOGGER.debug("deskshare preview[" + captureWidth + "," + captureHeight + "][" + vidW + "," + vidH + "]");
video = new Video(vidW, vidH);
LOGGER.debug("deskshare preview[" + captureWidth + "," + captureHeight + "][" + video.width + "," + video.height + "]");
videoWrapper.addChild(video);
video.x = videoWrapper.width/2 - video.width/2;
@ -377,8 +371,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
pauseBox.visible = pauseBox.includeInLayout = false;
videoWrapper.visible = videoWrapper.includeInLayout = true;
pauseBox.width = vidW;
pauseBox.height = vidH;
pauseBox.width = videoWrapper.width;
pauseBox.height = videoWrapper.height;
}
public function onMetaData(info:Object):void{
@ -586,20 +581,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</mx:VBox>
<mx:VBox id="previewBox" width="100%" height="100%" visible="false" horizontalAlign="center" >
<mx:Box id="videoHolder" width="100%" height="90%" horizontalAlign="center">
<mx:UIComponent id="videoWrapper" width="100%" height="100%" />
<mx:UIComponent id="videoWrapper" width="100%" height="100%" verticalCenter="0" horizontalCenter="0"/>
<mx:VBox id="pauseBox" visible="false" includeInLayout="false" styleName="desksharePublishPauseBox" >
<mx:Text width="100%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pauseMessage.label')}" />
</mx:VBox>
</mx:Box>
<mx:Button id="pauseBtn"
click="pauseSharing()"
toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.tooltip')}"
label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.label')}" />
<mx:Button id="restartBtn"
visible="false" includeInLayout="false"
click="pauseSharing()"
toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.tooltip')}"
label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.label')}" />
</mx:VBox>
<mx:VBox id="errorBox" width="100%" height="100%" visible="false" includeInLayout="false" horizontalAlign="center" verticalAlign="middle">
<mx:Text id="startFailedLbl" width="70%" visible="false" includeInLayout="false" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.startFailed.label')}"/>
@ -619,6 +605,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:ComboBox id="shareTypeCombo" dataProvider="{shareTypeProvider}" />
</mx:HBox>
<mx:Spacer width="80%" />
<mx:Button id="pauseBtn" visible="false" includeInLayout="false" click="pauseSharing()" toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.tooltip')}" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.label')}" />
<mx:Button id="restartBtn" visible="false" includeInLayout="false" click="pauseSharing()" toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.tooltip')}" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.label')}" />
<mx:Button id="startBtn" styleName="mainActionButton" click="onStartButtonClick()" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.startButton.label')}" />
<mx:Button id="cancelBtn" click="closeWindow()" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.cancelButton.label')}" />
<mx:Button id="stopBtn" styleName="mainActionButton" visible="false" includeInLayout="false" click="close()" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.stopButton.label')}" />

View File

@ -27,6 +27,7 @@
width="100%"
height="400"
initialize="init()"
layout="absolute"
creationComplete="onCreationComplete()"
implements="org.bigbluebutton.common.IBbbModuleWindow"
xmlns:mate="http://mate.asfusion.com/"
@ -42,6 +43,7 @@
<fx:Script>
<![CDATA[
import mx.core.ScrollPolicy;
import mx.core.UIComponent;
import flexlib.mdi.events.MDIWindowEvent;
@ -66,9 +68,6 @@
private static const LOG:String = "SC::ScreenshareViewWIndow - ";
private static const LOGGER:ILogger = getClassLogger(ScreenshareViewWindow);
private var screenHeight:Number = Capabilities.screenResolutionY;
private var screenWidth:Number = Capabilities.screenResolutionX;
private var streamAvailable:Boolean = false;
private var video:Video;
@ -79,7 +78,7 @@
private var videoWidth:Number = 1;
private static const VIDEO_WIDTH_PADDING:int = 7;
private static const VIDEO_HEIGHT_PADDING:int = 65;
private static const VIDEO_HEIGHT_PADDING:int = 40;
// The following code block is to deal with a bug in FLexLib
// with MDI windows not responding well to being maximized
@ -90,19 +89,17 @@
private var isMaximized:Boolean = false;
private var connection:Connection;
[Bindable] private var baseIndex:int;
[Bindable] private var dsOptions:ScreenshareOptions;
private function init():void{
dsOptions = Options.getOptions(ScreenshareOptions) as ScreenshareOptions;
baseIndex = dsOptions.baseTabIndex;
}
private function onCreationComplete():void{
viewScreenshareStream();
videoHolder.addChild(video);
this.addChild(videoHolder);
videoCanvas.addChildAt(videoHolder, 0);
videoHolder.percentWidth = 100;
videoHolder.percentHeight = 100;
addEventListener(MDIWindowEvent.RESIZE_END, onResizeEndEvent);
@ -111,11 +108,6 @@
resourcesChanged();
titleBarOverlay.tabIndex = baseIndex;
minimizeBtn.tabIndex = baseIndex+1;
maximizeRestoreBtn.tabIndex = baseIndex+2;
closeBtn.tabIndex = baseIndex+3;
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.width = videoWidth;
@ -186,19 +178,6 @@
LOGGER.info(JSON.stringify(logData));
}
protected function updateButtonsPosition():void {
if (this.width < bottomBar.width) {
bottomBar.visible = false;
}
if (bottomBar.visible == false) {
bottomBar.y = bottomBar.x = 0;
} else {
bottomBar.y = (this.height - bottomBar.height) / 2;
bottomBar.x = (this.width - bottomBar.width) / 2;
}
}
public function stopViewing():void {
ns.close();
closeWindow();
@ -239,7 +218,7 @@
}
/**
* resizes the desktop sharing video to fit to this window
* Resizes the desktop sharing video to fit to this window
*/
private function fitToWindow():void {
if (!streamAvailable)
@ -253,15 +232,23 @@
if (!btnActualSize.selected) {
fitVideoToWindow();
}
}
videoHolder.verticalCenter = 0;
videoHolder.horizontalCenter = 0;
}
private function fitVideoToWindow():void {
if (this.width < this.height) {
fitToWidthAndAdjustHeightToMaintainAspectRatio();
} else {
fitToHeightAndAdjustWidthToMaintainAspectRatio();
video.width=this.width - VIDEO_WIDTH_PADDING;
video.scaleY=video.scaleX;
if(video.height>this.height - VIDEO_HEIGHT_PADDING){
video.height=this.height - VIDEO_HEIGHT_PADDING;
video.scaleX=video.scaleY;
}
videoHolder.width = video.width;
videoHolder.height = video.height;
videoCanvas.verticalScrollPolicy = ScrollPolicy.OFF;
videoCanvas.horizontalScrollPolicy = ScrollPolicy.OFF;
}
private function fitWindowToVideo():void {
@ -269,33 +256,12 @@
videoHolder.width = videoWidth;
video.height = videoHeight;
videoHolder.height = videoHeight;
this.height = videoHeight + VIDEO_HEIGHT_PADDING;
this.width = videoWidth + VIDEO_WIDTH_PADDING;
}
private function videoIsSmallerThanWindow():Boolean {
return (videoHeight < this.height) && (videoWidth < this.width);
}
private function fitToWidthAndAdjustHeightToMaintainAspectRatio():void {
video.width = this.width - VIDEO_WIDTH_PADDING;
videoHolder.width = video.width;
// Maintain aspect-ratio
video.height = (videoHeight * video.width) / videoWidth;
videoHolder.height = video.height;
this.height = video.height + VIDEO_HEIGHT_PADDING;
}
private function fitToHeightAndAdjustWidthToMaintainAspectRatio():void {
video.height = this.height - VIDEO_HEIGHT_PADDING;
videoHolder.height = video.height;
// Maintain aspect-ratio
video.width = (videoWidth * video.height) / videoHeight;
videoHolder.width = video.width;
this.width = video.width + VIDEO_WIDTH_PADDING;
}
/**
* resizes the desktop sharing video to actual video resolution
*/
@ -308,6 +274,9 @@
video.height = videoHeight;
videoHolder.height = videoHeight;
}
videoCanvas.verticalScrollPolicy = ScrollPolicy.AUTO;
videoCanvas.horizontalScrollPolicy = ScrollPolicy.AUTO;
}
private function determineHowToDisplayVideo():void {
@ -354,17 +323,20 @@
]]>
</fx:Script>
<mx:HBox id="bottomBar" visible="true" height="30" horizontalAlign="center" paddingTop="0" paddingBottom="0" width="100%">
<fx:Declarations>
<common:TabIndexer id="tabIndexer" startIndex="{dsOptions.baseTabIndex + 1}"
tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, btnActualSize]}"/>
</fx:Declarations>
<mx:Canvas id="videoCanvas" width="100%" height="100%" />
<mx:Button id="btnActualSize"
paddingTop="0"
paddingBottom="0"
styleName="deskshareControlButtonStyle"
toggle="true"
horizontalCenter="0"
top="{VIDEO_HEIGHT_PADDING}"
click="determineHowToDisplayVideo()"
mouseOut="btnActualSize.alpha = 0"
mouseOver="btnActualSize.alpha = 100"
selected="false"
height="90%"
label="{ btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize') }"
toolTip="{ btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize') }"
tabIndex="{ baseIndex + 4 }" />
</mx:HBox>
toolTip="{ btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize') }"/>
</common:CustomMdiWindow>

View File

@ -23,14 +23,14 @@ 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/"
implements="org.bigbluebutton.common.IKeyboardClose"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
horizontalAlign="center"
close="onCancelClicked()"
layout="absolute"
creationComplete="onCreationComplete()"
keyUp="keyUpHandler(event)"
width="240" xmlns:common="org.bigbluebutton.common.*">
width="280" xmlns:common="org.bigbluebutton.common.*">
<fx:Script>
<![CDATA[
@ -38,6 +38,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.managers.PopUpManager;
import org.bigbluebutton.common.IKeyboardClose;
import org.bigbluebutton.core.model.LiveMeeting;
import org.bigbluebutton.modules.sharednotes.events.SharedNotesEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;

View File

@ -50,11 +50,9 @@
import mx.controls.Alert;
import mx.controls.Menu;
import mx.core.FlexGlobals;
import mx.core.IFlexDisplayObject;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.events.MenuEvent;
import mx.managers.PopUpManager;
import flashx.textLayout.formats.Direction;
@ -66,6 +64,7 @@
import org.bigbluebutton.common.Role;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.Options;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.model.LiveMeeting;
import org.bigbluebutton.main.events.ShortcutEvent;
@ -479,8 +478,7 @@
}
protected function newNoteHandler():void {
var noteNameWindow:IFlexDisplayObject = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, SharedNotesNameWindow, true);
PopUpManager.centerPopUp(noteNameWindow);
PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, SharedNotesNameWindow, true);
}
protected function btnUndo_clickHandler(event:MouseEvent = null):void {

View File

@ -54,6 +54,7 @@ package org.bigbluebutton.modules.users.services
import org.bigbluebutton.main.model.users.events.StreamStoppedEvent;
import org.bigbluebutton.main.model.users.events.UserAddedToPresenterGroupEvent;
import org.bigbluebutton.main.model.users.events.UserRemovedFromPresenterGroupEvent;
import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.users.events.MeetingMutedEvent;
@ -841,6 +842,15 @@ package org.bigbluebutton.modules.users.services
var body: Object = msg.body as Object;
var breakoutId: String = body.breakoutId as String;
// Display audio join window
if (LiveMeeting.inst().me.breakoutEjectFromAudio &&
LiveMeeting.inst().breakoutRooms.getBreakoutRoom(breakoutId).hasUserWithId(LiveMeeting.inst().me.id) &&
!LiveMeeting.inst().me.inVoiceConf
) {
LiveMeeting.inst().me.breakoutEjectFromAudio = false;
dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.SHOW_AUDIO_SELECTION));
}
switchUserFromBreakoutToMainVoiceConf(breakoutId);
var breakoutRoom: BreakoutRoom = LiveMeeting.inst().breakoutRooms.getBreakoutRoom(breakoutId);
LiveMeeting.inst().breakoutRooms.removeBreakoutRoom(breakoutId);

View File

@ -25,8 +25,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
implements="org.bigbluebutton.common.IKeyboardClose"
show="this.setFocus()"
width="630"
close="onCloseClicked()"
visible="false"
showCloseButton="false">

View File

@ -23,6 +23,8 @@ 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"
implements="org.bigbluebutton.common.IKeyboardClose"
show="this.setFocus()"
close="onCloseClick()"
layout="absolute"
width="600" xmlns:common="org.bigbluebutton.common.*">
@ -33,6 +35,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import flash.net.navigateToURL;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.model.LiveMeeting;
import org.bigbluebutton.modules.phone.events.LeaveVoiceConferenceCommand;
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -47,6 +50,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
protected function joinButtonClickHandler(event:MouseEvent):void {
if (LiveMeeting.inst().me.inVoiceConf) {
LiveMeeting.inst().me.breakoutEjectFromAudio = true;
} else {
LiveMeeting.inst().me.breakoutEjectFromAudio = false;
}
dispatcher.dispatchEvent(new LeaveVoiceConferenceCommand());
dispatcher.dispatchEvent(new StopBroadcastEvent());
navigateToURL(new URLRequest(this.joinUrl), "_blank");

View File

@ -387,7 +387,7 @@ $Id: $
}
private function openEmojiStatusMenu():void {
var moodMenu:MoodMenu = PopUpUtil.createNonModelPopUp(DisplayObject(FlexGlobals.topLevelApplication), MoodMenu, false) as MoodMenu;
var moodMenu:MoodMenu = PopUpUtil.createNonModalPopUp(DisplayObject(FlexGlobals.topLevelApplication), MoodMenu, false) as MoodMenu;
moodMenu.btn = emojiStatusBtn;
moodMenu.show();
}

View File

@ -18,7 +18,7 @@
*/
package org.bigbluebutton.modules.videoconf.model {
import org.bigbluebutton.core.Options;
import org.bigbluebutton.main.api.JSAPI;
import org.bigbluebutton.util.browser.BrowserCheck;
public class VideoConfOptions extends Options {
public var uri:String = "rtmp://localhost/video";
@ -58,10 +58,8 @@ package org.bigbluebutton.modules.videoconf.model {
}
override protected function handleExtraData():void {
var browserInfo:Array = JSAPI.getInstance().getBrowserInfo();
// If we are using Puffin browser
if (browserInfo[0] == "Puffin" && String(browserInfo[2]).substr(0, 3) < "4.6") {
if (BrowserCheck.isPuffinBelow46()) {
showButton = false;
}
}

View File

@ -44,6 +44,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.controls.Alert;
import mx.controls.Menu;
import mx.events.MenuEvent;
import mx.styles.IStyleManager2;
@ -60,8 +61,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.main.views.MainToolbar;
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
import org.bigbluebutton.modules.videoconf.events.StopShareCameraRequestEvent;
import org.bigbluebutton.util.browser.BrowserCheck;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(ToolbarPopupButton);
public const OFF_STATE:Number = 0;
@ -177,6 +183,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function openPublishWindow():void{
if (!BrowserCheck.isHttps() && ((BrowserCheck.isChrome() && BrowserCheck.browserMajorVersion >= "60") || (BrowserCheck.isOpera() && BrowserCheck.browserMajorVersion >= "47"))) {
Alert.show(ResourceUtil.getInstance().getString("bbb.video.message.browserhttp", [BrowserCheck.browserName]));
return;
}
this.enabled = false;
if(_currentState == ON_STATE) {
LOGGER.debug("[ToolbarPopupButton:openPublishWindow] Close window");

View File

@ -4,6 +4,8 @@ package org.bigbluebutton.modules.videoconf.views
import flash.events.Event;
import flash.net.URLRequest;
import mx.core.UIComponent;
public class UserAvatar extends UserGraphic {
private var _imageLoader:Loader = null;
@ -18,14 +20,17 @@ package org.bigbluebutton.modules.videoconf.views
_completed = false;
_imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadingComplete);
addChild(_imageLoader);
var request:URLRequest = new URLRequest(avatarUrl);
_imageLoader.load(request);
}
private function onLoadingComplete(event:Event):void {
_completed = true;
addChild(_imageLoader);
setOriginalDimensions(_imageLoader.width, _imageLoader.height);
if (parent && parent is UIComponent)
UIComponent(parent).invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {

View File

@ -62,12 +62,12 @@ package org.bigbluebutton.modules.videoconf.views
object_height = unscaledHeight;
object_width = Math.ceil(unscaledHeight * aspectRatio);
object_y = BORDER_THICKNESS;
object_x = Math.floor((unscaledWidth - object.width) / 2);
object_x = Math.floor((unscaledWidth - object_width) / 2);
} else {
object_width = unscaledWidth;
object_height = Math.ceil(unscaledWidth / aspectRatio);
object_x = BORDER_THICKNESS;
object_y = Math.floor((unscaledHeight - object.height) / 2);
object_y = Math.floor((unscaledHeight - object_height) / 2);
}
object.x = object_x;

View File

@ -76,6 +76,7 @@ package org.bigbluebutton.modules.whiteboard.views {
whiteboardToolbar.whiteboardAccessModified(wbModel.multiUser);
this.clipContent = true;
this.mouseEnabled = false;
//create the annotation display container
this.addChild(graphicObjectHolder);
@ -119,12 +120,14 @@ package org.bigbluebutton.modules.whiteboard.views {
addEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
mouseEnabled = true;
}
private function unregisterForMouseEvents():void {
removeEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
mouseEnabled = false;
}
private function doMouseUp(event:MouseEvent):void {

View File

@ -0,0 +1,95 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2016 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.util.browser {
import flash.external.ExternalInterface;
import org.as3commons.lang.StringUtils;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
public class BrowserCheck {
private static const LOGGER:ILogger = getClassLogger(BrowserCheck);
private static var _browserName:String;
private static var _majorVersion:String;
private static var _fullVersion:String;
// The function below is called in $cinit, while the class is used for the first time.
getBrowserInfo();
public static function isWebRTCSupported():Boolean {
/*LOGGER.debug("isWebRTCSupported - ExternalInterface.available=[{0}], isWebRTCAvailable=[{1}]", [ExternalInterface.available, ExternalInterface.call("isWebRTCAvailable")]);*/
return (ExternalInterface.available && ExternalInterface.call("isWebRTCAvailable"));
}
public static function get browserName():String {
return _browserName;
}
public static function get browserMajorVersion():String {
return _majorVersion;
}
public static function get browserFullVersion():String {
return _fullVersion;
}
public static function isChrome():Boolean {
return _browserName.toLowerCase() == "chrome";
}
public static function isOpera():Boolean {
return _browserName.toLowerCase() == "opera";
}
public static function isFirefox():Boolean {
return _browserName.toLowerCase() == "firefox";
}
public static function isPuffinBelow46():Boolean {
return _browserName.toLowerCase() == "puffin" && String(_fullVersion).substr(0, 3) < "4.6";
}
public static function isPuffin46AndAbove():Boolean {
return browserName.toLowerCase() == "puffin" && String(_fullVersion).substr(0, 3) >= "4.6";
}
private static function getBrowserInfo():void {
if (ExternalInterface.available && StringUtils.isEmpty(browserName)) {
var browserInfo:Array = ExternalInterface.call("determineBrowser");
_browserName = browserInfo[0];
_majorVersion = String(browserInfo[1]);
_fullVersion = String(browserInfo[2]);
} else {
_browserName = "unknown";
_majorVersion = "0";
_fullVersion = "0";
}
}
public static function isHttps():Boolean {
var url:String = ExternalInterface.call("window.location.href.toString");
var httpsPattern:RegExp = /^https/;
return httpsPattern.test(url);
}
}
}

View File

@ -357,15 +357,15 @@ export default function addAnnotation(meetingId, whiteboardId, userId, annotatio
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Adding annotation2x to collection: ${err}`);
return Logger.error(`Adding annotation to collection: ${err}`);
}
const { insertedId } = numChanged;
if (insertedId) {
return Logger.info(`Added annotation2x id=${annotation.id} whiteboard=${whiteboardId}`);
return Logger.info(`Added annotation id=${annotation.id} whiteboard=${whiteboardId}`);
}
return Logger.info(`Upserted annotation2x id=${annotation.id} whiteboard=${whiteboardId}`);
return Logger.info(`Upserted annotation id=${annotation.id} whiteboard=${whiteboardId}`);
};
return Annotations.upsert(query.selector, query.modifier, cb);

View File

@ -18,7 +18,7 @@ export default function clearAnnotations(meetingId, whiteboardId, userId) {
const cb = (err) => {
if (err) {
return Logger.error(`Removing Shapes2x from collection: ${err}`);
return Logger.error(`Removing Annotations from collection: ${err}`);
}
if (!meetingId) {
@ -26,10 +26,10 @@ export default function clearAnnotations(meetingId, whiteboardId, userId) {
}
if (userId) {
return Logger.info(`Removed Shapes2x for userId=${userId} where whiteboard=${whiteboardId}`);
return Logger.info(`Removed Annotations for userId=${userId} where whiteboard=${whiteboardId}`);
}
return Logger.info(`Removed Shapes2x where whiteboard=${whiteboardId}`);
return Logger.info(`Removed Annotations where whiteboard=${whiteboardId}`);
};
return Annotations.remove(selector, cb);

View File

@ -11,7 +11,7 @@ function annotations(credentials) {
check(requesterUserId, String);
check(requesterToken, String);
Logger.info(`Publishing Annotations2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
Logger.info(`Publishing Annotations for ${meetingId} ${requesterUserId} ${requesterToken}`);
return Annotations.find({ meetingId });
}

View File

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
const Breakouts = new Mongo.Collection('breakouts2x');
const Breakouts = new Mongo.Collection('breakouts');
if (Meteor.isServer) {
// types of queries for the breakouts:

View File

@ -9,7 +9,7 @@ function breakouts(credentials) {
requesterUserId,
} = credentials;
Logger.info(`Publishing Breakouts2x for ${meetingId} ${requesterUserId}`);
Logger.info(`Publishing Breakouts for ${meetingId} ${requesterUserId}`);
return Breakouts.find({
$or: [
@ -29,4 +29,4 @@ function publish(...args) {
return mapToAcl('subscriptions.breakouts', boundBreakouts)(args);
}
Meteor.publish('breakouts2x', publish);
Meteor.publish('breakouts', publish);

View File

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
const Captions = new Mongo.Collection('captions2x');
const Captions = new Mongo.Collection('captions');
if (Meteor.isServer) {
// types of queries for the captions:

View File

@ -37,15 +37,15 @@ export default function addCaption(meetingId, locale, captionHistory, id = false
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Adding caption2x to collection: ${err}`);
return Logger.error(`Adding caption to collection: ${err}`);
}
const { insertedId } = numChanged;
if (insertedId) {
return Logger.verbose(`Added caption2x locale=${locale} meeting=${meetingId}`);
return Logger.verbose(`Added caption locale=${locale} meeting=${meetingId}`);
}
return Logger.verbose(`Upserted caption2x locale=${locale} meeting=${meetingId}`);
return Logger.verbose(`Upserted caption locale=${locale} meeting=${meetingId}`);
};
return Captions.upsert(selector, modifier, cb);

View File

@ -3,8 +3,8 @@ import Logger from '/imports/startup/server/logger';
export default function clearCaptions(meetingId) {
if (meetingId) {
return Captions.remove({ meetingId }, Logger.info(`Cleared Captions2x (${meetingId})`));
return Captions.remove({ meetingId }, Logger.info(`Cleared Captions (${meetingId})`));
}
return Captions.remove({}, Logger.info('Cleared Captions2x (all)'));
return Captions.remove({}, Logger.info('Cleared Captions (all)'));
}

View File

@ -11,7 +11,7 @@ function captions(credentials) {
check(requesterUserId, String);
check(requesterToken, String);
Logger.verbose(`Publishing Captions2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
Logger.verbose(`Publishing Captions for ${meetingId} ${requesterUserId} ${requesterToken}`);
return Captions.find({ meetingId });
}
@ -21,4 +21,4 @@ function publish(...args) {
return mapToAcl('subscriptions.captions', boundCaptions)(args);
}
Meteor.publish('captions2x', publish);
Meteor.publish('captions', publish);

View File

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
const Chat = new Mongo.Collection('chat2x');
const Chat = new Mongo.Collection('chat');
if (Meteor.isServer) {
// types of queries for the chat:

View File

@ -37,4 +37,4 @@ function publish(...args) {
return mapToAcl('subscriptions.chat', boundChat)(args);
}
Meteor.publish('chat2x', publish);
Meteor.publish('chat', publish);

View File

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
const Cursor = new Mongo.Collection('cursor2x');
const Cursor = new Mongo.Collection('cursor');
if (Meteor.isServer) {
// types of queries for the cursor:

View File

@ -12,7 +12,7 @@ function cursor(credentials) {
check(requesterUserId, String);
check(requesterToken, String);
Logger.debug(`Publishing Cursor2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
Logger.debug(`Publishing Cursor for ${meetingId} ${requesterUserId} ${requesterToken}`);
return Cursor.find({ meetingId });
}
@ -22,5 +22,5 @@ function publish(...args) {
return mapToAcl('subscriptions.cursor', boundCursor)(args);
}
Meteor.publish('cursor2x', publish);
Meteor.publish('cursor', publish);

View File

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
const Meetings = new Mongo.Collection('meetings2x');
const Meetings = new Mongo.Collection('meetings');
if (Meteor.isServer) {
// types of queries for the meetings:

View File

@ -79,11 +79,11 @@ export default function addMeeting(meeting) {
const { insertedId } = numChanged;
if (insertedId) {
Logger.info(`Added meeting2x id=${meetingId}`);
Logger.info(`Added meeting id=${meetingId}`);
}
if (numChanged) {
Logger.info(`Upserted meeting2x id=${meetingId}`);
Logger.info(`Upserted meeting id=${meetingId}`);
}
};

View File

@ -11,7 +11,7 @@ function meetings(credentials) {
check(requesterUserId, String);
check(requesterToken, String);
Logger.info(`Publishing meeting2x =${meetingId} ${requesterUserId} ${requesterToken}`);
Logger.info(`Publishing meeting =${meetingId} ${requesterUserId} ${requesterToken}`);
return Meetings.find({
meetingId,
@ -23,5 +23,5 @@ function publish(...args) {
return mapToAcl('subscriptions.meetings', boundMeetings)(args);
}
Meteor.publish('meetings2x', publish);
Meteor.publish('meetings', publish);

View File

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
const Polls = new Mongo.Collection('polls2x');
const Polls = new Mongo.Collection('polls');
if (Meteor.isServer) {
// We can have just one active poll per meeting

Some files were not shown because too many files have changed in this diff Show More