Merge branch '090-guest-role' into HEAD

Conflicts:
	bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/meeting/messaging/redis/MeetingMessageHandler.java
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/CollectorActor.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/MeetingActor.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/ValueObjects.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
	bigbluebutton-client/locale/en_US/bbbResources.properties
	bigbluebutton-client/locale/pt_BR/bbbResources.properties
	bigbluebutton-client/src/org/bigbluebutton/main/views/LoadingBar.mxml
	bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
This commit is contained in:
Felipe Cecagno 2015-01-25 18:36:30 -02:00
commit f6d6e4e40c
80 changed files with 4003 additions and 1648 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,8 @@ with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
Author: Fred Dixon <ffdixon@bigbluebutton.org>
-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
@ -197,6 +198,16 @@ if (request.getParameterMap().isEmpty()) {
<td>
<input type="password" required name="password" /></td>
</tr>
<tr>
<td>
&nbsp;</td>
<td style="text-align: right; ">
Guest:</td>
<td>
&nbsp;</td>
<td>
<input type="checkbox" name="guest" value="guest" /></td>
</tr>
<tr>
<td>
&nbsp;</td>
@ -272,8 +283,12 @@ Error: createMeeting() failed
//
// We've got a valid meeting_ID and passoword -- let's join!
//
String joinURL = getJoinMeetingURL(username, meeting_ID, password, null);
String joinURL;
if(request.getParameter("guest") != null)
joinURL = getJoinMeetingURL(username, meeting_ID, password, null, true);
else
joinURL = getJoinMeetingURL(username, meeting_ID, password, null);
%>
<script language="javascript" type="text/javascript">

View File

@ -132,13 +132,18 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
lsMap = new HashMap<String, Boolean>();
}
}
Boolean guest = false;
if (params.length >= 10 && ((Boolean) params[10])) {
guest = true;
}
if (record == true) {
recorderApplication.createRecordSession(room);
}
BigBlueButtonSession bbbSession = new BigBlueButtonSession(room, internalUserID, username, role,
voiceBridge, record, externalUserID, muted);
voiceBridge, record, externalUserID, muted, guest);
connection.setAttribute(Constants.SESSION, bbbSession);
connection.setAttribute("INTERNAL_USER_ID", internalUserID);

View File

@ -28,10 +28,11 @@ public class BigBlueButtonSession {
private final Boolean record;
private final String externalUserID;
private final Boolean startAsMuted;
private final Boolean guest;
public BigBlueButtonSession(String room, String internalUserID, String username,
String role, String voiceBridge, Boolean record,
String externalUserID, Boolean startAsMuted){
String externalUserID, Boolean startAsMuted, Boolean guest){
this.internalUserID = internalUserID;
this.username = username;
this.role = role;
@ -40,6 +41,7 @@ public class BigBlueButtonSession {
this.record = record;
this.externalUserID = externalUserID;
this.startAsMuted = startAsMuted;
this.guest = guest;
}
public String getUsername() {
@ -73,4 +75,8 @@ public class BigBlueButtonSession {
public Boolean getStartAsMuted() {
return startAsMuted;
}
public Boolean isGuest() {
return guest;
}
}

View File

@ -45,8 +45,8 @@ public class MeetingMessageHandler implements MessageHandler {
emm.duration, emm.autoStartRecording, emm.allowStartStopRecording);
} else if (msg instanceof RegisterUserMessage) {
RegisterUserMessage emm = (RegisterUserMessage) msg;
log.info("Received register user request. Meeting id [{}], userid=[{}], token=[{}]", emm.meetingID, emm.internalUserId, emm.authToken);
bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken);
log.info("Received register user request. Meeting id [{}], userid=[{}], token=[{}], guest=[{}]", emm.meetingID, emm.internalUserId, emm.authToken, emm.guest);
bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken, emm.guest);
} else if (msg instanceof DestroyMeetingMessage) {
DestroyMeetingMessage emm = (DestroyMeetingMessage) msg;
log.info("Received destroy meeting request. Meeting id [{}]", emm.meetingId);

View File

@ -89,4 +89,5 @@ public class Constants {
public static final String Y_PERCENT = "y_percent";
public static final String KEEP_ALIVE_ID = "keep_alive_id";
public static final String INTERNAL_USER_ID = "internal_user_id";
public static final String GUEST = "guest";
}

View File

@ -14,14 +14,16 @@ public class RegisterUserMessage implements IMessage {
public final String role;
public final String externUserID;
public final String authToken;
public final Boolean guest;
public RegisterUserMessage(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken) {
public RegisterUserMessage(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken, Boolean guest) {
this.meetingID = meetingID;
this.internalUserId = internalUserId;
this.fullname = fullname;
this.role = role;
this.externUserID = externUserID;
this.authToken = authToken;
this.guest = guest;
}
public String toJson() {
@ -33,6 +35,7 @@ public class RegisterUserMessage implements IMessage {
payload.put(Constants.ROLE, role);
payload.put(Constants.EXT_USER_ID, externUserID);
payload.put(Constants.AUTH_TOKEN, authToken);
payload.put(Constants.GUEST, guest.toString());
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(REGISTER_USER, VERSION, null);
@ -60,9 +63,10 @@ public class RegisterUserMessage implements IMessage {
String role = payload.get(Constants.ROLE).getAsString();
String externUserID = payload.get(Constants.EXT_USER_ID).getAsString();
String authToken = payload.get(Constants.AUTH_TOKEN).getAsString();
Boolean guest = payload.get(Constants.GUEST).getAsBoolean();
//use externalUserId twice - once for external, once for internal
return new RegisterUserMessage(meetingID, externUserID, fullname, role, externUserID, authToken);
return new RegisterUserMessage(meetingID, externUserID, fullname, role, externUserID, authToken, guest);
}
}
}

View File

@ -62,8 +62,8 @@ public class ParticipantsApplication {
return true;
}
public boolean registerUser(String roomName, String userid, String username, String role, String externUserID) {
bbbInGW.registerUser(roomName, userid, username, role, externUserID, userid);
public boolean registerUser(String roomName, String userid, String username, String role, String externUserID, Boolean guest) {
bbbInGW.registerUser(roomName, userid, username, role, externUserID, userid, guest);
return true;
}
@ -86,4 +86,32 @@ public class ParticipantsApplication {
public void getRecordingStatus(String meetingId, String userId) {
bbbInGW.getRecordingStatus(meetingId, userId);
}
public void askingToEnter(String meetingId, String userId) {
bbbInGW.userRequestToEnter(meetingId, userId);
}
public void getGuestPolicy(String meetingId, String requesterId) {
bbbInGW.getGuestPolicy(meetingId, requesterId);
}
public void newGuestPolicy(String meetingId, String guestPolicy) {
bbbInGW.setGuestPolicy(meetingId, guestPolicy);
}
public void askingForGuestWaiting(String meetingId, String requesterId) {
bbbInGW.getGuestsWaiting(meetingId, requesterId);
}
public void responseToGuest(String meetingId, String userId, Boolean resp) {
bbbInGW.responseToGuest(meetingId, userId, resp);
}
public void responseToAllGuests(String meetingId, Boolean resp) {
bbbInGW.responseToAllGuests(meetingId, resp);
}
public void kickGuest(String meetingId, String guestId) {
bbbInGW.kickGuest(meetingId, guestId);
}
}

View File

@ -101,14 +101,15 @@ public class ParticipantsHandler implements IApplication{
String username = bbbSession.getUsername();
String role = bbbSession.getRole();
String room = bbbSession.getRoom();
log.debug(APP + ":participantJoin - [" + room + "] [" + userid + ", " + username + ", " + role + "]");
Boolean guest = bbbSession.isGuest();
log.debug(APP + ":participantJoin - [" + room + "] [" + userid + ", " + username + ", " + role + ", " + guest + "]");
Map<String, Boolean> status = new HashMap<String, Boolean>();
status.put("raiseHand", false);
status.put("presenter", false);
status.put("hasStream", false);
participantsApplication.registerUser(room, userid, username, role, bbbSession.getExternUserID());
participantsApplication.registerUser(room, userid, username, role, bbbSession.getExternUserID(), guest);
}
}

View File

@ -104,4 +104,41 @@ public class ParticipantsService {
return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
}
public void askingToEnter() {
String userId = getBbbSession().getInternalUserID();
String roomName = Red5.getConnectionLocal().getScope().getName();
application.askingToEnter(roomName, userId);
}
public void getGuestPolicy() {
String requesterId = getBbbSession().getInternalUserID();
String roomName = Red5.getConnectionLocal().getScope().getName();
application.getGuestPolicy(roomName, requesterId);
}
public void setGuestPolicy(String guestPolicy) {
String roomName = Red5.getConnectionLocal().getScope().getName();
application.newGuestPolicy(roomName, guestPolicy);
}
public void getGuestsWaiting() {
String userId = getBbbSession().getInternalUserID();
String roomName = Red5.getConnectionLocal().getScope().getName();
application.askingForGuestWaiting(roomName, userId);
}
public void responseToAllGuests(Boolean resp) {
String roomName = Red5.getConnectionLocal().getScope().getName();
application.responseToAllGuests(roomName, resp);
}
public void responseToGuest(Map<String, Object> msg) {
String roomName = Red5.getConnectionLocal().getScope().getName();
application.responseToGuest(roomName, (String) msg.get("guestID"), (Boolean) msg.get("response"));
}
public void kickGuest(String guestId) {
String roomName = Red5.getConnectionLocal().getScope().getName();
application.kickGuest(roomName, guestId);
}
}

View File

@ -0,0 +1,19 @@
package org.bigbluebutton.conference.service.recorder.participants;
public class GuestAskToEnterRecordEvent extends AbstractParticipantRecordEvent {
public GuestAskToEnterRecordEvent() {
super();
setEvent("GuestAskToEnterEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setName(String name) {
eventMap.put("name", name);
}
}

View File

@ -0,0 +1,14 @@
package org.bigbluebutton.conference.service.recorder.participants;
public class GuestPolicyEvent extends AbstractParticipantRecordEvent {
public GuestPolicyEvent() {
super();
setEvent("GuestPolicyEvent");
}
public void setPolicy(String guestPolicy) {
eventMap.put("guestPolicy", guestPolicy);
}
}

View File

@ -0,0 +1,19 @@
package org.bigbluebutton.conference.service.recorder.participants;
public class ModeratorResponseEvent extends AbstractParticipantRecordEvent {
public ModeratorResponseEvent() {
super();
setEvent("ModeratorResponseEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setResp(Boolean resp) {
eventMap.put("resp", resp.toString());
}
}

View File

@ -0,0 +1,17 @@
package org.bigbluebutton.conference.service.recorder.participants;
public class WaitingForModeratorEvent extends AbstractParticipantRecordEvent {
public WaitingForModeratorEvent() {
super();
setEvent("WaitingForModeratorEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setArg(String arg) {
eventMap.put("userId_userName", arg);
}
}

View File

@ -29,7 +29,7 @@ public interface IBigBlueButtonInGW {
// Users
void validateAuthToken(String meetingId, String userId, String token, String correlationId);
void registerUser(String roomName, String userid, String username, String role, String externUserID, String authToken);
void registerUser(String roomName, String userid, String username, String role, String externUserID, String authToken, Boolean guest);
void userRaiseHand(String meetingId, String userId);
void lowerHand(String meetingId, String userId, String loweredBy);
void shareWebcam(String meetingId, String userId, String stream);
@ -44,7 +44,14 @@ public interface IBigBlueButtonInGW {
void getRecordingStatus(String meetingId, String userId);
void userConnectedToGlobalAudio(String voiceConf, String userid, String name);
void userDisconnectedFromGlobalAudio(String voiceConf, String userid, String name);
void userRequestToEnter(String meetingID, String userID);
void getGuestPolicy(String meetingID, String userID);
void setGuestPolicy(String meetingID, String guestPolicy);
void getGuestsWaiting(String meetingID, String requesterID);
void responseToGuest(String meetingID, String userID, Boolean response);
void responseToAllGuests(String meetingID, Boolean response);
void kickGuest(String meetingID, String guestID);
// Voice
void muteAllExceptPresenter(String meetingID, String requesterID, Boolean mute);
void muteAllUsers(String meetingID, String requesterID, Boolean mute);

View File

@ -66,9 +66,9 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway, presUtil: PreuploadedPresen
bbbGW.accept(new ValidateAuthToken(meetingId, userId, token, correlationId))
}
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String, authToken: String):Unit = {
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String, authToken: String, guest: java.lang.Boolean):Unit = {
val userRole = if (role == "MODERATOR") Role.MODERATOR else Role.VIEWER
bbbGW.accept(new RegisterUser(meetingID, userID, name, userRole, extUserID, authToken))
bbbGW.accept(new RegisterUser(meetingID, userID, name, userRole, extUserID, authToken, guest))
}
def sendLockSettings(meetingID: String, userId: String, settings: java.util.Map[String, java.lang.Boolean]) {
@ -188,7 +188,43 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway, presUtil: PreuploadedPresen
def userDisconnectedFromGlobalAudio(voiceConf: String, userid: String, name: String) {
bbbGW.accept(new UserDisconnectedFromGlobalAudio(voiceConf, voiceConf, userid, name))
}
// Guest support
def userRequestToEnter(meetingID: String, userID: String) {
bbbGW.accept(new UserRequestToEnter(meetingID, userID))
}
def getGuestPolicy(meetingID: String, requesterID: String) {
bbbGW.accept(new GetGuestPolicy(meetingID, requesterID))
}
def setGuestPolicy(meetingID: String, guestPolicy: String) {
val policy = guestPolicy.toUpperCase() match {
case "ALWAYS_ACCEPT" => GuestPolicy.ALWAYS_ACCEPT
case "ALWAYS_DENY" => GuestPolicy.ALWAYS_DENY
case "ASK_MODERATOR" => GuestPolicy.ASK_MODERATOR
//default
case undef => GuestPolicy.ASK_MODERATOR
}
bbbGW.accept(new SetGuestPolicy(meetingID, policy))
}
def getGuestsWaiting(meetingID: String, requesterID: String) {
bbbGW.accept(new GetGuestsWaiting(meetingID, requesterID))
}
def responseToGuest(meetingID: String, guestID: String, response: java.lang.Boolean) {
bbbGW.accept(new RespondToGuest(meetingID, guestID, response))
}
def responseToAllGuests(meetingID: String, response: java.lang.Boolean) {
bbbGW.accept(new RespondToAllGuests(meetingID, response))
}
def kickGuest(meetingID: String, guestID: String) {
bbbGW.accept(new KickGuest(meetingID, guestID))
}
/**************************************************************************************
* Message Interface for Presentation
**************************************************************************************/

View File

@ -98,6 +98,12 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
case msg: UndoWhiteboardRequest => handleUndoWhiteboardRequest(msg)
case msg: EnableWhiteboardRequest => handleEnableWhiteboardRequest(msg)
case msg: IsWhiteboardEnabledRequest => handleIsWhiteboardEnabledRequest(msg)
case msg: UserRequestToEnter => handleUserRequestToEnter(msg)
case msg: GetGuestPolicy => handleGetGuestPolicy(msg)
case msg: SetGuestPolicy => handleSetGuestPolicy(msg)
case msg: GetGuestsWaiting => handleGetGuestsWaiting(msg)
case msg: RespondToGuest => handleRespondToGuest(msg)
case msg: KickGuest => handleKickGuest(msg)
case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg)
//OUT MESSAGES
@ -178,6 +184,12 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
case msg: WhiteboardEnabledEvent => handleWhiteboardEnabledEvent(msg)
case msg: IsWhiteboardEnabledReply => handleIsWhiteboardEnabledReply(msg)
case msg: GuestRequestedToEnter => handleGuestRequestedToEnter(msg)
case msg: GetGuestPolicyReply => handleGetGuestPolicyReply(msg)
case msg: GuestPolicyChanged => handleGuestPolicyChanged(msg)
case msg: GetGuestsWaitingReply => handleGetGuestsWaitingReply(msg)
case msg: ResponseToGuest => handleResponseToGuest(msg)
case msg: GuestKicked => handleGuestKicked(msg)
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
case _ => // do nothing
@ -427,6 +439,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
payload.put(Constants.NAME, msg.name)
payload.put(Constants.ROLE, msg.role.toString())
payload.put(Constants.EXT_USER_ID, msg.extUserID)
payload.put(Constants.GUEST, msg.guest.toString())
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.REGISTER_USER)
@ -2204,6 +2217,180 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
val json = WhiteboardMessageToJsonConverter.isWhiteboardEnabledReplyToJson(msg)
dispatcher.dispatch(json)
}
private def handleUserRequestToEnter(msg: UserRequestToEnter) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.userID)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.USER_REQUEST_TO_ENTER)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING USER REQUEST TO ENTER *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGetGuestPolicy(msg: GetGuestPolicy) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GET_GUEST_POLICY)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GET GUEST POLICY *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleSetGuestPolicy(msg: SetGuestPolicy) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.GUEST_POLICY, msg.policy.toString())
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.SET_GUEST_POLICY)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING SET GUEST POLICY *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGetGuestsWaiting(msg: GetGuestsWaiting) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GET_GUESTS_WAITING)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GET GUESTS WAITING *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleRespondToGuest(msg: RespondToGuest) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.guestID)
payload.put(Constants.RESPONSE, msg.response.toString())
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.RESPOND_TO_GUEST)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING RESPOND TO GUEST *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleKickGuest(msg: KickGuest) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.guestID)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.KICK_GUEST)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING KICK GUEST *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGuestRequestedToEnter(msg: GuestRequestedToEnter) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.userID)
payload.put(Constants.NAME, msg.name)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GUEST_REQUESTED_TO_ENTER)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GUEST REQUESTED TO ENTER *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGetGuestPolicyReply(msg: GetGuestPolicyReply) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.GUEST_POLICY, msg.policy)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GET_GUEST_POLICY_REPLY)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GET GUEST POLICY REPLY *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGuestPolicyChanged(msg: GuestPolicyChanged) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.GUEST_POLICY, msg.policy)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GUEST_POLICY_CHANGED)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GUEST POLICY CHANGED *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGetGuestsWaitingReply(msg: GetGuestsWaitingReply) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.GUESTS_WAITING, msg.guestsWaiting)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GET_GUESTS_WAITING_REPLY)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GET GUESTS WAITING REPLY *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleResponseToGuest(msg: ResponseToGuest) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.guestID)
payload.put(Constants.RESPONSE, msg.response)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.RESPONSE_TO_GUEST)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING RESPONSE TO GUEST *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGuestKicked(msg: GuestKicked) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.guestID)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.GUEST_KICKED)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING GUEST KICKED *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleGetAllMeetingsReply(msg: GetAllMeetingsReply) {
val json = MeetingMessageToJsonConverter.getAllMeetingsReplyToJson(msg)
println("***** DISPATCHING GET ALL MEETINGS REPLY OUTMSG *****************")

View File

@ -30,6 +30,7 @@ class MeetingActor(val meetingID: String, val externalMeetingID: String, val mee
var recording = false;
var muted = false;
var meetingEnded = false
var guestPolicy = GuestPolicy.ASK_MODERATOR
def getDuration():Long = {
duration
@ -131,6 +132,13 @@ class MeetingActor(val meetingID: String, val externalMeetingID: String, val mee
case msg: SetRecordingStatus => handleSetRecordingStatus(msg)
case msg: GetRecordingStatus => handleGetRecordingStatus(msg)
case msg: VoiceRecording => handleVoiceRecording(msg)
case msg: UserRequestToEnter => handleUserRequestToEnter(msg)
case msg: GetGuestPolicy => handleGetGuestPolicy(msg)
case msg: SetGuestPolicy => handleSetGuestPolicy(msg)
case msg: GetGuestsWaiting => handleGetGuestsWaiting(msg)
case msg: RespondToGuest => handleRespondToGuest(msg)
case msg: RespondToAllGuests => handleRespondToAllGuests(msg)
case msg: KickGuest => handleKickGuest(msg)
case msg: EndMeeting => handleEndMeeting(msg)
case StopMeetingActor => exit
@ -242,6 +250,15 @@ class MeetingActor(val meetingID: String, val externalMeetingID: String, val mee
private def handleGetRecordingStatus(msg: GetRecordingStatus) {
outGW.send(new GetRecordingStatusReply(meetingID, recorded, msg.userId, recording.booleanValue()))
}
private def handleGetGuestPolicy(msg: GetGuestPolicy) {
outGW.send(new GetGuestPolicyReply(msg.meetingID, recorded, msg.requesterID, guestPolicy.toString()))
}
private def handleSetGuestPolicy(msg: SetGuestPolicy) {
guestPolicy = msg.policy
outGW.send(new GuestPolicyChanged(msg.meetingID, recorded, guestPolicy.toString()))
}
def lockLayout(lock: Boolean) {
permissions = permissions.copy(lockedLayout=lock)

View File

@ -89,4 +89,7 @@ object Constants {
val Y_PERCENT = "y_percent"
val KEEP_ALIVE_ID = "keep_alive_id"
val LISTEN_ONLY = "listen_only"
}
val GUEST = "guest"
val GUEST_POLICY = "guest_policy"
val GUESTS_WAITING = "guests_waiting"
}

View File

@ -1,6 +1,7 @@
package org.bigbluebutton.core.api
import org.bigbluebutton.core.api.Role._
import org.bigbluebutton.core.api.GuestPolicy._
import org.bigbluebutton.core.apps.poll._
import org.bigbluebutton.core.apps.whiteboard.vo.AnnotationVO
import org.bigbluebutton.core.apps.presentation.Presentation
@ -88,7 +89,8 @@ case class RegisterUser(
name: String,
role: Role,
extUserID: String,
authToken: String
authToken: String,
guest: Boolean
) extends InMessage
case class UserJoining(
@ -188,6 +190,43 @@ case class UserDisconnectedFromGlobalAudio(
name: String
) extends InMessage
// Guest support
case class UserRequestToEnter(
meetingID: String,
userID: String
) extends InMessage
case class GetGuestPolicy(
meetingID: String,
requesterID: String
) extends InMessage
case class SetGuestPolicy(
meetingID: String,
policy: GuestPolicy
) extends InMessage
case class GetGuestsWaiting(
meetingID: String,
requesterID: String
) extends InMessage
case class RespondToGuest(
meetingID: String,
guestID: String,
response: Boolean
) extends InMessage
case class RespondToAllGuests(
meetingID: String,
response: Boolean
) extends InMessage
case class KickGuest(
meetingID: String,
guestID: String
) extends InMessage
// Layout
case class GetCurrentLayoutRequest(
meetingID: String,

View File

@ -78,6 +78,13 @@ object MessageNames {
val UNDO_WHITEBOARD = "undo_whiteboard_request"
val ENABLE_WHITEBOARD = "enable_whiteboard_request"
val IS_WHITEBOARD_ENABLED = "is_whiteboard_enabled_request"
val USER_REQUEST_TO_ENTER = "user_request_to_enter"
var GET_GUEST_POLICY = "get_guest_policy"
val SET_GUEST_POLICY = "set_guest_policy"
val GET_GUESTS_WAITING = "get_guests_waiting"
val RESPOND_TO_GUEST = "respond_to_guest"
val RESPOND_TO_ALL_GUESTS = "respond_to_all_guests"
val KICK_GUEST = "kick_guest"
val GET_ALL_MEETINGS_REQUEST = "get_all_meetings_request"
// OUT MESSAGES
@ -159,5 +166,11 @@ object MessageNames {
val MEETING_DESTROYED_EVENT = "meeting_destroyed_event"
val KEEP_ALIVE_REPLY = "keep_alive_reply"
val USER_LISTEN_ONLY = "user_listening_only"
val GUEST_REQUESTED_TO_ENTER = "guest_requested_to_enter"
var GET_GUEST_POLICY_REPLY = "get_guest_policy_reply"
val GUEST_POLICY_CHANGED = "guest_policy_changed"
val GET_GUESTS_WAITING_REPLY = "get_guests_waiting_reply"
val RESPONSE_TO_GUEST = "response_to_guest"
val GUEST_KICKED = "guest_kicked"
val GET_ALL_MEETINGS_REPLY = "get_all_meetings_reply"
}

View File

@ -206,6 +206,13 @@ case class UserJoined(
user:UserVO,
version:String = Versions.V_0_0_1
) extends IOutMessage
case class JoinMeetingReply(
meetingID: String,
recorded: Boolean,
user:UserVO,
version:String = Versions.V_0_0_1
) extends IOutMessage
case class UserRaisedHand(
meetingID: String,
@ -648,6 +655,46 @@ case class IsWhiteboardEnabledReply(
version:String = Versions.V_0_0_1
) extends IOutMessage
case class GuestRequestedToEnter (
meetingID: String,
recorded: Boolean,
userID: String,
name: String
) extends IOutMessage
case class GetGuestPolicyReply(
meetingID: String,
recorded: Boolean,
requesterID: String,
policy: String
) extends IOutMessage
case class GuestPolicyChanged(
meetingID: String,
recorded: Boolean,
policy: String
) extends IOutMessage
case class GetGuestsWaitingReply(
meetingID: String,
recorded: Boolean,
requesterID: String,
guestsWaiting: String
) extends IOutMessage
case class ResponseToGuest(
meetingID: String,
recorded: Boolean,
guestID: String,
response: Boolean
) extends IOutMessage
case class GuestKicked(
meetingID: String,
recorded: Boolean,
guestID: String
) extends IOutMessage
case class GetAllMeetingsReply(
meetings: Array[MeetingInfo],
version:String = Versions.V_0_0_1

View File

@ -1,107 +1,117 @@
package org.bigbluebutton.core.api
object Role extends Enumeration {
type Role = Value
val MODERATOR = Value("MODERATOR")
val VIEWER = Value("VIEWER")
}
case class Presenter(
presenterID: String,
presenterName: String,
assignedBy: String)
case class User(
id: String,
externId: String,
name: String,
moderator: Boolean,
avatarUrl: String,
logoutUrl: String,
presenter: Boolean,
callerId: CallerId,
phoneCaller: Boolean,
handRaised: Boolean,
muted: Boolean,
talking: Boolean
)
case class CallerId(
name: String,
number: String
)
case class Permissions(
disableCam: Boolean = false,
disableMic: Boolean = false,
disablePrivChat: Boolean = false,
disablePubChat: Boolean = false,
lockedLayout:Boolean = false
)
case class RegisteredUser (
id: String,
externId: String,
name: String,
role: Role.Role,
authToken: String
)
case class Voice(
id: String,
webId: String,
callId: CallerId,
phoningIn: Boolean,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean
)
case class UserVO(
userID: String,
externUserID: String,
name: String,
role: Role.Role,
raiseHand: Boolean,
presenter: Boolean,
hasStream: Boolean,
locked: Boolean,
webcamStream: String,
phoneUser: Boolean,
voiceUser: VoiceUser,
listenOnly: Boolean,
permissions: Permissions = new Permissions())
case class VoiceUser(userId: String,
webUserId: String,
callerName: String,
callerNum: String,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean)
case class MeetingConfig(name: String,
id: MeetingID,
passwords: MeetingPasswords,
welcomeMsg: String,
logoutUrl: String,
maxUsers: Int,
record: Boolean=false,
duration: MeetingDuration,
defaultAvatarURL: String,
defaultConfigToken: String)
case class MeetingName(name: String)
case class MeetingID(internal:String, external: String)
case class VoiceConfig(telVoice: String, webVoice: String, dialNumber: String)
case class MeetingPasswords(moderatorPass: String, viewerPass: String)
case class MeetingDuration(duration: Int = 0, createdTime: Long = 0,
startTime: Long = 0, endTime: Long = 0)
case class MeetingInfo(meetingID: String, meetingName: String, recorded: Boolean, voiceBridge: String, duration: Long)
package org.bigbluebutton.core.api
object Role extends Enumeration {
type Role = Value
val MODERATOR = Value("MODERATOR")
val VIEWER = Value("VIEWER")
}
object GuestPolicy extends Enumeration {
type GuestPolicy = Value
val ALWAYS_ACCEPT = Value("ALWAYS_ACCEPT")
val ALWAYS_DENY = Value("ALWAYS_DENY")
val ASK_MODERATOR = Value("ASK_MODERATOR")
}
case class Presenter(
presenterID: String,
presenterName: String,
assignedBy: String)
case class User(
id: String,
externId: String,
name: String,
moderator: Boolean,
avatarUrl: String,
logoutUrl: String,
presenter: Boolean,
callerId: CallerId,
phoneCaller: Boolean,
handRaised: Boolean,
muted: Boolean,
talking: Boolean
)
case class CallerId(
name: String,
number: String
)
case class Permissions(
disableCam: Boolean = false,
disableMic: Boolean = false,
disablePrivChat: Boolean = false,
disablePubChat: Boolean = false,
lockedLayout:Boolean = false
)
case class RegisteredUser (
id: String,
externId: String,
name: String,
role: Role.Role,
authToken: String,
guest: Boolean
)
case class Voice(
id: String,
webId: String,
callId: CallerId,
phoningIn: Boolean,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean
)
case class UserVO(
userID: String,
externUserID: String,
name: String,
role: Role.Role,
guest: Boolean,
raiseHand: Boolean,
presenter: Boolean,
hasStream: Boolean,
locked: Boolean,
webcamStream: String,
phoneUser: Boolean,
voiceUser: VoiceUser,
listenOnly: Boolean,
permissions: Permissions = new Permissions())
case class VoiceUser(userId: String,
webUserId: String,
callerName: String,
callerNum: String,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean)
case class MeetingConfig(name: String,
id: MeetingID,
passwords: MeetingPasswords,
welcomeMsg: String,
logoutUrl: String,
maxUsers: Int,
record: Boolean=false,
duration: MeetingDuration,
defaultAvatarURL: String,
defaultConfigToken: String,
guestPolicy: GuestPolicy.GuestPolicy=GuestPolicy.ASK_MODERATOR)
case class MeetingName(name: String)
case class MeetingID(internal:String, external: String)
case class VoiceConfig(telVoice: String, webVoice: String, dialNumber: String)
case class MeetingPasswords(moderatorPass: String, viewerPass: String)
case class MeetingDuration(duration: Int = 0, createdTime: Long = 0,
startTime: Long = 0, endTime: Long = 0)
case class MeetingInfo(meetingID: String, meetingName: String, recorded: Boolean, voiceBridge: String, duration: Long)

View File

@ -1,430 +1,500 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.core.api._
import scala.collection.mutable.HashMap
import org.bigbluebutton.core.User
import java.util.ArrayList
import org.bigbluebutton.core.MeetingActor
import scala.collection.mutable.ArrayBuffer
trait UsersApp {
this : MeetingActor =>
val outGW: MessageOutGateway
val users = new UsersModel
private var regUsers = new collection.immutable.HashMap[String, RegisteredUser]
private var locked = false
private var meetingMuted = false
private var currentPresenter = new Presenter("system", "system", "system")
def hasUser(userID: String):Boolean = {
users.hasUser(userID)
}
def getUser(userID:String):Option[UserVO] = {
users.getUser(userID)
}
def getCurrentPresenter:Presenter = {
currentPresenter
}
def handleUserConnectedToGlobalAudio(msg: UserConnectedToGlobalAudio) {
val user = users.getUserWithExternalId(msg.userid)
user foreach {u =>
val vu = u.voiceUser.copy(talking=false)
val uvo = u.copy(listenOnly=true, voiceUser=vu)
users.addUser(uvo)
logger.info("UserConnectedToGlobalAudio: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserListeningOnly(meetingID, recorded, uvo.userID, uvo.listenOnly))
}
}
def handleUserDisconnectedFromGlobalAudio(msg: UserDisconnectedFromGlobalAudio) {
val user = users.getUserWithExternalId(msg.userid)
user foreach {u =>
val uvo = u.copy(listenOnly=false)
users.addUser(uvo)
logger.info("UserDisconnectedToGlobalAudio: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserListeningOnly(meetingID, recorded, uvo.userID, uvo.listenOnly))
}
}
def handleMuteAllExceptPresenterRequest(msg: MuteAllExceptPresenterRequest) {
meetingMuted = msg.mute
outGW.send(new MeetingMuted(meetingID, recorded, meetingMuted))
usersWhoAreNotPresenter foreach {u =>
outGW.send(new MuteVoiceUser(meetingID, recorded, msg.requesterID, u.userID, msg.mute))
}
}
def handleMuteMeetingRequest(msg: MuteMeetingRequest) {
meetingMuted = msg.mute
outGW.send(new MeetingMuted(meetingID, recorded, meetingMuted))
users.getUsers foreach {u =>
outGW.send(new MuteVoiceUser(meetingID, recorded, msg.requesterID, u.userID, msg.mute))
}
}
def handleValidateAuthToken(msg: ValidateAuthToken) {
// println("*************** Got ValidateAuthToken message ********************" )
regUsers.get (msg.userId) match {
case Some(u) =>
{
val replyTo = meetingID + '/' + msg.userId
//send the reply
outGW.send(new ValidateAuthTokenReply(meetingID, msg.userId, msg.token, true, msg.correlationId))
//send the list of users in the meeting
outGW.send(new GetUsersReply(meetingID, msg.userId, users.getUsers))
//send chat history
this ! (new GetChatHistoryRequest(meetingID, msg.userId, replyTo))
//join the user
handleUserJoin(new UserJoining(meetingID, msg.userId))
//send the presentation
logger.info("ValidateToken success: mid=[" + meetingID + "] uid=[" + msg.userId + "]")
this ! (new GetPresentationInfo(meetingID, msg.userId, replyTo))
}
case None => {
logger.info("ValidateToken failed: mid=[" + meetingID + "] uid=[" + msg.userId + "]")
outGW.send(new ValidateAuthTokenReply(meetingID, msg.userId, msg.token, false, msg.correlationId))
}
}
}
def handleRegisterUser(msg: RegisterUser) {
if (hasMeetingEnded) {
// Check first if the meeting has ended and the user refreshed the client to re-connect.
logger.info("Register user failed: reason=[meeting has ended] mid=[" + meetingID + "] uid=[" + msg.userID + "]")
sendMeetingHasEnded(msg.userID)
} else {
val regUser = new RegisteredUser(msg.userID, msg.extUserID, msg.name, msg.role, msg.authToken)
regUsers += msg.userID -> regUser
logger.info("Register user success: mid=[" + meetingID + "] uid=[" + msg.userID + "]")
outGW.send(new UserRegistered(meetingID, recorded, regUser))
}
}
def handleIsMeetingMutedRequest(msg: IsMeetingMutedRequest) {
outGW.send(new IsMeetingMutedReply(meetingID, recorded, msg.requesterID, meetingMuted))
}
def handleMuteUserRequest(msg: MuteUserRequest) {
// println("Received mute user request uid=[" + msg.userID + "] mute=[" + msg.mute + "]")
users.getUser(msg.userID) match {
case Some(u) => {
// println("Sending mute user request uid=[" + msg.userID + "] mute=[" + msg.mute + "]")
logger.info("Muting user: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new MuteVoiceUser(meetingID, recorded, msg.requesterID, u.userID, msg.mute))
}
case None => {
logger.info("Could not find user to mute: mid=[" + meetingID + "] uid=[" + msg.userID + "]")
// println("Could not find user to mute. uid=[" + msg.userID + "] mute=[" + msg.mute + "]")
}
}
}
def handleEjectUserRequest(msg: EjectUserFromVoiceRequest) {
// println("Received eject user request uid=[" + msg.userID + "]")
users.getUser(msg.userId) match {
case Some(u) => {
if (u.voiceUser.joined) {
logger.info("Ejecting user from voice: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new EjectVoiceUser(meetingID, recorded, msg.ejectedBy, u.userID))
}
}
case None => // do nothing
}
}
def handleLockUser(msg: LockUser) {
}
def handleLockAllUsers(msg: LockAllUsers) {
}
def handleGetLockSettings(msg: GetLockSettings) {
}
def handleIsMeetingLocked(msg: IsMeetingLocked) {
}
def handleSetLockSettings(msg: SetLockSettings) {
// println("*************** Received new lock settings ********************")
if (!permissionsEqual(msg.settings)) {
newPermissions(msg.settings)
val au = affectedUsers(msg.settings)
outGW.send(new NewPermissionsSetting(meetingID, msg.setByUser, permissions, au))
handleLockLayout(msg.settings.lockedLayout, msg.setByUser)
}
}
def handleInitLockSettings(msg: InitLockSettings) {
if (! permissionsInited) {
permissionsInited = true
if (permissions != msg.settings || locked != msg.locked) {
permissions = msg.settings
locked = msg.locked
val au = affectedUsers(msg.settings)
outGW.send(new PermissionsSettingInitialized(msg.meetingID, msg.locked, msg.settings, au))
}
}
}
def usersWhoAreNotPresenter():Array[UserVO] = {
val au = ArrayBuffer[UserVO]()
users.getUsers foreach {u =>
if (! u.presenter) {
au += u
}
}
au.toArray
}
def affectedUsers(settings: Permissions):Array[UserVO] = {
val au = ArrayBuffer[UserVO]()
users.getUsers foreach {u =>
val nu = u.copy(permissions=permissions)
users.addUser(nu)
if (! u.presenter && u.role != Role.MODERATOR) {
au += nu
}
}
au.toArray
}
def handleUserRaiseHand(msg: UserRaiseHand) {
users.getUser(msg.userId) foreach {user =>
val uvo = user.copy(raiseHand=true)
users.addUser(uvo)
outGW.send(new UserRaisedHand(meetingID, recorded, uvo.userID))
}
}
def handleUserLowerHand(msg: UserLowerHand) {
users.getUser(msg.userId) foreach {user =>
val uvo = user.copy(raiseHand=false)
users.addUser(uvo)
outGW.send(new UserLoweredHand(meetingID, recorded, uvo.userID, msg.loweredBy))
}
}
def handleEjectUserFromMeeting(msg: EjectUserFromMeeting) {
users.getUser(msg.userId) foreach {user =>
if (user.voiceUser.joined) {
outGW.send(new EjectVoiceUser(meetingID, recorded, msg.ejectedBy, msg.userId))
}
users.removeUser(msg.userId)
logger.info("Ejecting user from meeting: mid=[" + meetingID + "]uid=[" + msg.userId + "]")
outGW.send(new UserEjectedFromMeeting(meetingID, recorded, msg.userId, msg.ejectedBy))
outGW.send(new DisconnectUser(meetingID, msg.userId))
outGW.send(new UserLeft(msg.meetingID, recorded, user))
}
}
def handleUserShareWebcam(msg: UserShareWebcam) {
users.getUser(msg.userId) foreach {user =>
val uvo = user.copy(hasStream=true, webcamStream=msg.stream)
users.addUser(uvo)
logger.info("User shared webcam: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserSharedWebcam(meetingID, recorded, uvo.userID, msg.stream))
}
}
def handleUserunshareWebcam(msg: UserUnshareWebcam) {
users.getUser(msg.userId) foreach {user =>
val stream = user.webcamStream
val uvo = user.copy(hasStream=false, webcamStream="")
users.addUser(uvo)
logger.info("User unshared webcam: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserUnsharedWebcam(meetingID, recorded, uvo.userID, stream))
}
}
def handleChangeUserStatus(msg: ChangeUserStatus):Unit = {
if (users.hasUser(msg.userID)) {
outGW.send(new UserStatusChange(meetingID, recorded, msg.userID, msg.status, msg.value))
}
}
def handleGetUsers(msg: GetUsers):Unit = {
outGW.send(new GetUsersReply(msg.meetingID, msg.requesterID, users.getUsers))
}
def handleUserJoin(msg: UserJoining):Unit = {
val regUser = regUsers.get(msg.userID)
regUser foreach { ru =>
val vu = new VoiceUser(msg.userID, msg.userID, ru.name, ru.name,
false, false, false, false)
val uvo = new UserVO(msg.userID, ru.externId, ru.name,
ru.role, raiseHand=false, presenter=false,
hasStream=false, locked=false, webcamStream="",
phoneUser=false, vu, listenOnly=false, permissions)
users.addUser(uvo)
logger.info("User joined meeting: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserJoined(meetingID, recorded, uvo))
outGW.send(new MeetingState(meetingID, recorded, uvo.userID, permissions, meetingMuted))
// Become presenter if the only moderator
if (users.numModerators == 1) {
if (ru.role == Role.MODERATOR) {
assignNewPresenter(msg.userID, ru.name, msg.userID)
}
}
webUserJoined
startRecordingIfAutoStart()
}
}
def handleUserLeft(msg: UserLeaving):Unit = {
if (users.hasUser(msg.userID)) {
val user = users.removeUser(msg.userID)
user foreach { u =>
logger.info("User left meeting: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new UserLeft(msg.meetingID, recorded, u))
}
startCheckingIfWeNeedToEndVoiceConf()
stopAutoStartedRecording()
}
}
def handleUserJoinedVoiceFromPhone(msg: VoiceUserJoined) = {
val user = users.getUserWithVoiceUserId(msg.voiceUser.userId) match {
case Some(user) => {
logger.info("Voice user=[" + msg.voiceUser.userId + "] is already in conf=[" + voiceBridge + "]. Must be duplicate message.")
}
case None => {
// No current web user. This means that the user called in through
// the phone. We need to generate a new user as we are not able
// to match with a web user.
val webUserId = users.generateWebUserId
val vu = new VoiceUser(msg.voiceUser.userId, webUserId,
msg.voiceUser.callerName, msg.voiceUser.callerNum,
true, false, false, false)
val uvo = new UserVO(webUserId, webUserId, msg.voiceUser.callerName,
Role.VIEWER, raiseHand=false, presenter=false,
hasStream=false, locked=false, webcamStream="",
phoneUser=true, vu, listenOnly=false, permissions)
users.addUser(uvo)
logger.info("New user joined voice for user [" + uvo.name + "] userid=[" + msg.voiceUser.webUserId + "]")
outGW.send(new UserJoined(meetingID, recorded, uvo))
outGW.send(new UserJoinedVoice(meetingID, recorded, voiceBridge, uvo))
if (meetingMuted)
outGW.send(new MuteVoiceUser(meetingID, recorded, uvo.userID, uvo.userID, meetingMuted))
}
}
}
def handleVoiceUserJoined(msg: VoiceUserJoined) = {
val user = users.getUser(msg.voiceUser.webUserId) match {
case Some(user) => {
val nu = user.copy(voiceUser=msg.voiceUser)
users.addUser(nu)
logger.info("Received user joined voice for user [" + nu.name + "] userid=[" + msg.voiceUser.webUserId + "]" )
outGW.send(new UserJoinedVoice(meetingID, recorded, voiceBridge, nu))
if (meetingMuted)
outGW.send(new MuteVoiceUser(meetingID, recorded, nu.userID, nu.userID, meetingMuted))
}
case None => {
handleUserJoinedVoiceFromPhone(msg)
}
}
}
def handleVoiceUserLeft(msg: VoiceUserLeft) {
users.getUser(msg.userId) foreach {user =>
val vu = new VoiceUser(user.userID, user.userID, user.name, user.name,
false, false, false, false)
val nu = user.copy(voiceUser=vu)
users.addUser(nu)
// println("Received voice user left =[" + user.name + "] wid=[" + msg.userId + "]" )
logger.info("Received user left voice for user [" + nu.name + "] userid=[" + msg.userId + "]" )
outGW.send(new UserLeftVoice(meetingID, recorded, voiceBridge, nu))
if (user.phoneUser) {
if (users.hasUser(user.userID)) {
val userLeaving = users.removeUser(user.userID)
userLeaving foreach (u => outGW.send(new UserLeft(msg.meetingID, recorded, u)))
}
}
}
}
def handleVoiceUserMuted(msg: VoiceUserMuted) {
users.getUser(msg.userId) foreach {user =>
val talking = if (msg.muted) false else user.voiceUser.talking
val nv = user.voiceUser.copy(muted=msg.muted, talking=talking)
val nu = user.copy(voiceUser=nv)
users.addUser(nu)
// println("Received voice muted=[" + msg.muted + "] wid=[" + msg.userId + "]" )
outGW.send(new UserVoiceMuted(meetingID, recorded, voiceBridge, nu))
}
}
def handleVoiceUserTalking(msg: VoiceUserTalking) {
users.getUser(msg.userId) foreach {user =>
val nv = user.voiceUser.copy(talking=msg.talking)
val nu = user.copy(voiceUser=nv)
users.addUser(nu)
// println("Received voice talking=[" + msg.talking + "] wid=[" + msg.userId + "]" )
outGW.send(new UserVoiceTalking(meetingID, recorded, voiceBridge, nu))
}
}
def handleAssignPresenter(msg: AssignPresenter):Unit = {
assignNewPresenter(msg.newPresenterID, msg.newPresenterName, msg.assignedBy)
}
def assignNewPresenter(newPresenterID:String, newPresenterName: String, assignedBy: String) {
if (users.hasUser(newPresenterID)) {
users.getCurrentPresenter match {
case Some(curPres) => {
users.unbecomePresenter(curPres.userID)
outGW.send(new UserStatusChange(meetingID, recorded, curPres.userID, "presenter", false:java.lang.Boolean))
}
case None => // do nothing
}
users.getUser(newPresenterID) match {
case Some(newPres) => {
users.becomePresenter(newPres.userID)
currentPresenter = new Presenter(newPresenterID, newPresenterName, assignedBy)
outGW.send(new PresenterAssigned(meetingID, recorded, new Presenter(newPresenterID, newPresenterName, assignedBy)))
outGW.send(new UserStatusChange(meetingID, recorded, newPresenterID, "presenter", true:java.lang.Boolean))
}
case None => // do nothing
}
}
}
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.core.api._
import scala.collection.mutable.HashMap
import org.bigbluebutton.core.User
import java.util.ArrayList
import org.bigbluebutton.core.MeetingActor
import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.ListSet
trait UsersApp {
this : MeetingActor =>
val outGW: MessageOutGateway
val users = new UsersModel
private var regUsers = new collection.immutable.HashMap[String, RegisteredUser]
private var locked = false
private var meetingMuted = false
private var currentPresenter = new Presenter("system", "system", "system")
private var guestsWaiting = new collection.immutable.ListSet[String]
def hasUser(userID: String):Boolean = {
users.hasUser(userID)
}
def getUser(userID:String):Option[UserVO] = {
users.getUser(userID)
}
def getCurrentPresenter:Presenter = {
currentPresenter
}
def handleUserConnectedToGlobalAudio(msg: UserConnectedToGlobalAudio) {
val user = users.getUserWithExternalId(msg.userid)
user foreach {u =>
val vu = u.voiceUser.copy(talking=false)
val uvo = u.copy(listenOnly=true, voiceUser=vu)
users.addUser(uvo)
logger.info("UserConnectedToGlobalAudio: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserListeningOnly(meetingID, recorded, uvo.userID, uvo.listenOnly))
}
}
def handleUserDisconnectedFromGlobalAudio(msg: UserDisconnectedFromGlobalAudio) {
val user = users.getUserWithExternalId(msg.userid)
user foreach {u =>
val uvo = u.copy(listenOnly=false)
users.addUser(uvo)
logger.info("UserDisconnectedToGlobalAudio: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserListeningOnly(meetingID, recorded, uvo.userID, uvo.listenOnly))
}
}
def handleMuteAllExceptPresenterRequest(msg: MuteAllExceptPresenterRequest) {
meetingMuted = msg.mute
outGW.send(new MeetingMuted(meetingID, recorded, meetingMuted))
usersWhoAreNotPresenter foreach {u =>
outGW.send(new MuteVoiceUser(meetingID, recorded, msg.requesterID, u.userID, msg.mute))
}
}
def handleMuteMeetingRequest(msg: MuteMeetingRequest) {
meetingMuted = msg.mute
outGW.send(new MeetingMuted(meetingID, recorded, meetingMuted))
users.getUsers foreach {u =>
outGW.send(new MuteVoiceUser(meetingID, recorded, msg.requesterID, u.userID, msg.mute))
}
}
def handleValidateAuthToken(msg: ValidateAuthToken) {
// println("*************** Got ValidateAuthToken message ********************" )
regUsers.get (msg.userId) match {
case Some(u) =>
{
val replyTo = meetingID + '/' + msg.userId
//send the reply
outGW.send(new ValidateAuthTokenReply(meetingID, msg.userId, msg.token, true, msg.correlationId))
//send the list of users in the meeting
outGW.send(new GetUsersReply(meetingID, msg.userId, users.getUsers))
//send chat history
this ! (new GetChatHistoryRequest(meetingID, msg.userId, replyTo))
//join the user
handleUserJoin(new UserJoining(meetingID, msg.userId))
//send the presentation
logger.info("ValidateToken success: mid=[" + meetingID + "] uid=[" + msg.userId + "]")
this ! (new GetPresentationInfo(meetingID, msg.userId, replyTo))
}
case None => {
logger.info("ValidateToken failed: mid=[" + meetingID + "] uid=[" + msg.userId + "]")
outGW.send(new ValidateAuthTokenReply(meetingID, msg.userId, msg.token, false, msg.correlationId))
}
}
}
def handleRegisterUser(msg: RegisterUser) {
if (hasMeetingEnded) {
// Check first if the meeting has ended and the user refreshed the client to re-connect.
logger.info("Register user failed: reason=[meeting has ended] mid=[" + meetingID + "] uid=[" + msg.userID + "]")
sendMeetingHasEnded(msg.userID)
} else {
val regUser = new RegisteredUser(msg.userID, msg.extUserID, msg.name, msg.role, msg.authToken, msg.guest)
regUsers += msg.userID -> regUser
logger.info("Register user success: mid=[" + meetingID + "] uid=[" + msg.userID + "]")
outGW.send(new UserRegistered(meetingID, recorded, regUser))
}
}
def handleIsMeetingMutedRequest(msg: IsMeetingMutedRequest) {
outGW.send(new IsMeetingMutedReply(meetingID, recorded, msg.requesterID, meetingMuted))
}
def handleMuteUserRequest(msg: MuteUserRequest) {
// println("Received mute user request uid=[" + msg.userID + "] mute=[" + msg.mute + "]")
users.getUser(msg.userID) match {
case Some(u) => {
// println("Sending mute user request uid=[" + msg.userID + "] mute=[" + msg.mute + "]")
logger.info("Muting user: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new MuteVoiceUser(meetingID, recorded, msg.requesterID, u.userID, msg.mute))
}
case None => {
logger.info("Could not find user to mute: mid=[" + meetingID + "] uid=[" + msg.userID + "]")
// println("Could not find user to mute. uid=[" + msg.userID + "] mute=[" + msg.mute + "]")
}
}
}
def handleEjectUserRequest(msg: EjectUserFromVoiceRequest) {
// println("Received eject user request uid=[" + msg.userID + "]")
users.getUser(msg.userId) match {
case Some(u) => {
if (u.voiceUser.joined) {
logger.info("Ejecting user from voice: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new EjectVoiceUser(meetingID, recorded, msg.ejectedBy, u.userID))
}
}
case None => // do nothing
}
}
def handleLockUser(msg: LockUser) {
}
def handleLockAllUsers(msg: LockAllUsers) {
}
def handleGetLockSettings(msg: GetLockSettings) {
}
def handleIsMeetingLocked(msg: IsMeetingLocked) {
}
def handleSetLockSettings(msg: SetLockSettings) {
// println("*************** Received new lock settings ********************")
if (!permissionsEqual(msg.settings)) {
newPermissions(msg.settings)
val au = affectedUsers(msg.settings)
outGW.send(new NewPermissionsSetting(meetingID, msg.setByUser, permissions, au))
handleLockLayout(msg.settings.lockedLayout, msg.setByUser)
}
}
def handleInitLockSettings(msg: InitLockSettings) {
if (! permissionsInited) {
permissionsInited = true
if (permissions != msg.settings || locked != msg.locked) {
permissions = msg.settings
locked = msg.locked
val au = affectedUsers(msg.settings)
outGW.send(new PermissionsSettingInitialized(msg.meetingID, msg.locked, msg.settings, au))
}
}
}
def usersWhoAreNotPresenter():Array[UserVO] = {
val au = ArrayBuffer[UserVO]()
users.getUsers foreach {u =>
if (! u.presenter) {
au += u
}
}
au.toArray
}
def affectedUsers(settings: Permissions):Array[UserVO] = {
val au = ArrayBuffer[UserVO]()
users.getUsers foreach {u =>
val nu = u.copy(permissions=permissions)
users.addUser(nu)
if (! u.presenter && u.role != Role.MODERATOR) {
au += nu
}
}
au.toArray
}
def handleUserRaiseHand(msg: UserRaiseHand) {
users.getUser(msg.userId) foreach {user =>
val uvo = user.copy(raiseHand=true)
users.addUser(uvo)
outGW.send(new UserRaisedHand(meetingID, recorded, uvo.userID))
}
}
def handleUserLowerHand(msg: UserLowerHand) {
users.getUser(msg.userId) foreach {user =>
val uvo = user.copy(raiseHand=false)
users.addUser(uvo)
outGW.send(new UserLoweredHand(meetingID, recorded, uvo.userID, msg.loweredBy))
}
}
def handleEjectUserFromMeeting(msg: EjectUserFromMeeting) {
users.getUser(msg.userId) foreach {user =>
if (user.voiceUser.joined) {
outGW.send(new EjectVoiceUser(meetingID, recorded, msg.ejectedBy, msg.userId))
}
users.removeUser(msg.userId)
logger.info("Ejecting user from meeting: mid=[" + meetingID + "]uid=[" + msg.userId + "]")
outGW.send(new UserEjectedFromMeeting(meetingID, recorded, msg.userId, msg.ejectedBy))
outGW.send(new DisconnectUser(meetingID, msg.userId))
outGW.send(new UserLeft(msg.meetingID, recorded, user))
}
}
def handleUserShareWebcam(msg: UserShareWebcam) {
users.getUser(msg.userId) foreach {user =>
val uvo = user.copy(hasStream=true, webcamStream=msg.stream)
users.addUser(uvo)
logger.info("User shared webcam: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserSharedWebcam(meetingID, recorded, uvo.userID, msg.stream))
}
}
def handleUserunshareWebcam(msg: UserUnshareWebcam) {
users.getUser(msg.userId) foreach {user =>
val stream = user.webcamStream
val uvo = user.copy(hasStream=false, webcamStream="")
users.addUser(uvo)
logger.info("User unshared webcam: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserUnsharedWebcam(meetingID, recorded, uvo.userID, stream))
}
}
def handleChangeUserStatus(msg: ChangeUserStatus):Unit = {
if (users.hasUser(msg.userID)) {
outGW.send(new UserStatusChange(meetingID, recorded, msg.userID, msg.status, msg.value))
}
}
def handleGetUsers(msg: GetUsers):Unit = {
// Filter out guests waiting
val approvedUsers = users.getUsers.filter(x => !guestsWaiting.contains(x.userID))
outGW.send(new GetUsersReply(msg.meetingID, msg.requesterID, approvedUsers))
}
def handleUserJoin(msg: UserJoining):Unit = {
val regUser = regUsers.get(msg.userID)
regUser foreach { ru =>
val vu = new VoiceUser(msg.userID, msg.userID, ru.name, ru.name,
false, false, false, false)
val uvo = new UserVO(msg.userID, ru.externId, ru.name,
ru.role, ru.guest, raiseHand=false, presenter=false,
hasStream=false, locked=false, webcamStream="",
phoneUser=false, vu, listenOnly=false, permissions)
users.addUser(uvo)
// Send UserJoined only if is not a guest or guest policy is always accept
// For guests this message will be sent when they are accepted
if(!ru.guest || guestPolicy == GuestPolicy.ALWAYS_ACCEPT) {
logger.info("User joined meeting: mid=[" + meetingID + "] uid=[" + uvo.userID + "]")
outGW.send(new UserJoined(meetingID, recorded, uvo))
outGW.send(new MeetingState(meetingID, recorded, uvo.userID, permissions, meetingMuted))
// Become presenter if the only moderator
if (users.numModerators == 1) {
if (ru.role == Role.MODERATOR) {
assignNewPresenter(msg.userID, ru.name, msg.userID)
}
}
}
outGW.send(new JoinMeetingReply(meetingID, recorded, uvo))
webUserJoined
startRecordingIfAutoStart()
}
}
def handleUserLeft(msg: UserLeaving):Unit = {
if (users.hasUser(msg.userID)) {
guestsWaiting = guestsWaiting - msg.userID
val user = users.removeUser(msg.userID)
user foreach { u =>
logger.info("User left meeting: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new UserLeft(msg.meetingID, recorded, u))
}
startCheckingIfWeNeedToEndVoiceConf()
stopAutoStartedRecording()
}
}
def handleUserJoinedVoiceFromPhone(msg: VoiceUserJoined) = {
val user = users.getUserWithVoiceUserId(msg.voiceUser.userId) match {
case Some(user) => {
logger.info("Voice user=[" + msg.voiceUser.userId + "] is already in conf=[" + voiceBridge + "]. Must be duplicate message.")
}
case None => {
// No current web user. This means that the user called in through
// the phone. We need to generate a new user as we are not able
// to match with a web user.
val webUserId = users.generateWebUserId
val vu = new VoiceUser(msg.voiceUser.userId, webUserId,
msg.voiceUser.callerName, msg.voiceUser.callerNum,
true, false, false, false)
val uvo = new UserVO(webUserId, webUserId, msg.voiceUser.callerName,
Role.VIEWER, guest=false, raiseHand=false, presenter=false,
hasStream=false, locked=false, webcamStream="",
phoneUser=true, vu, listenOnly=false, permissions)
users.addUser(uvo)
logger.info("New user joined voice for user [" + uvo.name + "] userid=[" + msg.voiceUser.webUserId + "]")
outGW.send(new UserJoined(meetingID, recorded, uvo))
outGW.send(new JoinMeetingReply(meetingID, recorded, uvo))
outGW.send(new UserJoinedVoice(meetingID, recorded, voiceBridge, uvo))
if (meetingMuted)
outGW.send(new MuteVoiceUser(meetingID, recorded, uvo.userID, uvo.userID, meetingMuted))
}
}
}
def handleVoiceUserJoined(msg: VoiceUserJoined) = {
val user = users.getUser(msg.voiceUser.webUserId) match {
case Some(user) => {
val nu = user.copy(voiceUser=msg.voiceUser)
users.addUser(nu)
logger.info("Received user joined voice for user [" + nu.name + "] userid=[" + msg.voiceUser.webUserId + "]" )
outGW.send(new UserJoinedVoice(meetingID, recorded, voiceBridge, nu))
if (meetingMuted)
outGW.send(new MuteVoiceUser(meetingID, recorded, nu.userID, nu.userID, meetingMuted))
}
case None => {
handleUserJoinedVoiceFromPhone(msg)
}
}
}
def handleVoiceUserLeft(msg: VoiceUserLeft) {
users.getUser(msg.userId) foreach {user =>
val vu = new VoiceUser(user.userID, user.userID, user.name, user.name,
false, false, false, false)
val nu = user.copy(voiceUser=vu)
users.addUser(nu)
// println("Received voice user left =[" + user.name + "] wid=[" + msg.userId + "]" )
logger.info("Received user left voice for user [" + nu.name + "] userid=[" + msg.userId + "]" )
outGW.send(new UserLeftVoice(meetingID, recorded, voiceBridge, nu))
if (user.phoneUser) {
if (users.hasUser(user.userID)) {
val userLeaving = users.removeUser(user.userID)
userLeaving foreach (u => outGW.send(new UserLeft(msg.meetingID, recorded, u)))
}
}
}
}
def handleVoiceUserMuted(msg: VoiceUserMuted) {
users.getUser(msg.userId) foreach {user =>
val talking = if (msg.muted) false else user.voiceUser.talking
val nv = user.voiceUser.copy(muted=msg.muted, talking=talking)
val nu = user.copy(voiceUser=nv)
users.addUser(nu)
// println("Received voice muted=[" + msg.muted + "] wid=[" + msg.userId + "]" )
outGW.send(new UserVoiceMuted(meetingID, recorded, voiceBridge, nu))
}
}
def handleVoiceUserTalking(msg: VoiceUserTalking) {
users.getUser(msg.userId) foreach {user =>
val nv = user.voiceUser.copy(talking=msg.talking)
val nu = user.copy(voiceUser=nv)
users.addUser(nu)
// println("Received voice talking=[" + msg.talking + "] wid=[" + msg.userId + "]" )
outGW.send(new UserVoiceTalking(meetingID, recorded, voiceBridge, nu))
}
}
def handleAssignPresenter(msg: AssignPresenter):Unit = {
assignNewPresenter(msg.newPresenterID, msg.newPresenterName, msg.assignedBy)
}
def assignNewPresenter(newPresenterID:String, newPresenterName: String, assignedBy: String) {
if (users.hasUser(newPresenterID)) {
users.getCurrentPresenter match {
case Some(curPres) => {
users.unbecomePresenter(curPres.userID)
outGW.send(new UserStatusChange(meetingID, recorded, curPres.userID, "presenter", false:java.lang.Boolean))
}
case None => // do nothing
}
users.getUser(newPresenterID) match {
case Some(newPres) => {
users.becomePresenter(newPres.userID)
currentPresenter = new Presenter(newPresenterID, newPresenterName, assignedBy)
outGW.send(new PresenterAssigned(meetingID, recorded, new Presenter(newPresenterID, newPresenterName, assignedBy)))
outGW.send(new UserStatusChange(meetingID, recorded, newPresenterID, "presenter", true:java.lang.Boolean))
}
case None => // do nothing
}
}
}
def handleUserRequestToEnter(msg: UserRequestToEnter) {
users.getUser(msg.userID) match {
case Some(user) => {
guestsWaiting = guestsWaiting + msg.userID;
outGW.send(new GuestRequestedToEnter(meetingID, recorded, msg.userID, user.name))
}
case None => {
// println("handleUserRequestToEnter user [" + msg.userId + "] not found.")
}
}
}
def handleGetGuestsWaiting(msg: GetGuestsWaiting) {
if(users.hasUser(msg.requesterID)) {
var message = "";
guestsWaiting foreach {guest => {
users.getUser(guest) match {
case Some(user) => message = message + user.userID + ":" + user.name + ","
case None => {}
}
}}
outGW.send(new GetGuestsWaitingReply(meetingID, recorded, msg.requesterID, message))
}
}
def handleRespondToGuest(msg: RespondToGuest) {
if(guestsWaiting.contains(msg.guestID)) {
guestsWaiting = guestsWaiting - msg.guestID
outGW.send(new ResponseToGuest(meetingID, recorded, msg.guestID, msg.response))
if(msg.response == true) {
users.getUser(msg.guestID) foreach {user =>
println("UsersApp - handleResponseToGuest sending userJoined["+user.userID+"]");
outGW.send(new UserJoined(meetingID, recorded, user))
outGW.send(new MeetingState(meetingID, recorded, user.userID, permissions, meetingMuted))
}
}
}
}
def handleRespondToAllGuests(msg: RespondToAllGuests) {
guestsWaiting foreach {guest =>
if(msg.response == true) {
users.getUser(guest) foreach {user =>
println("UsersApp - handleResponseToGuest sending userJoined["+user.userID+"]");
outGW.send(new UserJoined(meetingID, recorded, user))
outGW.send(new MeetingState(meetingID, recorded, user.userID, permissions, meetingMuted))
}
}
outGW.send(new ResponseToGuest(meetingID, recorded, guest, msg.response))
}
guestsWaiting = new collection.immutable.ListSet[String]
}
def handleKickGuest(msg: KickGuest) {
guestsWaiting = guestsWaiting - msg.guestID;
outGW.send(new GuestKicked(meetingID, recorded, msg.guestID))
}
}

View File

@ -23,6 +23,7 @@ class UsersClientMessageSender(service: ConnectionInvokerService) extends OutMes
case msg: DisconnectUser => handleDisconnectUser(msg)
case msg: PresenterAssigned => handleAssignPresenter(msg)
case msg: UserJoined => handleUserJoined(msg)
case msg: JoinMeetingReply => handleJoinMeetingReply(msg)
case msg: UserLeft => handleUserLeft(msg)
case msg: UserStatusChange => handleUserStatusChange(msg)
case msg: UserRaisedHand => handleUserRaisedHand(msg)
@ -42,6 +43,12 @@ class UsersClientMessageSender(service: ConnectionInvokerService) extends OutMes
case msg: NewPermissionsSetting => handleNewPermissionsSetting(msg)
case msg: MeetingMuted => handleMeetingMuted(msg)
case msg: MeetingState => handleMeetingState(msg)
case msg: GuestRequestedToEnter => handleGuestRequestedToEnter(msg)
case msg: GetGuestPolicyReply => handleGetGuestPolicyReply(msg)
case msg: GuestPolicyChanged => handleGuestPolicyChanged(msg)
case msg: GetGuestsWaitingReply => handleGetGuestsWaitingReply(msg)
case msg: ResponseToGuest => handleResponseToGuest(msg)
case msg: GuestKicked => handleGuestKicked(msg)
case _ => // println("Unhandled message in UsersClientMessageSender")
}
@ -74,6 +81,7 @@ class UsersClientMessageSender(service: ConnectionInvokerService) extends OutMes
wuser.put("externUserID", user.externUserID)
wuser.put("name", user.name)
wuser.put("role", user.role.toString())
wuser.put("guest", user.guest:java.lang.Boolean)
wuser.put("raiseHand", user.raiseHand:java.lang.Boolean)
wuser.put("presenter", user.presenter:java.lang.Boolean)
wuser.put("hasStream", user.hasStream:java.lang.Boolean)
@ -347,19 +355,25 @@ class UsersClientMessageSender(service: ConnectionInvokerService) extends OutMes
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - joinMeetingReply \n" + message.get("msg") + "\n")
var jmr = new DirectClientMessage(msg.meetingID, msg.user.userID, "joinMeetingReply", message);
service.sendMessage(jmr);
// println("UsersClientMessageSender - handleUserJoined \n" + message.get("msg") + "\n")
var m = new BroadcastClientMessage(msg.meetingID, "participantJoined", message);
service.sendMessage(m);
}
private def handleJoinMeetingReply(msg: JoinMeetingReply):Unit = {
var args = new HashMap[String, Object]();
args.put("user", buildUserHashMap(msg.user));
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - joinMeetingReply \n" + message.get("msg") + "\n")
var jmr = new DirectClientMessage(msg.meetingID, msg.user.userID, "joinMeetingReply", message);
service.sendMessage(jmr);
}
private def handleUserLeft(msg: UserLeft):Unit = {
var args = new HashMap[String, Object]();
args.put("user", buildUserHashMap(msg.user));
@ -462,4 +476,90 @@ class UsersClientMessageSender(service: ConnectionInvokerService) extends OutMes
var m = new BroadcastClientMessage(msg.meetingID, "user_listening_only", message);
service.sendMessage(m);
}
}
private def handleGuestRequestedToEnter(msg: GuestRequestedToEnter) {
var args = new HashMap[String, Object]();
args.put("userId", msg.userID);
args.put("name", msg.name);
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - handleGuestRequestedToEnter \n" + message.get("msg") + "\n")
var m = new BroadcastClientMessage(msg.meetingID, "user_requested_to_enter", message);
service.sendMessage(m);
}
private def handleGetGuestPolicyReply(msg: GetGuestPolicyReply) {
var args = new HashMap[String, Object]();
args.put("guestPolicy", msg.policy.toString());
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - handleGetGuestPolicyReply \n" + message.get("msg") + "\n")
val m = new DirectClientMessage(msg.meetingID, msg.requesterID,"get_guest_policy_reply", message);
service.sendMessage(m);
}
private def handleGuestPolicyChanged(msg: GuestPolicyChanged) {
var args = new HashMap[String, Object]();
args.put("guestPolicy", msg.policy.toString());
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - handleGuestPolicyChanged \n" + message.get("msg") + "\n")
var m = new BroadcastClientMessage(msg.meetingID, "guest_policy_changed", message);
service.sendMessage(m);
}
private def handleGetGuestsWaitingReply(msg: GetGuestsWaitingReply) {
var args = new HashMap[String, Object]();
args.put("guestsWaiting", msg.guestsWaiting);
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - handleGetGuestsWaitingReply \n" + message.get("msg") + "\n")
val m = new DirectClientMessage(msg.meetingID, msg.requesterID, "get_guests_waiting_reply", message);
service.sendMessage(m);
}
private def handleResponseToGuest(msg: ResponseToGuest) {
var args = new HashMap[String, Object]();
args.put("userId", msg.guestID);
args.put("response", msg.response:java.lang.Boolean);
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - handleResponseToGuest \n" + message.get("msg") + "\n")
val m = new BroadcastClientMessage(msg.meetingID, "response_to_guest", message);
service.sendMessage(m);
}
private def handleGuestKicked(msg: GuestKicked) {
var args = new HashMap[String, Object]();
args.put("guestId", msg.guestID);
val message = new java.util.HashMap[String, Object]()
val gson = new Gson();
message.put("msg", gson.toJson(args))
// println("UsersClientMessageSender - handleGuestKicked \n" + message.get("msg") + "\n")
val m = new BroadcastClientMessage(msg.meetingID, "guest_kicked", message);
service.sendMessage(m);
}
}

View File

@ -16,6 +16,7 @@ object UsersMessageToJsonConverter {
wuser += "extern_userid" -> user.externUserID
wuser += "name" -> user.name
wuser += "role" -> user.role.toString()
wuser += "guest" -> user.guest
wuser += "raise_hand" -> user.raiseHand
wuser += "presenter" -> user.presenter
wuser += "has_stream" -> user.hasStream
@ -55,7 +56,8 @@ object UsersMessageToJsonConverter {
wuser += "name" -> user.name
wuser += "role" -> user.role.toString()
wuser += "authToken" -> user.authToken
wuser += "guest" -> user.guest
mapAsJavaMap(wuser)
}

View File

@ -64,7 +64,7 @@ ToolTip {
color: #e1e2e5;
}
Button, .logoutButtonStyle, .chatSendButtonStyle, .helpLinkButtonStyle, .cameraDisplaySettingsWindowChangeResolutionCombo, .languageSelectorStyle, .testJavaLinkButtonStyle, .recordButtonStyleNormal, .recordButtonStyleStart, .recordButtonStyleStop, .micSettingsWindowHelpButtonStyle {
Button, .logoutButtonStyle, .chatSendButtonStyle, .helpLinkButtonStyle, .cameraDisplaySettingsWindowChangeResolutionCombo, .languageSelectorStyle, .testJavaLinkButtonStyle, .recordButtonStyleNormal, .recordButtonStyleStart, .recordButtonStyleStop, .micSettingsWindowHelpButtonStyle, .settingsButtonStyle {
textIndent: 0;
paddingLeft: 10;
paddingRight: 10;
@ -134,6 +134,10 @@ Button, .logoutButtonStyle, .chatSendButtonStyle, .helpLinkButtonStyle, .cameraD
icon: Embed('assets/images/logout.png');
}
.settingsButtonStyle {
icon: Embed('assets/images/wrench.png');
}
DataGrid {
backgroundColor: #e1e2e5;
rollOverColor: #f3f3f3;
@ -851,4 +855,4 @@ Alert {
.statusMessageStyle {
fontSize: 12;
paddingTop: 0;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

View File

@ -95,6 +95,20 @@ bbb.mainToolbar.recordBtn..notification.message1 = You can record this meeting.
bbb.mainToolbar.recordBtn..notification.message2 = You must click the Start/Stop Recording button in the title bar to begin/end recording.
bbb.mainToolbar.recordingLabel.recording = (Recording)
bbb.mainToolbar.recordingLabel.notRecording = Not Recording
bbb.waitWindow.waitMessage.message = You are a guest, please wait moderator approval.
bbb.waitWindow.waitMessage.title = Waiting
bbb.guests.title = Guests
bbb.guests.message.singular = {0} user wants to join this meeting
bbb.guests.message.plural = {0} users want to join this meeting
bbb.guests.allowBtn.toolTip = Allow
bbb.guests.allowEveryoneBtn.text = Allow everyone
bbb.guests.denyBtn.toolTip = Deny
bbb.guests.denyEveryoneBtn.text = Deny everyone
bbb.guests.rememberAction.text = Remember choice
bbb.guests.alwaysAccept = Always accept
bbb.guests.alwaysDeny = Always deny
bbb.guests.askModerator = Ask moderator
bbb.guests.Management = Guest management
bbb.clientstatus.title = Configuration Notifications
bbb.clientstatus.notification = Unread notifications
bbb.clientstatus.tunneling.title = Firewall
@ -328,9 +342,14 @@ bbb.logout.connectionfailed = The connection to the server has failed
bbb.logout.rejected = The connection to the server has been rejected
bbb.logout.invalidapp = The red5 app does not exist
bbb.logout.unknown = Your client has lost connection with the server
bbb.logout.guestkickedout = The moderator didn't allow you to join this meeting
bbb.logout.usercommand = You have logged out of the conference
bbb.logout.refresh.message = If this logout was unexpected click the button below to reconnect.
bbb.logout.refresh.label = Reconnect
bbb.settings.title = Settings
bbb.settings.ok = OK
bbb.settings.cancel = Cancel
bbb.settings.btn.toolTip = Open configuration window
bbb.logout.confirm.title = Confirm Logout
bbb.logout.confirm.message = Are you sure you want to log out?
bbb.logout.confirm.yes = Yes

View File

@ -95,6 +95,20 @@ bbb.mainToolbar.recordBtn..notification.message1 = Você pode gravar esta sessã
bbb.mainToolbar.recordBtn..notification.message2 = Você precisa clicar no botão de Iniciar/Encerrar gravação na barra superior para começar/terminar a gravação.
bbb.mainToolbar.recordingLabel.recording = (Gravando)
bbb.mainToolbar.recordingLabel.notRecording = Não gravando
bbb.waitWindow.waitMessage.message = Você é um convidado, por favor aguarde a aprovação do moderador da sessão.
bbb.waitWindow.waitMessage.title = Aguardando
bbb.guests.title = Convidados
bbb.guests.message.singular = {0} usuário deseja entrar na sessão
bbb.guests.message.plural = {0} usuários desejam entrar na sessão
bbb.guests.allowBtn.toolTip = Permitir
bbb.guests.allowEveryoneBtn.text = Permitir todos
bbb.guests.denyBtn.toolTip = Rejeitar
bbb.guests.denyEveryoneBtn.text = Rejeitar todos
bbb.guests.rememberAction.text = Lembrar escolha
bbb.guests.alwaysAccept = Sempre permitir
bbb.guests.alwaysDeny = Sempre rejeitar
bbb.guests.askModerator = Perguntar para o moderador
bbb.guests.Management = Gerenciar convidados
bbb.clientstatus.title = Configuração de Notificações
bbb.clientstatus.notification = Notificações não lidas
bbb.clientstatus.tunneling.title = Firewall
@ -328,6 +342,11 @@ bbb.logout.connectionfailed = A conexão com o servidor falhou
bbb.logout.rejected = A conexão com o servidor foi rejeitada
bbb.logout.invalidapp = O aplicativo red5 não existe
bbb.logout.unknown = Seu cliente perdeu conexão com o servidor
bbb.logout.guestkickedout = O moderador não permitiu sua entrada na sala
bbb.settings.title = Configurações
bbb.settings.ok = OK
bbb.settings.cancel = Cancelar
bbb.settings.btn.toolTip = Abrir janela de configurações
bbb.logout.usercommand = Você saiu da conferência
bbb.logout.refresh.message = Se você foi desconectado de maneira inesperada, clique no botão baixo para reconectar.
bbb.logout.refresh.label = Reconectar

View File

@ -205,6 +205,12 @@ package org.bigbluebutton.common
[Embed(source="assets/images/control_play_blue.png")]
public var control_play:Class;
[Embed(source="assets/images/accept.png")]
public var accept_user:Class;
[Embed(source="assets/images/cancel.png")]
public var cancel_user:Class;
[Embed(source="assets/images/shape_move_front.png")]
public var layout:Class;

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

View File

@ -0,0 +1,40 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
import mx.core.UIComponent;
public class SettingsComponentEvent extends Event
{
public static const ADD:String = "Add Component Event";
public static const REMOVE:String = "Remove Component Event";
public var component:UIComponent;
public function SettingsComponentEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -177,6 +177,17 @@ package org.bigbluebutton.core
}
return null;
}
public static function amIGuest(): Boolean {
return UserManager.getInstance().getConference().amIGuest();
}
public static function amIWaitForModerator(): Boolean {
return UserManager.getInstance().getConference().amIWaitForModerator();
}
public static function setWaitForModerator(state: Boolean): void {
UserManager.getInstance().getConference().setWaitForModerator(state);
}
}
}
}

View File

@ -64,9 +64,13 @@ package org.bigbluebutton.core.managers
connDelegate.sendMessage(service, onSuccess, onFailure, message);
}
public function forceClose():void {
connDelegate.forceClose();
}
public function forceClose():void {
connDelegate.forceClose();
}
public function guestDisconnect():void {
connDelegate.guestDisconnect();
}
}
}

View File

@ -12,6 +12,7 @@ package org.bigbluebutton.core.model
internal var logoutURL:String;
internal var dialNumber:String;
internal var role:String;
internal var guest:Boolean;
internal var customData:Object;
public function MeBuilder(id: String, name: String) {
@ -58,7 +59,12 @@ package org.bigbluebutton.core.model
role = value;
return this;
}
public function withGuest(value: Boolean):MeBuilder {
guest = value;
return this;
}
public function withCustomData(value: Object):MeBuilder {
customData = value;
return this;
@ -68,4 +74,4 @@ package org.bigbluebutton.core.model
return new Me(this);
}
}
}
}

View File

@ -43,7 +43,11 @@ package org.bigbluebutton.core.model.users
public function withRole(value: String):UserBuilder {
return this;
}
public function withGuest(value: Boolean):UserBuilder {
return this;
}
public function withCustomData(value: String):UserBuilder {
return this;
}
@ -53,4 +57,4 @@ package org.bigbluebutton.core.model.users
}
}
}
}

View File

@ -0,0 +1,36 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
public class AddGuestEvent extends Event
{
public static const ADD_GUEST:String = "AddGuest";
public var userid:String;
public var name:String;
public function AddGuestEvent(type:String = ADD_GUEST)
{
super(type, true, false);
}
}
}

View File

@ -31,7 +31,7 @@ package org.bigbluebutton.main.events {
public static const VIDEO_STARTED:String = 'BBB_VIDEO_STARTED';
public static const START_DESKSHARE:String = 'BBB_START_DESKSHARE';
public static const DESKSHARE_STARTED:String = 'BBB_DESKSHARE_STARTED';
public static const USER_VOICE_JOINED:String = 'user voice joined event';
public static const USER_VOICE_JOINED:String = 'user voice joined event';
public static const USER_VOICE_MUTED:String = "user voice muted event";
public static const USER_LOCKED:String = "user locked event";
public static const USER_VOICE_LEFT:String = "user voice left event";
@ -42,7 +42,21 @@ package org.bigbluebutton.main.events {
public static const CAM_SETTINGS_CLOSED:String = "CAM_SETTINGS_CLOSED";
public static const JOIN_VOICE_FOCUS_HEAD:String = "JOIN_VOICE_FOCUS_HEAD";
public static const CHANGE_RECORDING_STATUS:String = "CHANGE_RECORDING_STATUS";
public static const SETTINGS_CONFIRMED:String = "BBB_SETTINGS_CONFIRMED";
public static const SETTINGS_CANCELLED:String = "BBB_SETTINGS_CANCELLED";
public static const ACCEPT_ALL_WAITING_GUESTS:String = "BBB_ACCEPT_ALL_WAITING_GUESTS";
public static const DENY_ALL_WAITING_GUESTS:String = "BBB_DENY_ALL_WAITING_GUESTS";
public static const DENY_GUEST:String = "BBB_DENY_GUEST";
public static const ACCEPT_GUEST:String = "BBB_ACCEPT_GUEST";
public static const ASK_TO_ACCEPT_GUEST:String = "BBB_ASK_TO_ACCEPT_GUEST";
public static const BROADCAST_GUEST_POLICY:String = "BBB_BROADCAST_GUEST_POLICY";
public static const RETRIEVE_GUEST_POLICY:String = "BBB_RETRIEVE_GUEST_POLICY";
public static const KICK_GUEST:String = "KICK_GUEST";
public var message:String;
public var payload:Object = new Object();
@ -51,4 +65,4 @@ package org.bigbluebutton.main.events {
this.message = message;
}
}
}
}

View File

@ -25,6 +25,7 @@ package org.bigbluebutton.main.events
public static const USER_LOGGED_OUT:String = "USER_LOGGED_OUT";
public static const DISCONNECT_TEST:String = "disconnect_test";
public static const USER_KICKED_OUT:String = "USER_KICKED_OUT";
public static const GUEST_KICKED_OUT:String = "GUEST_KICKED_OUT";
public static const CONFIRM_LOGOUT:String = "CONFIRM_LOGOUT";
public static const REFOCUS_CONFIRM:String = "REFOCUS_CONFIRM";

View File

@ -0,0 +1,32 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
public class ModeratorRespEvent extends Event
{
public static const GUEST_ALLOWED:String = "GuestAllowed";
public function ModeratorRespEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,40 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
import org.bigbluebutton.main.model.users.BBBUser;
public class NewGuestEvent extends Event
{
public static const NEW_GUEST_EVENT:String = "NewGuestEvent";
public var userid:String;
public var name:String;
public function NewGuestEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,34 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
public class RefreshGuestEvent extends Event
{
public static const REFRESH_GUEST_VIEW:String = "RefreshGuestView";
public var listOfGuests:Object;
public function RefreshGuestEvent(type:String = REFRESH_GUEST_VIEW)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,35 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
public class RemoveGuestEvent extends Event
{
public static const REMOVE_GUEST:String = "RemoveGuest";
public static const REMOVE_ALL:String = "RemoveAllGuests";
public var userid:String;
public function RemoveGuestEvent(type:String = REMOVE_GUEST)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,34 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
public class RemoveGuestFromViewEvent extends Event
{
public static const REMOVE_GUEST:String = "RemoveGuest";
public var userid:String;
public function RemoveGuestFromViewEvent(type:String = REMOVE_GUEST)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,38 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
public class RemoveGuestRequestEvent extends Event
{
public static const GUEST_EVENT:String = "GuestEvent";
public var userid:String;
public function RemoveGuestRequestEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,41 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
import org.bigbluebutton.main.model.ConferenceParameters;
import org.bigbluebutton.main.model.users.BBBUser;
import org.bigbluebutton.main.model.ConferenceParameters;
public class ResponseModeratorEvent extends Event
{
public static const RESPONSE:String = "Response";
public static const RESPONSE_ALL:String = "RESPONSE_ALL";
public var userid:String;
public var resp:Boolean;
public function ResponseModeratorEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -0,0 +1,36 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.events
{
import flash.events.Event;
import org.bigbluebutton.main.model.ConferenceParameters;
public class WaitModeratorEvent extends Event
{
public static const USER_LOGGED_IN:String = "UserLoggedIn";
public var conferenceParameters:ConferenceParameters;
public function WaitModeratorEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -51,11 +51,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<EventHandlers type="{SuccessfulLoginEvent.USER_LOGGED_IN}" >
<MethodInvoker generator="{ModulesProxy}" method="loadAllModules" arguments="{event.conferenceParameters}" />
</EventHandlers>
<EventHandlers type="{LogoutEvent.USER_LOGGED_OUT}" >
<MethodInvoker generator="{ModulesProxy}" method="handleLogout" />
</EventHandlers>
<EventHandlers type="{ConfigEvent.CONFIG_EVENT}" >
<MethodInvoker generator="{ConfigManager}" method="setConfig" arguments="{event.config}" />
<MethodInvoker generator="{SkinningService}" method="loadSkins" arguments="{event.config.skinning}" />
@ -69,8 +69,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<MethodInvoker generator="{ModulesProxy}" method="startAllModules" />
</EventHandlers>
<EventHandlers type="{LogoutEvent.GUEST_KICKED_OUT}" >
<MethodInvoker generator="{ModulesProxy}" method="handleLogout" />
</EventHandlers>
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
@ -86,7 +88,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.main.model.PortTestProxy;
import org.bigbluebutton.main.model.modules.ModulesProxy;
]]>
</mx:Script>

View File

@ -60,6 +60,11 @@ package org.bigbluebutton.main.model
* Voice conference bridge that external SIP clients use. Usually the same as webvoiceconf
*/
public var voicebridge:String;
/**
* Flag used to enter as a guest
*/
public var guest:Boolean;
/**
* The welcome string, as passed in through the API /create call.
@ -100,4 +105,4 @@ package org.bigbluebutton.main.model
* */
public var lockSettings:Object;
}
}
}

View File

@ -0,0 +1,57 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2013 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 2.1 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/>.
*
* author:
*/
package org.bigbluebutton.main.model
{
public class Guest
{
private var listOfGuests:Object = new Object();
private var numberOfGuests:Number = 0;
public function hasGuest():Boolean {
return numberOfGuests > 0;
}
public function getNumberOfGuests():Number {
return numberOfGuests;
}
public function addGuest(userid:String, username:String):void {
listOfGuests[userid] = username;
numberOfGuests++;
}
public function getGuests():Object {
return this.listOfGuests;
}
public function removeAllGuests():void {
listOfGuests = new Object();
numberOfGuests = 0;
}
public function remove(userid:String):void {
if (listOfGuests[userid] != null) {
numberOfGuests--;
delete listOfGuests[userid];
}
}
}
}

View File

@ -0,0 +1,64 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2013 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 2.1 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/>.
*
* author:
*/
package org.bigbluebutton.main.model
{
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.main.events.RefreshGuestEvent;
import org.bigbluebutton.main.events.AddGuestEvent;
import org.bigbluebutton.main.events.RemoveGuestFromViewEvent;
public class GuestManager
{
private var guest:Guest;
private var dispatcher:Dispatcher;
function GuestManager() {
this.dispatcher = new Dispatcher();
this.guest = new Guest();
}
public function addGuest(evt:AddGuestEvent):void {
guest.addGuest(evt.userid, evt.name);
refreshGuestView();
}
private function refreshGuestView():void {
var refreshGuestEvent:RefreshGuestEvent = new RefreshGuestEvent();
refreshGuestEvent.listOfGuests = guest.getGuests();
dispatcher.dispatchEvent(refreshGuestEvent);
}
public function removeAllGuests():void {
guest.removeAllGuests();
}
private function removeGuestFromView(userid:String):void {
var removeGuestFromViewEvent:RemoveGuestFromViewEvent = new RemoveGuestFromViewEvent();
removeGuestFromViewEvent.userid = userid;
dispatcher.dispatchEvent(removeGuestFromViewEvent);
}
public function removeGuest(userid:String):void {
guest.remove(userid);
removeGuestFromView(userid);
}
}
}

View File

@ -28,5 +28,6 @@ package org.bigbluebutton.main.model
public var role:String;
public var isPresenter:Boolean;
public var authToken:String;
public var guest:Boolean;
}
}
}

View File

@ -40,7 +40,7 @@ package org.bigbluebutton.main.model.users
[Bindable] public var me:Boolean = false;
[Bindable] public var userID:String = "UNKNOWN USER";
[Bindable] public var externUserID:String = "UNKNOWN USER";
[Bindable] public var externUserID:String = "UNKNOWN USER";
[Bindable] public var name:String;
[Bindable] public var talking:Boolean = false;
[Bindable] public var phoneUser:Boolean = false;
@ -52,6 +52,10 @@ package org.bigbluebutton.main.model.users
[Bindable] public var disableMyPublicChat:Boolean = false;
[Bindable] public var lockedLayout:Boolean = false;
[Bindable] public var waitingForMod:Boolean = false;
[Bindable] public var guest:Boolean;
[Bindable] public var acceptedJoin:Boolean = false;
private var _hasStream:Boolean = false;
[Bindable]
public function get hasStream():Boolean {
@ -149,6 +153,10 @@ package org.bigbluebutton.main.model.users
_userStatus = ResourceUtil.getInstance().getString('bbb.users.usersGrid.statusItemRenderer.viewer');
}
public function amIGuest():Boolean {
return guest;
}
/*
* This variable is for accessibility for the Users Window. It can't be manually set
* and only changes when one of the relevant media variables changes. Use the verifyMedia
@ -298,6 +306,8 @@ package org.bigbluebutton.main.model.users
n.disableMyMic = user.disableMyMic;
n.disableMyPrivateChat = user.disableMyPrivateChat;
n.disableMyPublicChat = user.disableMyPublicChat;
n.guest = user.guest;
return n;
}
@ -335,4 +345,4 @@ package org.bigbluebutton.main.model.users
}
}
}
}
}

View File

@ -143,6 +143,14 @@ package org.bigbluebutton.main.model.users {
public function getDefaultLayout():String {
return defaultLayout;
}
public function amIWaitForModerator():Boolean {
return me.waitingForMod;
}
public function setWaitForModerator(state:Boolean):void {
me.waitingForMod = state;
}
public function hasUser(userID:String):Boolean {
var p:Object = getUserIndex(userID);
@ -363,6 +371,14 @@ package org.bigbluebutton.main.model.users {
public function setMyRole(role:String):void {
me.role = role;
}
public function amIGuest():Boolean {
return me.guest;
}
public function setGuest(guest:Boolean):void {
me.guest = guest;
}
public function setMyRoom(room:String):void {
me.room = room;

View File

@ -100,6 +100,7 @@ package org.bigbluebutton.main.model.users
response.externUserID = result.response.externUserID;
response.internalUserId = result.response.internalUserID;
response.role = result.response.role;
response.guest = result.response.guest;
response.room = result.response.room;
response.authToken = result.response.room;
response.record = result.response.record;
@ -137,7 +138,8 @@ package org.bigbluebutton.main.model.users
.withExternalId(response.externUserID).withToken(response.authToken)
.withLayout(response.defaultLayout).withWelcome(response.welcome)
.withDialNumber(response.dialnumber).withRole(response.role)
.withCustomData(response.customData).build();
.withCustomData(response.customData)
.withGuest(response.guest.toUpperCase() == "TRUE").build();
MeetingModel.getInstance().meeting = new MeetingBuilder(response.conference, response.conferenceName)
.withDefaultLayout(response.defaultLayout).withVoiceConf(response.voiceBridge)
@ -156,4 +158,4 @@ package org.bigbluebutton.main.model.users
return this.urlLoader;
}
}
}
}

View File

@ -31,7 +31,7 @@ package org.bigbluebutton.main.model.users
import org.bigbluebutton.main.events.InvalidAuthTokenEvent;
import org.bigbluebutton.main.model.ConferenceParameters;
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
public class NetConnectionDelegate
{
@ -52,6 +52,7 @@ package org.bigbluebutton.main.model.users
private var _room:String;
private var tried_tunneling:Boolean = false;
private var logoutOnUserCommand:Boolean = false;
private var guestKickedOutCommand:Boolean = false;
private var backoff:Number = 2000;
private var dispatcher:Dispatcher;
@ -199,7 +200,8 @@ package org.bigbluebutton.main.model.users
_conferenceParameters.room, _conferenceParameters.voicebridge,
_conferenceParameters.record, _conferenceParameters.externUserID,
_conferenceParameters.internalUserID, _conferenceParameters.lockOnStart,
_conferenceParameters.muteOnStart, _conferenceParameters.lockSettings);
_conferenceParameters.muteOnStart, _conferenceParameters.lockSettings,
_conferenceParameters.guest);
} catch(e:ArgumentError) {
// Invalid parameters.
switch (e.errorID) {
@ -217,12 +219,17 @@ package org.bigbluebutton.main.model.users
this.logoutOnUserCommand = logoutOnUserCommand;
_netConnection.close();
}
public function forceClose():void {
_netConnection.close();
}
public function guestDisconnect() : void
{
this.guestKickedOutCommand = true;
_netConnection.close();
}
public function forceClose():void {
_netConnection.close();
}
protected function netStatus(event:NetStatusEvent):void {
handleResult( event );
}
@ -332,11 +339,16 @@ package org.bigbluebutton.main.model.users
}
private function sendConnectionFailedEvent(reason:String):void{
if (this.guestKickedOutCommand) {
sendGuestUserKickedOutEvent();
return;
}
if (this.logoutOnUserCommand){
sendUserLoggedOutEvent();
return;
}
var e:ConnectionFailedEvent = new ConnectionFailedEvent(reason);
dispatcher.dispatchEvent(e);
@ -347,6 +359,11 @@ package org.bigbluebutton.main.model.users
var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT);
dispatcher.dispatchEvent(e);
}
private function sendGuestUserKickedOutEvent():void {
var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.GUEST_KICKED_OUT);
dispatcher.dispatchEvent(e);
}
private function attemptReconnect(backoff:Number):void{
var retryTimer:Timer = new Timer(backoff, 1);

View File

@ -36,11 +36,14 @@ package org.bigbluebutton.main.model.users
import org.bigbluebutton.core.managers.ConnectionManager;
import org.bigbluebutton.core.managers.UserConfigManager;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.model.Config;
import org.bigbluebutton.core.model.MeetingModel;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.core.model.Config
import org.bigbluebutton.common.Role;
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.main.events.WaitModeratorEvent;
import org.bigbluebutton.main.events.UserServicesEvent;
import org.bigbluebutton.main.events.ResponseModeratorEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.model.ConferenceParameters;
import org.bigbluebutton.main.model.users.events.BroadcastStartedEvent;
import org.bigbluebutton.main.model.users.events.BroadcastStoppedEvent;
@ -88,6 +91,7 @@ package org.bigbluebutton.main.model.users
UserManager.getInstance().getConference().setMyName(result.username);
UserManager.getInstance().getConference().setMyRole(result.role);
UserManager.getInstance().getConference().setMyRoom(result.room);
UserManager.getInstance().getConference().setGuest(result.guest == "true");
UserManager.getInstance().getConference().setMyAuthToken(result.authToken);
UserManager.getInstance().getConference().setMyCustomData(result.customdata);
UserManager.getInstance().getConference().setDefaultLayout(result.defaultLayout);
@ -110,6 +114,7 @@ package org.bigbluebutton.main.model.users
_conferenceParameters.externMeetingID = result.externMeetingID;
_conferenceParameters.conference = result.conference;
_conferenceParameters.username = result.username;
_conferenceParameters.guest = (result.guest.toUpperCase() == "TRUE");
_conferenceParameters.role = result.role;
_conferenceParameters.room = result.room;
_conferenceParameters.webvoiceconf = result.webvoiceconf;
@ -189,12 +194,47 @@ package org.bigbluebutton.main.model.users
sender.queryForParticipants();
sender.queryForRecordingStatus();
sender.queryForGuestPolicy();
if(UsersUtil.amIGuest() == false) {
var loadCommand:SuccessfulLoginEvent = new SuccessfulLoginEvent(SuccessfulLoginEvent.USER_LOGGED_IN);
loadCommand.conferenceParameters = _conferenceParameters;
dispatcher.dispatchEvent(loadCommand);
}
}
public function askToAccept():void {
UserManager.getInstance().getConference().setWaitForModerator(true);
var guestCommand:WaitModeratorEvent = new WaitModeratorEvent(WaitModeratorEvent.USER_LOGGED_IN);
guestCommand.conferenceParameters = _conferenceParameters;
dispatcher.dispatchEvent(guestCommand);
}
public function acceptGuest():void {
var loadCommand:SuccessfulLoginEvent = new SuccessfulLoginEvent(SuccessfulLoginEvent.USER_LOGGED_IN);
loadCommand.conferenceParameters = _conferenceParameters;
dispatcher.dispatchEvent(loadCommand);
dispatcher.dispatchEvent(loadCommand);
}
public function denyGuest():void {
dispatcher.dispatchEvent(new LogoutEvent(LogoutEvent.GUEST_KICKED_OUT));
}
public function newGuestPolicy(event:BBBEvent):void {
sender.setGuestPolicy(event.payload['guestPolicy']);
}
public function getAllGuests(e:SuccessfulLoginEvent):void {
if(UserManager.getInstance().getConference().amIModerator()) {
sender.queryForGuestsWaiting();
}
}
public function guestDisconnect():void {
_connectionManager.guestDisconnect();
}
public function isModerator():Boolean {
return UserManager.getInstance().getConference().amIModerator();
}
@ -214,7 +254,23 @@ package org.bigbluebutton.main.model.users
public function raiseHand(e:RaiseHandEvent):void {
sender.raiseHand(UserManager.getInstance().getConference().getMyUserId(), e.raised);
}
public function askToEnter(e:WaitModeratorEvent):void {
sender.askToEnter();
}
public function responseToGuest(e:ResponseModeratorEvent):void {
sender.responseToGuest(e.userid, e.resp);
}
public function responseToAllGuests(e:ResponseModeratorEvent):void {
sender.responseToAllGuests(e.resp);
}
public function kickGuest(e:BBBEvent):void {
sender.kickGuest(e.payload.userId);
}
public function lowerHand(e:LowerHandEvent):void {
if (this.isModerator()) sender.raiseHand(e.userid, false);
}

View File

@ -30,10 +30,11 @@ package org.bigbluebutton.main.model.users.events
public static const CONNECTION_REJECTED:String = "connectionRejected";
public static const ASYNC_ERROR:String = "asyncError";
public static const USER_LOGGED_OUT:String = "userHasLoggedOut";
public static const GUEST_KICKED_OUT:String = "guestKickedOut";
public function ConnectionFailedEvent(type:String)
{
super(type, true, false);
}
}
}
}

View File

@ -0,0 +1,36 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 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 2.1 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.users.events
{
import flash.events.Event;
import flash.net.NetConnection;
public class GuestConnectionEvent extends Event
{
public static const GUEST_CONNECTION:String = "guestConnection";
public var connection:NetConnection;
public var userid:Number;
public function UsersConnectionEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -25,10 +25,12 @@ package org.bigbluebutton.main.model.users.events
{
public static const CONNECTION_SUCCESS:String = "usersConnectionSuccess";
public var userid:String;
public var connection:NetConnection;
public var userid:String;
public var guest:Boolean;
public function UsersConnectionEvent(type:String) {
super(type, true, false);
}
}
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
showCloseButton="false"
xmlns:mate="http://mate.asfusion.com/"
minWidth="250"
creationComplete="init()"
title="{ResourceUtil.getInstance().getString('bbb.settings.title')}" >
<mx:Script>
<![CDATA[
import mx.events.ItemClickEvent;
import mx.managers.PopUpManager;
import mx.core.UIComponent;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.common.events.SettingsComponentEvent;
private function init():void {
this.x = (this.parent.width - this.width) / 2;
this.y = (this.parent.height - this.height) / 2;
}
public function pushComponents(components:Array):void {
for (var i:int = 0; i < components.length; ++i) {
addedComponents.addChildAt(components[i] as UIComponent, 0);
}
}
private function onCancelClicked():void {
var event:BBBEvent = new BBBEvent(BBBEvent.SETTINGS_CANCELLED);
dispatchEvent(event);
close();
}
private function onOkClicked():void {
var event:BBBEvent = new BBBEvent(BBBEvent.SETTINGS_CONFIRMED);
dispatchEvent(event);
close();
}
private function close():void {
PopUpManager.removePopUp(this);
}
]]>
</mx:Script>
<mx:VBox id="addedComponents" height="100%" />
<mx:ControlBar width="100%" horizontalAlign="center">
<mx:Button id="okBtn" label="{ResourceUtil.getInstance().getString('bbb.settings.ok')}" width="100" click="onOkClicked()"/>
<mx:Spacer width="10"/>
<mx:Button id="cancelBtn" label="{ResourceUtil.getInstance().getString('bbb.settings.cancel')}" width="100" click="onCancelClicked()"/>
</mx:ControlBar>
</mx:TitleWindow>

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org
Copyright (c) 2010 BigBlueButton Inc. and by respective authors (see below).
BigBlueButton 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 2.1 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/>.
$Id: $
-->
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
verticalAlign="middle" width="100%" >
<mx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.ResponseModeratorEvent;
import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import mx.containers.HBox;
import mx.controls.Button;
import mx.controls.Spacer;
import org.bigbluebutton.main.events.BBBEvent;
private var dispatcher:Dispatcher = new Dispatcher();
private var images:Images = new Images();
[Bindable] public var acceptUserIcon:Class = images.accept_user;
[Bindable] public var rejectUserIcon:Class = images.cancel_user;
[Bindable] private var username:String = "";
private var userid:String;
public function setUser(username:String, userid:String):void {
this.username = username;
this.userid = userid;
}
private function onRejectUserBtnClick():void {
sendResponseToServer(false);
}
private function onAcceptUserBtnClick():void {
sendResponseToServer(true);
}
private function sendResponseToServer(accept:Boolean):void {
var respCommand:ResponseModeratorEvent = new ResponseModeratorEvent(ResponseModeratorEvent.RESPONSE);
respCommand.userid = userid;
respCommand.resp = accept;
dispatcher.dispatchEvent(respCommand);
}
]]>
</mx:Script>
<mx:Label text="{username}" maxWidth="150" />
<mx:Spacer width="100%" />
<mx:Button icon="{rejectUserIcon}" toolTip="{ResourceUtil.getInstance().getString('bbb.guests.denyBtn.toolTip')}" click="onRejectUserBtnClick()" />
<mx:Button icon="{acceptUserIcon}" toolTip="{ResourceUtil.getInstance().getString('bbb.guests.allowBtn.toolTip')}" click="onAcceptUserBtnClick()" />
</mx:HBox>

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
width="400" >
<mate:Listener type="{BBBEvent.RETRIEVE_GUEST_POLICY}" method="refreshGuestPolicy"/>
<mate:Listener type="{BBBEvent.SETTINGS_CONFIRMED}" method="onOkClicked"/>
<mate:Listener type="{BBBEvent.SETTINGS_CANCELLED}" method="onCancelClicked"/>
<mx:Script>
<![CDATA[
import mx.events.ItemClickEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.common.events.SettingsComponentEvent;
import com.asfusion.mate.events.Dispatcher;
private var option:Number = 0;
private var guestPolicy:String;
private function refreshGuestPolicy(event:BBBEvent):void {
setGuestPolicy(event.payload.guestPolicy);
}
public function setGuestPolicy(guestPolicy:String):void {
this.guestPolicy = guestPolicy;
if(guestPolicy == "ASK_MODERATOR") {
guestManagement.selectedValue = 0;
option = 0;
} else if(guestPolicy == "ALWAYS_ACCEPT") {
guestManagement.selectedValue = 1;
option = 1;
} else {
guestManagement.selectedValue = 2;
option = 2;
}
}
public function addToSettings():void {
var addGuestManagement:SettingsComponentEvent = new SettingsComponentEvent(SettingsComponentEvent.ADD);
addGuestManagement.component = this;
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(addGuestManagement);
}
private function onCancelClicked(e:Event = null):void {
setGuestPolicy(guestPolicy);
}
private function handleGuestClick(event:ItemClickEvent):void {
option = event.currentTarget.selectedValue;
}
private function onOkClicked(e:Event = null):void {
var event:BBBEvent = new BBBEvent(BBBEvent.BROADCAST_GUEST_POLICY);
if(option == 0) {
event.payload['guestPolicy'] = "ASK_MODERATOR";
dispatchEvent(event);
}
else if(option == 1) {
event.payload['guestPolicy'] = "ALWAYS_ACCEPT";
dispatchEvent(event);
dispatchEvent(new BBBEvent(BBBEvent.ACCEPT_ALL_WAITING_GUESTS));
}
else {
event.payload['guestPolicy'] = "ALWAYS_DENY";
dispatchEvent(event);
dispatchEvent(new BBBEvent(BBBEvent.DENY_ALL_WAITING_GUESTS));
}
LogUtil.debug("SENDING TO SERVER POLICY");
}
]]>
</mx:Script>
<mx:VBox width="30%">
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.guests.Management')}"/>
</mx:VBox>
<mx:Spacer width="30" />
<mx:VBox width="70%">
<mx:RadioButtonGroup id="guestManagement" itemClick="handleGuestClick(event);"/>
<mx:RadioButton groupName="guestManagement"
id="askModerator"
label="{ResourceUtil.getInstance().getString('bbb.guests.askModerator')}"
value="0"
/>
<mx:RadioButton groupName="guestManagement"
id="alwaysAccept"
label="{ResourceUtil.getInstance().getString('bbb.guests.alwaysAccept')}"
value="1"
/>
<mx:RadioButton groupName="guestManagement"
id="AlwaysDeny"
label="{ResourceUtil.getInstance().getString('bbb.guests.alwaysDeny')}"
value="2"
/>
</mx:VBox>
</mx:HBox>

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org
Copyright (c) 2010 BigBlueButton Inc. and by respective authors (see below).
BigBlueButton 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 2.1 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/>.
$Id: $
-->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
title="{ResourceUtil.getInstance().getString('bbb.guests.title')}" showCloseButton="false" creationComplete="init()"
x="0" y="0" layout="vertical" width="320" horizontalAlign="center"
xmlns:mate="http://mate.asfusion.com/" >
<mate:Listener type="{BBBEvent.ACCEPT_ALL_WAITING_GUESTS}" method="acceptAllWaitingGuests" />
<mate:Listener type="{BBBEvent.DENY_ALL_WAITING_GUESTS}" method="denyAllWaitingGuests" />
<mate:Listener type="{RemoveGuestFromViewEvent.REMOVE_GUEST}" receive="{remove(event.userid)}" />
<mx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.main.events.RemoveGuestEvent;
import org.bigbluebutton.main.events.ResponseModeratorEvent;
import org.bigbluebutton.main.events.RemoveGuestFromViewEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import mx.containers.HBox;
import mx.controls.Button;
import mx.controls.Spacer;
import mx.events.CloseEvent;
import org.bigbluebutton.main.events.BBBEvent;
private var guestButtons:Object = new Object();
[Bindable] private var numberOfGuests:Number = 0;
private var dispatcher:Dispatcher = new Dispatcher();
public function init():void {
//Uncomment this line to make titlewindow undraggable
//this.isPopUp = false;
}
public function refreshGuestView(listOfGuests:Object):void {
for (var userid:String in listOfGuests) {
if(guestButtons[userid] == null) {
var guestItem:GuestItem = new GuestItem();
guestItem.setUser(listOfGuests[userid], userid);
guestListBox.addChild(guestItem);
guestButtons[userid] = guestItem;
numberOfGuests++;
}
}
this.visible = true;
}
public function sendResponseToAllGuests(resp:Boolean):void {
removeAllGuests();
var respCommand:ResponseModeratorEvent = new ResponseModeratorEvent(ResponseModeratorEvent.RESPONSE_ALL);
respCommand.resp = resp;
dispatcher.dispatchEvent(respCommand);
}
public function sendResponseToAllGuestsCheckBox(resp:Boolean):void {
if(rememberCheckBox.selected) {
var event:BBBEvent = new BBBEvent(BBBEvent.BROADCAST_GUEST_POLICY);
if (resp) {
event.payload['guestPolicy'] = "ALWAYS_ACCEPT";
} else {
event.payload['guestPolicy'] = "ALWAYS_DENY";
}
dispatcher.dispatchEvent(event);
}
sendResponseToAllGuests(resp);
}
public function acceptAllWaitingGuests(event:BBBEvent):void {
sendResponseToAllGuests(true);
}
public function denyAllWaitingGuests(event:BBBEvent):void {
sendResponseToAllGuests(false);
}
public function removeAllGuests():void {
var removeGuestEvent:RemoveGuestEvent = new RemoveGuestEvent(RemoveGuestEvent.REMOVE_ALL);
dispatcher.dispatchEvent(removeGuestEvent);
closeWindow();
}
public function remove(userid:String):void {
if (guestButtons[userid] != null) {
numberOfGuests = numberOfGuests - 1;
guestListBox.removeChild(guestButtons[userid]);
delete guestButtons[userid];
var removeGuestEvent:RemoveGuestEvent = new RemoveGuestEvent();
removeGuestEvent.userid = userid;
dispatcher.dispatchEvent(removeGuestEvent);
if (!hasGuest()) {
closeWindow();
}
}
}
public function hasGuest():Boolean {
return numberOfGuests > 0;
}
public function closeWindow():void {
this.visible = false;
PopUpManager.removePopUp(this);
dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
}
]]>
</mx:Script>
<mx:Label text="{numberOfGuests > 1? ResourceUtil.getInstance().getString('bbb.guests.message.plural', [String(numberOfGuests)]): ResourceUtil.getInstance().getString('bbb.guests.message.singular', [String(numberOfGuests)])}"/>
<mx:HRule width="100%"/>
<mx:Button id="allowEveryoneBtn" label="{ResourceUtil.getInstance().getString('bbb.guests.allowEveryoneBtn.text')}" width="70%" click="sendResponseToAllGuestsCheckBox(true)" toolTip="{allowEveryoneBtn.label}"/>
<mx:Button id="denyEveryoneBtn" label="{ResourceUtil.getInstance().getString('bbb.guests.denyEveryoneBtn.text')}" width="70%" click="sendResponseToAllGuestsCheckBox(false)" toolTip="{denyEveryoneBtn.label}"/>
<mx:CheckBox id="rememberCheckBox" label="{ResourceUtil.getInstance().getString('bbb.guests.rememberAction.text')}"/>
<mx:HRule width="100%"/>
<mx:VBox id="guestListBox" width="100%" height="100%" maxHeight="200" paddingLeft="10" paddingRight="10" paddingBottom="2" />
</mx:TitleWindow>

View File

@ -55,6 +55,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
this.label = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loading', [numModules]);
this.visible = true;
}
private function moduleLoadProgress(e:ModuleLoadEvent):void{

View File

@ -27,6 +27,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.core.BBB;
@ -34,6 +35,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOG:String = "Main::LoggedOutWindow - ";
[Bindable] private var DISPLAY_MESSAGE_ONLY_STATE:String = "displayMessageOnlyState";
[Bindable] private var DISPLAY_RECONNECT_BUTTON_STATE:String = "displayReconnectButton";
[Bindable] private var message:String = "You have logged out of the conference";
private var urlLoader:URLLoader;
@ -83,29 +87,42 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
switch(reason){
case ConnectionFailedEvent.APP_SHUTDOWN:
message = ResourceUtil.getInstance().getString('bbb.logout.appshutdown');
setCurrentState(DISPLAY_MESSAGE_ONLY_STATE);
break;
case ConnectionFailedEvent.ASYNC_ERROR:
message = ResourceUtil.getInstance().getString('bbb.logout.asyncerror');
setCurrentState(DISPLAY_RECONNECT_BUTTON_STATE);
break;
case ConnectionFailedEvent.CONNECTION_CLOSED:
message = ResourceUtil.getInstance().getString('bbb.logout.connectionclosed');
setCurrentState(DISPLAY_RECONNECT_BUTTON_STATE);
break;
case ConnectionFailedEvent.CONNECTION_FAILED:
message = ResourceUtil.getInstance().getString('bbb.logout.connectionfailed');
setCurrentState(DISPLAY_RECONNECT_BUTTON_STATE);
break;
case ConnectionFailedEvent.CONNECTION_REJECTED:
message = ResourceUtil.getInstance().getString('bbb.logout.rejected');
setCurrentState(DISPLAY_RECONNECT_BUTTON_STATE);
break;
case ConnectionFailedEvent.INVALID_APP:
message = ResourceUtil.getInstance().getString('bbb.logout.invalidapp');
setCurrentState(DISPLAY_MESSAGE_ONLY_STATE);
break;
case ConnectionFailedEvent.UNKNOWN_REASON:
message = ResourceUtil.getInstance().getString('bbb.logout.unknown');
setCurrentState(DISPLAY_RECONNECT_BUTTON_STATE);
break;
case ConnectionFailedEvent.USER_LOGGED_OUT:
message = ResourceUtil.getInstance().getString('bbb.logout.usercommand');
setCurrentState(DISPLAY_MESSAGE_ONLY_STATE);
redirect(); // we know that the disconnect was requested so automatically redirect
break;
case ConnectionFailedEvent.GUEST_KICKED_OUT:
message = ResourceUtil.getInstance().getString('bbb.logout.guestkickedout');
setCurrentState(DISPLAY_MESSAGE_ONLY_STATE);
// setCurrentState(DISPLAY_RECONNECT_BUTTON_STATE);
break;
}
}
@ -114,11 +131,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%" horizontalAlign="center">
<mx:states>
<mx:State name="{DISPLAY_MESSAGE_ONLY_STATE}">
<mx:SetProperty target="{this}" name="height" value="{110}"/>
</mx:State>
<mx:State name="{DISPLAY_RECONNECT_BUTTON_STATE}">
<mx:AddChild relativeTo="okBtn" position="after">
<mx:VBox id="reconnectDialog" width="100%" height="100%" horizontalAlign="center">
<mx:HRule width="100%"/>
<mx:Text width="380" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.logout.refresh.message')}" />
<mx:Button id="reconnectBtn" label="{ResourceUtil.getInstance().getString('bbb.logout.refresh.label')}" click="reconnect()" />
</mx:VBox>
</mx:AddChild>
</mx:State>
</mx:states>
<mx:VBox id="mainContainer" width="100%" height="100%" horizontalAlign="center">
<mx:Text text="{message}"/>
<mx:Button id="okBtn" label="{ResourceUtil.getInstance().getString('bbb.logout.button.label')}" click="redirect()"/>
<mx:HRule width="100%" />
<mx:Text width="380" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.logout.refresh.message')}" />
<mx:Button id="reconnectBtn" label="{ResourceUtil.getInstance().getString('bbb.logout.refresh.label')}" click="reconnect()" />
</mx:VBox>
</mx:TitleWindow>
</mx:TitleWindow>

View File

@ -33,7 +33,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{OpenWindowEvent.OPEN_WINDOW_EVENT}" method="handleOpenWindowEvent" />
<mate:Listener type="{CloseWindowEvent.CLOSE_WINDOW_EVENT}" method="handleCloseWindowEvent"/>
<mate:Listener type="{AddUIComponentToMainCanvas.ADD_COMPONENT}" method="addComponentToCanvas" />
<mate:Listener type="{AddUIComponentToMainCanvas.ADD_COMPONENT}" method="addComponentToCanvas" />
<mate:Listener type="{AppVersionEvent.APP_VERSION_EVENT}" method="handleApplicationVersionEvent" />
<mate:Listener type="{MeetingNotFoundEvent.MEETING_NOT_FOUND}" method="handleMeetingNotFoundEvent" />
<mate:Listener type="{ConnectionFailedEvent.USER_LOGGED_OUT}" method="handleLogout" />
@ -58,6 +58,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{LockControlEvent.OPEN_LOCK_SETTINGS}" method="openLockSettingsWindow" />
<mate:Listener type="{InvalidAuthTokenEvent.INVALID_AUTH_TOKEN}" method="handleInvalidAuthToken" />
<mate:Listener type="{BBBEvent.RETRIEVE_GUEST_POLICY}" method="setGuestPolicy"/>
<mate:Listener type="{ConnectionFailedEvent.GUEST_KICKED_OUT}" method="handleLogout" />
<mate:Listener type="{ModeratorRespEvent.GUEST_ALLOWED}" method="guestAllowed" />
<mate:Listener type="{RefreshGuestEvent.REFRESH_GUEST_VIEW}" method="refreshGuestView" />
<mate:Listener type="{RemoveGuestRequestEvent.GUEST_EVENT}" method="removeGuestWindow" />
<mate:Listener type="{WaitModeratorEvent.USER_LOGGED_IN}" method="openWaitWindow" />
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
@ -84,6 +91,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.common.events.AddUIComponentToMainCanvas;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.common.events.SettingsComponentEvent;
import org.bigbluebutton.common.events.ToolbarButtonEvent;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.events.LockControlEvent;
@ -96,10 +104,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.main.events.InvalidAuthTokenEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.events.MeetingNotFoundEvent;
import org.bigbluebutton.main.events.ModeratorRespEvent;
import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.main.events.PortTestEvent;
import org.bigbluebutton.main.events.RefreshGuestEvent;
import org.bigbluebutton.main.events.RemoveGuestRequestEvent;
import org.bigbluebutton.main.events.ShortcutEvent;
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.main.events.WaitModeratorEvent;
import org.bigbluebutton.main.model.Guest;
import org.bigbluebutton.main.model.LayoutOptions;
import org.bigbluebutton.main.model.users.Conference;
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
@ -121,9 +134,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private var images:Images = new Images();
private var stoppedModules:ArrayCollection;
private var logs:Logger = new Logger();
private var logWindow:LogWindow;
private var scWindow:ShortcutHelpWindow;
private var logoutWindow:LoggedOutWindow;
private var waitWindow:WaitingWindow = null;
private var guestWindow:GuestWindow = null;
private var scWindow:ShortcutHelpWindow;
private var logoutWindow:LoggedOutWindow;
private var connectionLostWindow:ConnectionLostWindow;
[Bindable] private var baseIndex:int = 100000;
@ -141,14 +157,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private var receivedConfigLocaleVer:Boolean = false;
private var receivedResourceLocaleVer:Boolean = false;
public function get mode():String {
return _mode;
}
[Bindable] private var layoutOptions:LayoutOptions;
[Bindable] private var showToolbarOpt:Boolean = true;
private var guestManagement:GuestManagement = null;
private var guest:Guest = new Guest();
private var guestPolicy:String = "ASK_MODERATOR";
public function get mode():String {
return _mode;
}
[Bindable] private var layoutOptions:LayoutOptions;
[Bindable] private var showToolbarOpt:Boolean = true;
[Bindable] private var toolbarHeight:Number = 32;
[Bindable] private var toolbarPaddingTop:Number = 4;
[Bindable] private var showFooterOpt:Boolean = true;
@ -188,6 +207,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
copyrightLabel2.addEventListener(FlexEvent.UPDATE_COMPLETE, updateCopyrightLabelDimensions);
updateCopyrightLabelDimensions();
}
private function setGuestPolicy(event:BBBEvent):void {
guestPolicy = event.payload.guestPolicy;
if(guestManagement == null) {
LogUtil.debug("ADD Guest Event");
guestManagement = new GuestManagement();
guestManagement.setGuestPolicy(guestPolicy);
guestManagement.addToSettings();
}
}
private function updateCopyrightLabelDimensions(e:Event = null):void {
var screenRect:Rectangle = systemManager.screen;
@ -224,11 +253,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
trace("Comparing locale versions.");
if (!event.suppressLocaleWarning) checkLocaleVersion(localeVersion);
if (sendStartModulesEvent) {
sendStartModulesEvent = false;
sendStartAllModulesEvent();
}
}
sendStartModulesEvent = false;
sendStartAllModulesEvent();
}
}
}
public function sendStartAllModulesEvent():void{
@ -236,29 +265,68 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new ModuleLoadEvent(ModuleLoadEvent.START_ALL_MODULES));
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
LogUtil.debug("Switching to full screen");
/* Do something specific here if we switched to full screen mode. */
} else {
LogUtil.debug("Switching to normal screen");
/* Do something specific here if we switched to normal mode. */
public function guestAllowed(evt:ModeratorRespEvent):void {
progressBar.visible = true;
waitWindow.guestAllowed();
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
LogUtil.debug("Switching to full screen");
/* Do something specific here if we switched to full screen mode. */
} else {
LogUtil.debug("Switching to normal screen");
/* Do something specific here if we switched to normal mode. */
}
}
private function closeGuestWindow(e:Event):void {
if(guestWindow != null) {
guestWindow.closeWindow();
guestWindow = null;
}
}
private function refreshGuestView(evt:RefreshGuestEvent):void {
LogUtil.debug("REFRESH GUEST");
if(guestWindow == null) {
guestWindow = PopUpManager.createPopUp( mdiCanvas, GuestWindow, false) as GuestWindow;
guestWindow.addEventListener(Event.CLOSE, closeGuestWindow);
guestWindow.x = systemManager.screen.width - guestWindow.width - 20;
guestWindow.y = 20;
}
guestWindow.refreshGuestView(evt.listOfGuests);
}
public function removeGuestWindow(evt:RemoveGuestRequestEvent):void {
if(guestWindow != null)
guestWindow.remove(evt.userid);
}
private function openWaitWindow(evt:WaitModeratorEvent):void {
progressBar.visible = false;
waitWindow = PopUpManager.createPopUp( mdiCanvas, WaitingWindow, false) as WaitingWindow;
waitWindow.conferenceParameters = evt.conferenceParameters;
// Calculate position of TitleWindow in Application's coordinates.
waitWindow.x = (systemManager.screen.width - waitWindow.width) / 2;
waitWindow.y = (systemManager.screen.height - waitWindow.height) / 2;
}
private function openLogWindow():void {
if (logWindow == null){
logWindow = new LogWindow();
logWindow.logs = logs;
}
mdiCanvas.windowManager.add(logWindow);
mdiCanvas.windowManager.absPos(logWindow, 50, 50);
logWindow.width = mdiCanvas.width - 100;
logWindow.height = mdiCanvas.height - 100;
}
private function openLogWindow():void {
if (logWindow == null){
logWindow = new LogWindow();
logWindow.logs = logs;
}
mdiCanvas.windowManager.add(logWindow);
mdiCanvas.windowManager.absPos(logWindow, 50, 50);
logWindow.width = mdiCanvas.width - 100;
logWindow.height = mdiCanvas.height - 100;
}
public function openShortcutHelpWindow(e:Event = null):void{
if (scWindow == null) {
@ -539,13 +607,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
return logoutUrl;
}
private function handleLogout(e:ConnectionFailedEvent):void {
private function handleLogout(e:ConnectionFailedEvent):void {
if(progressBar != null)
progressBar.visible = false;
if(waitWindow != null)
waitWindow.removeWindow();
if(guestWindow != null) {
guestWindow.closeWindow();
}
if (e is ConnectionFailedEvent) {
showlogoutWindow((e as ConnectionFailedEvent).type);
}
else showlogoutWindow("You have logged out of the conference");
}
}
private function redirectToLogoutUrl ():void {
var logoutURL:String = getLogoutUrl();
var request:URLRequest = new URLRequest(logoutURL);
@ -660,7 +738,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<views:LoadingBar id="progressBar" horizontalCenter="0" verticalCenter="0" width="50%" />
<views:BrandingLogo x="{this.width - 300}" y="{this.height - 300}" />
</views:MainCanvas>
<mx:ControlBar width="100%" height="{footerHeight}" paddingTop="0" id="controlBar">
<mx:Label
htmlText="{ResourceUtil.getInstance().getString('bbb.mainshell.copyrightLabel2',[appVersion])}"

View File

@ -37,28 +37,39 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{ShortcutEvent.FOCUS_SHORTCUT_BUTTON}" method="focusShortcutButton" />
<mate:Listener type="{ShortcutEvent.FOCUS_LOGOUT_BUTTON}" method="focusLogoutButton" />
<mate:Listener type="{ConferenceCreatedEvent.CONFERENCE_CREATED_EVENT}" method="retrieveMeetingName" />
<mate:Listener type="{ConnectionFailedEvent.GUEST_KICKED_OUT}" method="hideToolbar" />
<mate:Listener type="{SettingsComponentEvent.ADD}" method="addSettingsComponent" />
<mate:Listener type="{SettingsComponentEvent.REMOVE}" method="removeSettingsComponent"/>
<mate:Listener type="{BBBEvent.CHANGE_RECORDING_STATUS}" method="onRecordingStatusChanged" />
<mate:Listener type="{WaitModeratorEvent.USER_LOGGED_IN}" method="refreshSettingsBtn" />
<mate:Listener type="{ModeratorRespEvent.GUEST_ALLOWED}" method="refreshSettingsBtn" />
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.accessibility.AlertAccImpl;
import mx.controls.Alert;
import mx.core.UIComponent;
import mx.events.CloseEvent;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.IBbbToolbarComponent;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.common.events.ToolbarButtonEvent;
import org.bigbluebutton.common.events.SettingsComponentEvent;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.services.BandwidthMonitor;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.ConfigEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.events.ModeratorRespEvent;
import org.bigbluebutton.main.events.SettingsEvent;
import org.bigbluebutton.main.events.ShortcutEvent;
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.main.events.WaitModeratorEvent;
import org.bigbluebutton.main.model.LayoutOptions;
import org.bigbluebutton.main.model.users.events.ConferenceCreatedEvent;
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
@ -71,7 +82,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
[Bindable] private var showHelpBtn:Boolean = false;
[Bindable] private var showToolbar:Boolean = false;
[Bindable] public var toolbarOptions:LayoutOptions = new LayoutOptions();
[Bindable] private var showConfigurationsButton:Boolean = false;
[Bindable] public var toolbarOptions:LayoutOptions = new LayoutOptions();
[Bindable] private var baseIndex:int;
[Bindable] private var numButtons:int;
@ -84,7 +96,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*/
private var xml:XML;
private var settingsComponents:Array = new Array();
private var settingsPopup:BBBSettings = null;
private function init():void{
if (Capabilities.hasAccessibility) {
AlertAccImpl.enableAccessibility();
@ -98,6 +112,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
timer.addEventListener(TimerEvent.TIMER, checkAccessiblity);
timer.start();
}
private function onCreationComplete():void {
@ -152,16 +168,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
showHelpBtn = false;
}
}
private function retrieveMeetingName(e:ConferenceCreatedEvent):void {
if (toolbarOptions.showMeetingName) {
var meetingTitle:String = BBB.initUserConfigManager().getMeetingTitle();
var meetingTitle:String = BBB.initUserConfigManager().getMeetingTitle();
if (meetingTitle != null) {
meetingNameLbl.text = meetingTitle;
}
}
}
// need to put it here because on init() the conference object
// still doesn't have the updated information
refreshSettingsBtn(null);
}
private function refreshSettingsBtn(e:*):void {
showConfigurationsButton = UsersUtil.amIModerator() && !UsersUtil.amIWaitForModerator();
}
public function addButton(name:String):Button{
var btn:Button = new Button();
btn.id = name;
@ -334,6 +357,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
}
private function addSettingsComponent(e:SettingsComponentEvent = null):void {
settingsComponents.push(e.component);
}
private function removeSettingsComponent(e:SettingsComponentEvent = null):void {
throw("Not implemented");
}
private function onSettingsButtonClick():void {
settingsPopup = BBBSettings(PopUpManager.createPopUp(this.parent, BBBSettings, true));
settingsPopup.pushComponents(settingsComponents);
}
]]>
</mx:Script>
@ -359,6 +395,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Label id="meetingNameLbl" styleName="meetingNameLabelStyle" />
<mx:Spacer width="50%"/>
<mx:Button
id="bbbSettings"
visible="{showConfigurationsButton}"
includeInLayout="{showConfigurationsButton}"
toolTip="{ResourceUtil.getInstance().getString('bbb.settings.btn.toolTip')}"
click="onSettingsButtonClick()"
styleName="settingsButtonStyle"
height="22"
/>
<!--
<mx:Button label="DISCONNECT!" click="BBB.initConnectionManager().forceClose()" height="22" toolTip="Click to simulate disconnection" />
-->

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org
Copyright (c) 2010 BigBlueButton Inc. and by respective authors (see below).
BigBlueButton 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 2.1 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/>.
$Id: $
-->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
title="{ResourceUtil.getInstance().getString('bbb.waitWindow.waitMessage.title')}" showCloseButton="false"
layout="vertical" width="350" horizontalAlign="center">
<mx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.main.model.ConferenceParameters;
public var conferenceParameters:ConferenceParameters;
private var urlLoader:URLLoader;
public function guestAllowed():void {
var dispatcher:Dispatcher = new Dispatcher();
var loadCommand:SuccessfulLoginEvent = new SuccessfulLoginEvent(SuccessfulLoginEvent.USER_LOGGED_IN);
loadCommand.conferenceParameters = conferenceParameters;
dispatcher.dispatchEvent(loadCommand);
PopUpManager.removePopUp(this);
}
public function removeWindow():void {
PopUpManager.removePopUp(this);
}
]]>
</mx:Script>
<mx:Text text="{ResourceUtil.getInstance().getString('bbb.waitWindow.waitMessage.message')}" width="100%" textAlign="center" />
</mx:TitleWindow>

View File

@ -28,7 +28,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.core.events.VoiceConfEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.LogoutEvent;
<!--TODO: Move guest events to user events? -->
import org.bigbluebutton.main.events.AddGuestEvent;
import org.bigbluebutton.main.events.RemoveGuestRequestEvent;
import org.bigbluebutton.main.events.ResponseModeratorEvent;
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
import org.bigbluebutton.main.events.UserServicesEvent;
import org.bigbluebutton.main.events.WaitModeratorEvent;
import org.bigbluebutton.main.model.GuestManager;
import org.bigbluebutton.main.model.users.UserService;
import org.bigbluebutton.main.model.users.events.BroadcastStartedEvent;
import org.bigbluebutton.main.model.users.events.BroadcastStoppedEvent;
@ -43,6 +50,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<EventHandlers type="{FlexEvent.APPLICATION_COMPLETE}" >
<ObjectBuilder generator="{UserService}" cache="global" />
<ObjectBuilder generator="{GuestManager}" cache="global" />
</EventHandlers>
<EventHandlers type="{LogoutEvent.USER_LOGGED_OUT}" >
@ -87,11 +95,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<MethodInvoker generator="{UserService}" method="changeRecordingStatus" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{KickUserEvent.KICK_USER}" >
<MethodInvoker generator="{UserService}" method="kickUser" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{VoiceConfEvent.EJECT_USER}" >
<MethodInvoker generator="{UserService}" method="ejectUser" arguments="{event}" />
</EventHandlers>
@ -140,4 +143,61 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<EventHandlers type="{RoleChangeEvent.ASSIGN_PRESENTER}">
<MethodInvoker generator="{UserService}" method="assignPresenter" arguments="{event}" />
</EventHandlers>
<!-- End Lock Events -->
<!-- Guest Events -->
<EventHandlers type="{SuccessfulLoginEvent.USER_LOGGED_IN}" >
<MethodInvoker generator="{UserService}" method="getAllGuests" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{AddGuestEvent.ADD_GUEST}" >
<MethodInvoker generator="{GuestManager}" method="addGuest" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{LogoutEvent.GUEST_KICKED_OUT}" >
<MethodInvoker generator="{UserService}" method="guestDisconnect" />
<MethodInvoker generator="{UserService}" method="logoutUser" />
</EventHandlers>
<EventHandlers type="LOAD_MODULE_GUEST_AUTO_ACCEPT">
<MethodInvoker generator="{UserService}" method="loadModulesCommand"/>
</EventHandlers>
<EventHandlers type="{WaitModeratorEvent.USER_LOGGED_IN}" >
<MethodInvoker generator="{UserService}" method="askToEnter" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{ResponseModeratorEvent.RESPONSE}" >
<MethodInvoker generator="{UserService}" method="responseToGuest" arguments="{event}" />
<MethodInvoker generator="{GuestManager}" method="removeGuest" arguments="{event.userid}" />
</EventHandlers>
<EventHandlers type="{RemoveGuestRequestEvent.GUEST_EVENT}" >
<MethodInvoker generator="{GuestManager}" method="removeGuest" arguments="{event.userid}" />
</EventHandlers>
<EventHandlers type="{ResponseModeratorEvent.RESPONSE_ALL}" >
<MethodInvoker generator="{UserService}" method="responseToAllGuests" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{BBBEvent.ASK_TO_ACCEPT_GUEST}" >
<MethodInvoker generator="{UserService}" method="askToAccept" />
</EventHandlers>
<EventHandlers type="{BBBEvent.ACCEPT_GUEST}" >
<MethodInvoker generator="{UserService}" method="acceptGuest" />
</EventHandlers>
<EventHandlers type="{BBBEvent.DENY_GUEST}" >
<MethodInvoker generator="{UserService}" method="denyGuest" />
</EventHandlers>
<EventHandlers type="{BBBEvent.BROADCAST_GUEST_POLICY}" >
<MethodInvoker generator="{UserService}" method="newGuestPolicy" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{BBBEvent.KICK_GUEST}" >
<MethodInvoker generator="{UserService}" method="kickGuest" arguments="{event}" />
</EventHandlers>
<!-- End Guest Events -->
</EventMap>

View File

@ -32,9 +32,13 @@ package org.bigbluebutton.modules.users.services
import org.bigbluebutton.core.services.UsersService;
import org.bigbluebutton.core.vo.LockSettings;
import org.bigbluebutton.core.vo.LockSettingsVO;
import org.bigbluebutton.main.events.AddGuestEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.main.events.ModeratorRespEvent;
import org.bigbluebutton.main.events.PresenterStatusEvent;
import org.bigbluebutton.main.events.RemoveGuestRequestEvent;
import org.bigbluebutton.main.events.SwitchedPresenterEvent;
import org.bigbluebutton.main.events.UserJoinedEvent;
import org.bigbluebutton.main.events.UserLeftEvent;
@ -133,6 +137,24 @@ package org.bigbluebutton.modules.users.services
case "permissionsSettingsChanged":
handlePermissionsSettingsChanged(message);
break;
case "user_requested_to_enter":
handleGuestRequestedToEnter(message);
break;
case "get_guest_policy_reply":
handleGetGuestPolicyReply(message);
break;
case "guest_policy_changed":
handleGuestPolicyChanged(message);
break;
case "get_guests_waiting_reply":
handleGetGuestsWaitingReply(message);
break;
case "response_to_guest":
handleResponseToGuest(message);
break;
case "guest_kicked":
handleGuestKicked(message);
break;
}
}
@ -360,19 +382,27 @@ package org.bigbluebutton.modules.users.services
UsersService.getInstance().userLeft(webUser);
if(webUser.guest) {
var e:RemoveGuestRequestEvent = new RemoveGuestRequestEvent(RemoveGuestRequestEvent.GUEST_EVENT);
e.userid = webUser.userId;
dispatcher.dispatchEvent(e);
}
var user:BBBUser = UserManager.getInstance().getConference().getUser(webUserId);
trace(LOG + "Notify others that user [" + user.userID + ", " + user.name + "] is leaving!!!!");
// Flag that the user is leaving the meeting so that apps (such as avatar) doesn't hang
// around when the user already left.
user.isLeavingFlag = true;
var joinEvent:UserLeftEvent = new UserLeftEvent(UserLeftEvent.LEFT);
joinEvent.userID = user.userID;
dispatcher.dispatchEvent(joinEvent);
UserManager.getInstance().getConference().removeUser(webUserId);
// If the user is null, it was a rejected guest
if(user != null) {
trace(LOG + "Notify others that user [" + user.userID + ", " + user.name + "] is leaving!!!!");
// Flag that the user is leaving the meeting so that apps (such as avatar) doesn't hang
// around when the user already left.
user.isLeavingFlag = true;
var joinEvent:UserLeftEvent = new UserLeftEvent(UserLeftEvent.LEFT);
joinEvent.userID = user.userID;
dispatcher.dispatchEvent(joinEvent);
UserManager.getInstance().getConference().removeUser(webUserId);
}
}
public function handleParticipantJoined(msg:Object):void {
@ -521,6 +551,8 @@ package org.bigbluebutton.modules.users.services
user.userID = joinedUser.userId;
user.name = joinedUser.name;
user.role = joinedUser.role;
user.guest = joinedUser.guest;
user.acceptedJoin = !user.guest;
user.externUserID = joinedUser.externUserID;
user.isLeavingFlag = false;
user.listenOnly = joinedUser.listenOnly;
@ -562,5 +594,98 @@ package org.bigbluebutton.modules.users.services
dispatcher.dispatchEvent(e);
}
}
public function handleGuestRequestedToEnter(msg:Object):void {
trace(LOG + "*** handleRequestedToEnter " + msg.msg + " **** \n");
var map:Object = JSON.parse(msg.msg);
if(UsersUtil.amIModerator() && UsersUtil.amIWaitForModerator() == false) {
var e:AddGuestEvent = new AddGuestEvent();
e.userid = map.userId;
e.name = map.name;
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(e);
}
}
public function handleGuestPolicyChanged(msg:Object):void {
trace(LOG + "*** handleGuestPolicyChanged " + msg.msg + " **** \n");
var map:Object = JSON.parse(msg.msg);
var policy:BBBEvent = new BBBEvent(BBBEvent.RETRIEVE_GUEST_POLICY);
policy.payload['guestPolicy'] = map.guestPolicy;
dispatcher.dispatchEvent(policy);
}
public function handleGetGuestPolicyReply(msg:Object):void {
trace(LOG + "*** handleGetGuestPolicyReply " + msg.msg + " **** \n");
var map:Object = JSON.parse(msg.msg);
var policy:BBBEvent = new BBBEvent(BBBEvent.RETRIEVE_GUEST_POLICY);
policy.payload['guestPolicy'] = map.guestPolicy;
if(UsersUtil.amIGuest()) {
if(map.guestPolicy == "ALWAYS_DENY")
dispatcher.dispatchEvent(new BBBEvent(BBBEvent.DENY_GUEST));
else if(map.guestPolicy == "ALWAYS_ACCEPT")
dispatcher.dispatchEvent(new BBBEvent(BBBEvent.ACCEPT_GUEST));
else
dispatcher.dispatchEvent(new BBBEvent(BBBEvent.ASK_TO_ACCEPT_GUEST));
}
dispatcher.dispatchEvent(policy);
}
public function handleResponseToGuest(msg:Object):void {
trace(LOG + "*** handleResponseToGuest " + msg.msg + " **** \n");
var map:Object = JSON.parse(msg.msg);
var dispatcher:Dispatcher = new Dispatcher();
if(UsersUtil.getMyUserID() == map.userId && UsersUtil.amIWaitForModerator()) {
UsersUtil.setWaitForModerator(false);
if(map.response == false) {
var kickEvent:BBBEvent = new BBBEvent(BBBEvent.KICK_GUEST);
kickEvent.payload.userId = map.userId;
dispatcher.dispatchEvent(kickEvent);
}
else {
var allowCommand:ModeratorRespEvent = new ModeratorRespEvent(ModeratorRespEvent.GUEST_ALLOWED);
dispatcher.dispatchEvent(allowCommand);
}
}
if(UsersUtil.amIModerator()) {
var e:RemoveGuestRequestEvent = new RemoveGuestRequestEvent(RemoveGuestRequestEvent.GUEST_EVENT);
e.userid = map.userId;
dispatcher.dispatchEvent(e);
}
}
public function handleGetGuestsWaitingReply(msg:Object):void {
trace(LOG + "*** handleGetGuestsPolicyReply " + msg.msg + " **** \n");
var map:Object = JSON.parse(msg.msg);
if(UsersUtil.amIModerator()) {
var guests:Array = map.guestsWaiting.split(",");
for each(var guest:String in guests) {
if(guest != "") {
var pairSplited:Array = guest.split(":");
var addGuestEvent:AddGuestEvent = new AddGuestEvent(AddGuestEvent.ADD_GUEST);
addGuestEvent.userid = pairSplited[0];
addGuestEvent.name = pairSplited[1];
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(addGuestEvent);
}
}
}
}
public function handleGuestKicked(msg:Object):void {
trace(LOG + "*** handleGuestKicked " + msg.msg + " **** \n");
var map:Object = JSON.parse(msg.msg);
if (UsersUtil.getMyUserID() == map.guestId){
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new LogoutEvent(LogoutEvent.GUEST_KICKED_OUT));
}
}
}
}
}

View File

@ -357,5 +357,116 @@ package org.bigbluebutton.modules.users.services
newLockSettings
);
}
public function queryForGuestPolicy():void {
trace(LOG + "queryForGuestPolicy");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.getGuestPolicy",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
}
);
}
public function setGuestPolicy(policy:String):void {
trace(LOG + "setGuestPolicy - new policy:[" + policy + "]");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.setGuestPolicy",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
},
policy
);
}
public function queryForGuestsWaiting():void {
trace(LOG + "queryForGuestsWaiting");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.getGuestsWaiting",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
}
);
}
public function kickGuest(userId:String):void {
trace(LOG + "kickGuest userID:[" + userId + "]");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.kickGuest",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
},
userId
);
}
public function guestDisconnect():void {
//TODO: Still need this?
}
public function askToEnter():void {
trace(LOG + "askToEnter - userID:[" + UsersUtil.getMyUserID() + "]");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.askingToEnter",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
}
);
}
public function responseToGuest(userId:String, response:Boolean):void {
trace(LOG + "responseToGuest - guestID:[" + userId + "] response:[" + response + "]");
var message:Object = new Object();
message["guestID"] = userId;
message["response"] = response;
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.responseToGuest",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
},
message
);
}
public function responseToAllGuests(response:Boolean):void {
trace(LOG + "responseToAllGuests - response:[" + response + "]");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage(
"participants.responseToAllGuests",
function(result:String):void { // On successful result
LogUtil.debug(result);
},
function(status:String):void { // status - On error occurred
LogUtil.error(status);
},
response
);
}
}
}
}

View File

@ -204,6 +204,12 @@ class ApiController {
errors.missingParamError("checksum");
}
String guest;
if (!StringUtils.isEmpty(params.guest) && params.guest.equalsIgnoreCase("true"))
guest = "true";
else
guest = "false";
// Do we have a name for the user joining? If none, complain.
String fullName = params.fullName
if (StringUtils.isEmpty(fullName)) {
@ -363,6 +369,7 @@ class ApiController {
us.mode = "LIVE"
us.record = meeting.isRecord()
us.welcome = meeting.getWelcomeMessage()
us.guest = guest
us.logoutUrl = meeting.getLogoutUrl();
us.configXML = configxml;
@ -385,7 +392,7 @@ class ApiController {
meetingService.addUserSession(session['user-token'], us);
// Register user into the meeting.
meetingService.registerUser(us.meetingID, us.internalUserId, us.fullname, us.role, us.externUserID, us.authToken)
meetingService.registerUser(us.meetingID, us.internalUserId, us.fullname, us.role, us.externUserID, us.authToken, us.guest)
log.info("Session user token for " + us.fullname + " [" + session['user-token'] + "]")
session.setMaxInactiveInterval(SESSION_TIMEOUT);
@ -1358,6 +1365,7 @@ class ApiController {
internalUserID = us.internalUserId
authToken = us.authToken
role = us.role
guest = us.guest
conference = us.conference
room = us.room
voicebridge = us.voicebridge

View File

@ -87,8 +87,8 @@ public class MeetingService implements MessageListener {
sessions.put(token, user);
}
public void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken) {
handle(new RegisterUser(meetingID, internalUserId, fullname, role, externUserID, authToken));
public void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken, String guest) {
handle(new RegisterUser(meetingID, internalUserId, fullname, role, externUserID, authToken, guest));
}
public UserSession getUserSession(String token) {
@ -543,7 +543,7 @@ public class MeetingService implements MessageListener {
log.debug("User joined in meeting[{}]", message.meetingId);
Meeting m = getMeeting(message.meetingId);
if (m != null) {
User user = new User(message.userId, message.externalUserId, message.name, message.role);
User user = new User(message.userId, message.externalUserId, message.name, message.role, message.guest);
m.userJoined(user);
log.info("New user in meeting [" + message.meetingId + "] user [" + user.getFullname() + "]");

View File

@ -28,12 +28,14 @@ public class User {
private String fullname;
private String role;
private Map<String,String> status;
private Boolean guest;
public User(String internalUserId, String externalUserId, String fullname, String role) {
public User(String internalUserId, String externalUserId, String fullname, String role, Boolean guest) {
this.internalUserId = internalUserId;
this.externalUserId = externalUserId;
this.fullname = fullname;
this.role = role;
this.guest = guest;
this.status = new ConcurrentHashMap<String, String>();
}
@ -51,6 +53,14 @@ public class User {
public void setExternalUserId(String externalUserId){
this.externalUserId = externalUserId;
}
public void setGuest(Boolean guest) {
this.guest = guest;
}
public Boolean isGuest() {
return this.guest;
}
public String getFullname() {
return fullname;

View File

@ -30,6 +30,7 @@ public class UserSession {
public String role = null;
public String conference = null;
public String room = null;
public String guest = "false";
public String voicebridge = null;
public String webvoiceconf = null;
public String mode = null;

View File

@ -99,9 +99,10 @@ public class MeetingMessageHandler implements MessageHandler {
String externuserid = user.get("extern_userid").getAsString();
String username = user.get("name").getAsString();
String role = user.get("role").getAsString();
Boolean guest = user.get("guest").getAsBoolean();
for (MessageListener listener : listeners) {
listener.handle(new UserJoined(meetingId, userid, externuserid, username, role));
listener.handle(new UserJoined(meetingId, userid, externuserid, username, role, guest));
}
} else if(MessagingConstants.USER_STATUS_CHANGE_EVENT.equalsIgnoreCase(messageName)) {
System.out.println("Handling [" + messageName + "] message.");

View File

@ -8,13 +8,15 @@ public class RegisterUser implements IMessage {
public final String role;
public final String externUserID;
public final String authToken;
public final String guest;
public RegisterUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken) {
public RegisterUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken, String guest) {
this.meetingID = meetingID;
this.internalUserId = internalUserId;
this.fullname = fullname;
this.role = role;
this.externUserID = externUserID;
this.authToken = authToken;
this.guest = guest;
}
}

View File

@ -6,12 +6,14 @@ public class UserJoined implements IMessage {
public final String externalUserId;
public final String name;
public final String role;
public final Boolean guest;
public UserJoined(String meetingId, String userId, String externalUserId, String name, String role) {
public UserJoined(String meetingId, String userId, String externalUserId, String name, String role, Boolean guest) {
this.meetingId = meetingId;
this.userId = userId;
this.externalUserId = externalUserId;
this.name = name;
this.role = role;
this.guest = guest;
}
}