Merge pull request #12789 from jfsiebel/implement-default-layout-config
Allow default layout config in bbb-web
This commit is contained in:
commit
1abedcc698
@ -1,7 +1,7 @@
|
||||
package org.bigbluebutton.core.apps.layout
|
||||
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.models.Layouts
|
||||
import org.bigbluebutton.core.models.{ Layouts, LayoutsType }
|
||||
import org.bigbluebutton.core.running.OutMsgRouter
|
||||
import org.bigbluebutton.core2.MeetingStatus2x
|
||||
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
||||
@ -17,9 +17,13 @@ trait BroadcastLayoutMsgHdlr extends RightsManagementTrait {
|
||||
val reason = "No permission to broadcast layout to meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
} else {
|
||||
Layouts.setCurrentLayout(liveMeeting.layouts, msg.body.layout, msg.header.userId)
|
||||
if (LayoutsType.layoutsType.contains(msg.body.layout)) {
|
||||
val newlayout = LayoutsType.layoutsType.getOrElse(msg.body.layout, "")
|
||||
|
||||
sendBroadcastLayoutEvtMsg(msg.header.userId)
|
||||
Layouts.setCurrentLayout(liveMeeting.layouts, newlayout, msg.header.userId)
|
||||
|
||||
sendBroadcastLayoutEvtMsg(msg.header.userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.bigbluebutton.core.models
|
||||
|
||||
import scala.collection.mutable.Map
|
||||
|
||||
object Layouts {
|
||||
def setCurrentLayout(instance: Layouts, layout: String, setBy: String) {
|
||||
instance.currentLayout = layout
|
||||
@ -29,3 +31,13 @@ class Layouts {
|
||||
// this is not being set by the client, and we need to apply the layouts to all users, not just viewers, so will keep the default value of this as false
|
||||
private var affectViewersOnly = true
|
||||
}
|
||||
|
||||
object LayoutsType {
|
||||
val layoutsType = Map(
|
||||
"legacy" -> "LEGACY",
|
||||
"custom" -> "CUSTOM_LAYOUT",
|
||||
"smart" -> "SMART_LAYOUT",
|
||||
"presentationFocus" -> "PRESENTATION_FOCUS",
|
||||
"videoFocus" -> "VIDEO_FOCUS"
|
||||
)
|
||||
}
|
||||
|
@ -45,6 +45,12 @@ class RunningMeeting(val props: DefaultProps, outGW: OutMessageGateway,
|
||||
GuestPolicy(props.usersProp.guestPolicy, SystemUser.ID)
|
||||
)
|
||||
|
||||
Layouts.setCurrentLayout(
|
||||
liveMeeting.layouts,
|
||||
props.usersProp.meetingLayout,
|
||||
SystemUser.ID
|
||||
)
|
||||
|
||||
private val recordEvents = props.recordProp.record || props.recordProp.keepEvents
|
||||
val outMsgRouter = new OutMsgRouter(recordEvents, outGW)
|
||||
|
||||
|
@ -169,6 +169,10 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging {
|
||||
case m: LockSettingsNotInitializedRespMsg => logMessage(msg)
|
||||
case m: MeetingInfoAnalyticsMsg => logMessage(msg)
|
||||
|
||||
// Layout
|
||||
case m: BroadcastLayoutMsg => logMessage(msg)
|
||||
case m: BroadcastLayoutEvtMsg => logMessage(msg)
|
||||
|
||||
case _ => // ignore message
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ case class WelcomeProp(welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMe
|
||||
|
||||
case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean)
|
||||
|
||||
case class UsersProp(maxUsers: Int, webcamsOnlyForModerator: Boolean, guestPolicy: String, allowModsToUnmuteUsers: Boolean, authenticatedGuest: Boolean)
|
||||
case class UsersProp(maxUsers: Int, webcamsOnlyForModerator: Boolean, guestPolicy: String, meetingLayout: String, allowModsToUnmuteUsers: Boolean, authenticatedGuest: Boolean)
|
||||
|
||||
case class MetadataProp(metadata: collection.immutable.Map[String, String])
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
@ -33,6 +33,7 @@ public class ApiParams {
|
||||
public static final String FREE_JOIN = "freeJoin";
|
||||
public static final String FULL_NAME = "fullName";
|
||||
public static final String GUEST_POLICY = "guestPolicy";
|
||||
public static final String MEETING_LAYOUT = "meetingLayout";
|
||||
public static final String IS_BREAKOUT = "isBreakout";
|
||||
public static final String LOGO = "logo";
|
||||
public static final String LOGOUT_TIMER = "logoutTimer";
|
||||
|
@ -49,6 +49,7 @@ import org.bigbluebutton.api.domain.Recording;
|
||||
import org.bigbluebutton.api.domain.RegisteredUser;
|
||||
import org.bigbluebutton.api.domain.User;
|
||||
import org.bigbluebutton.api.domain.UserSession;
|
||||
import org.bigbluebutton.api.domain.MeetingLayout;
|
||||
import org.bigbluebutton.api.messaging.MessageListener;
|
||||
import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage;
|
||||
import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage;
|
||||
@ -142,7 +143,7 @@ public class MeetingService implements MessageListener {
|
||||
public void addUserSession(String token, UserSession user) {
|
||||
sessions.put(token, user);
|
||||
}
|
||||
|
||||
|
||||
public String getTokenByUserId(String internalUserId) {
|
||||
String result = null;
|
||||
for (Entry<String, UserSession> e : sessions.entrySet()) {
|
||||
@ -418,6 +419,7 @@ public class MeetingService implements MessageListener {
|
||||
logData.put("description", "Create meeting.");
|
||||
|
||||
logData.put("meetingKeepEvents", m.getMeetingKeepEvents());
|
||||
logData.put("meetingLayout", m.getMeetingLayout());
|
||||
|
||||
Gson gson = new Gson();
|
||||
String logStr = gson.toJson(logData);
|
||||
@ -428,7 +430,7 @@ public class MeetingService implements MessageListener {
|
||||
m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), m.getAllowStartStopRecording(),
|
||||
m.getWebcamsOnlyForModerator(), m.getModeratorPassword(), m.getViewerPassword(), m.getCreateTime(),
|
||||
formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(),
|
||||
m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), m.getModeratorOnlyMessage(),
|
||||
m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getMeetingLayout(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), m.getModeratorOnlyMessage(),
|
||||
m.getDialNumber(), m.getMaxUsers(),
|
||||
m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getmeetingExpireWhenLastUserLeftInMinutes(),
|
||||
m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(),
|
||||
@ -581,7 +583,7 @@ public class MeetingService implements MessageListener {
|
||||
public String getCaptionTrackInboxDir() {
|
||||
return recordingService.getCaptionTrackInboxDir();
|
||||
}
|
||||
|
||||
|
||||
public String getCaptionsDir() {
|
||||
return recordingService.getCaptionsDir();
|
||||
}
|
||||
@ -695,7 +697,7 @@ public class MeetingService implements MessageListener {
|
||||
log.error(" --analytics-- data={}", logStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void processUpdateRecordingStatus(UpdateRecordingStatus message) {
|
||||
Meeting m = getMeeting(message.meetingId);
|
||||
// Set only once
|
||||
|
@ -77,6 +77,7 @@ public class ParamsProcessorUtil {
|
||||
private String defaultAvatarURL;
|
||||
private String defaultGuestPolicy;
|
||||
private Boolean authenticatedGuest;
|
||||
private String defaultMeetingLayout;
|
||||
private int defaultMeetingDuration;
|
||||
private boolean disableRecordingDefault;
|
||||
private boolean autoStartRecording;
|
||||
@ -447,12 +448,17 @@ public class ParamsProcessorUtil {
|
||||
String guestPolicy = defaultGuestPolicy;
|
||||
if (!StringUtils.isEmpty(params.get(ApiParams.GUEST_POLICY))) {
|
||||
guestPolicy = params.get(ApiParams.GUEST_POLICY);
|
||||
}
|
||||
}
|
||||
|
||||
String meetingLayout = defaultMeetingLayout;
|
||||
|
||||
if (!StringUtils.isEmpty(params.get(ApiParams.MEETING_LAYOUT))) {
|
||||
meetingLayout = params.get(ApiParams.MEETING_LAYOUT);
|
||||
}
|
||||
|
||||
BreakoutRoomsParams breakoutParams = processBreakoutRoomsParams(params);
|
||||
LockSettingsParams lockSettingsParams = processLockSettingsParams(params);
|
||||
|
||||
|
||||
|
||||
// Collect metadata for this meeting that the third-party app wants to
|
||||
// store if meeting is recorded.
|
||||
Map<String, String> meetingInfo = processMetaParam(params);
|
||||
@ -501,6 +507,7 @@ public class ParamsProcessorUtil {
|
||||
.withWelcomeMessage(welcomeMessage).isBreakout(isBreakout)
|
||||
.withGuestPolicy(guestPolicy)
|
||||
.withAuthenticatedGuest(authenticatedGuest)
|
||||
.withMeetingLayout(meetingLayout)
|
||||
.withBreakoutRoomsParams(breakoutParams)
|
||||
.withLockSettingsParams(lockSettingsParams)
|
||||
.withAllowDuplicateExtUserid(defaultAllowDuplicateExtUserid)
|
||||
@ -914,6 +921,10 @@ public class ParamsProcessorUtil {
|
||||
this.authenticatedGuest = value;
|
||||
}
|
||||
|
||||
public void setDefaultMeetingLayout(String meetingLayout) {
|
||||
this.defaultMeetingLayout = meetingLayout;
|
||||
}
|
||||
|
||||
public void setClientLogoutTimerInMinutes(Integer value) {
|
||||
clientLogoutTimerInMinutes = value;
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
@ -42,7 +42,7 @@ public class Meeting {
|
||||
private String parentMeetingId = "bbb-none"; // Initialize so we don't send null in the json message.
|
||||
private Integer sequence = 0;
|
||||
private Boolean freeJoin = false;
|
||||
private Integer duration = 0;
|
||||
private Integer duration = 0;
|
||||
private long createdTime = 0;
|
||||
private long startTime = 0;
|
||||
private long endTime = 0;
|
||||
@ -69,6 +69,7 @@ public class Meeting {
|
||||
private String guestPolicy = GuestPolicy.ASK_MODERATOR;
|
||||
private String guestLobbyMessage = "";
|
||||
private Boolean authenticatedGuest = false;
|
||||
private String meetingLayout = MeetingLayout.SMART_LAYOUT;
|
||||
private boolean userHasJoined = false;
|
||||
private Map<String, String> pads;
|
||||
private Map<String, String> metadata;
|
||||
@ -128,6 +129,7 @@ public class Meeting {
|
||||
isBreakout = builder.isBreakout;
|
||||
guestPolicy = builder.guestPolicy;
|
||||
authenticatedGuest = builder.authenticatedGuest;
|
||||
meetingLayout = builder.meetingLayout;
|
||||
breakoutRoomsParams = builder.breakoutRoomsParams;
|
||||
lockSettingsParams = builder.lockSettingsParams;
|
||||
allowDuplicateExtUserid = builder.allowDuplicateExtUserid;
|
||||
@ -219,11 +221,11 @@ public class Meeting {
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
|
||||
public void setStartTime(long t) {
|
||||
startTime = t;
|
||||
}
|
||||
|
||||
|
||||
public long getCreateTime() {
|
||||
return createdTime;
|
||||
}
|
||||
@ -243,35 +245,35 @@ public class Meeting {
|
||||
public void setFreeJoin(Boolean freeJoin) {
|
||||
this.freeJoin = freeJoin;
|
||||
}
|
||||
|
||||
|
||||
public Integer getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
||||
public long getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
|
||||
public void setModeratorOnlyMessage(String msg) {
|
||||
modOnlyMessage = msg;
|
||||
}
|
||||
|
||||
|
||||
public String getModeratorOnlyMessage() {
|
||||
return modOnlyMessage;
|
||||
}
|
||||
|
||||
|
||||
public void setEndTime(long t) {
|
||||
endTime = t;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRunning() {
|
||||
return ! users.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public Boolean isBreakout() {
|
||||
return isBreakout;
|
||||
}
|
||||
|
||||
|
||||
public void setHaveRecordingMarks(boolean marks) {
|
||||
haveRecordingMarks = marks;
|
||||
}
|
||||
@ -279,7 +281,7 @@ public class Meeting {
|
||||
public boolean haveRecordingMarks() {
|
||||
return haveRecordingMarks;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@ -295,7 +297,7 @@ public class Meeting {
|
||||
public String getExternalId() {
|
||||
return extMeetingId;
|
||||
}
|
||||
|
||||
|
||||
public String getInternalId() {
|
||||
return intMeetingId;
|
||||
}
|
||||
@ -323,7 +325,7 @@ public class Meeting {
|
||||
public String getViewerPassword() {
|
||||
return viewerPass;
|
||||
}
|
||||
|
||||
|
||||
public String getWelcomeMessageTemplate() {
|
||||
return welcomeMsgTemplate;
|
||||
}
|
||||
@ -360,6 +362,14 @@ public class Meeting {
|
||||
return authenticatedGuest;
|
||||
}
|
||||
|
||||
public void setMeetingLayout(String layout) {
|
||||
meetingLayout = layout;
|
||||
}
|
||||
|
||||
public String getMeetingLayout() {
|
||||
return meetingLayout;
|
||||
}
|
||||
|
||||
private String getUnauthenticatedGuestStatus(Boolean guest) {
|
||||
if (guest) {
|
||||
switch(guestPolicy) {
|
||||
@ -413,15 +423,15 @@ public class Meeting {
|
||||
public int getMaxUsers() {
|
||||
return maxUsers;
|
||||
}
|
||||
|
||||
|
||||
public int getLogoutTimer() {
|
||||
return logoutTimer;
|
||||
}
|
||||
|
||||
|
||||
public String getBannerColor() {
|
||||
return bannerColor;
|
||||
}
|
||||
|
||||
|
||||
public String getBannerText() {
|
||||
return bannerText;
|
||||
}
|
||||
@ -429,19 +439,19 @@ public class Meeting {
|
||||
public boolean isRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
public boolean getAutoStartRecording() {
|
||||
return autoStartRecording;
|
||||
}
|
||||
|
||||
|
||||
public boolean getAllowStartStopRecording() {
|
||||
return allowStartStopRecording;
|
||||
}
|
||||
|
||||
|
||||
public boolean getWebcamsOnlyForModerator() {
|
||||
return webcamsOnlyForModerator;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasUserJoined() {
|
||||
return userHasJoined;
|
||||
}
|
||||
@ -525,11 +535,11 @@ public class Meeting {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getNumUsers(){
|
||||
return this.users.size();
|
||||
}
|
||||
|
||||
|
||||
public int getNumModerators() {
|
||||
int sum = 0;
|
||||
for (Map.Entry<String, User> entry : users.entrySet()) {
|
||||
@ -539,7 +549,7 @@ public class Meeting {
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
public String getDialNumber() {
|
||||
return dialNumber;
|
||||
}
|
||||
@ -553,7 +563,7 @@ public class Meeting {
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
public int getNumVoiceJoined() {
|
||||
int sum = 0;
|
||||
for (Map.Entry<String, User> entry : users.entrySet()) {
|
||||
@ -572,7 +582,7 @@ public class Meeting {
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
public void addPad(String padId, String readOnlyId) {
|
||||
pads.put(padId, readOnlyId);
|
||||
}
|
||||
@ -601,7 +611,7 @@ public class Meeting {
|
||||
public Integer getMeetingExpireIfNoUserJoinedInMinutes() {
|
||||
return meetingExpireIfNoUserJoinedInMinutes;
|
||||
}
|
||||
|
||||
|
||||
public Integer getUserInactivityInspectTimerInMinutes() {
|
||||
return userInactivityInspectTimerInMinutes;
|
||||
}
|
||||
@ -609,7 +619,7 @@ public class Meeting {
|
||||
public void setUserInactivityInspectTimerInMinutes(Integer userInactivityInjspectTimerInMinutes) {
|
||||
this.userInactivityInspectTimerInMinutes = userInactivityInjspectTimerInMinutes;
|
||||
}
|
||||
|
||||
|
||||
public Integer getUserInactivityThresholdInMinutes() {
|
||||
return userInactivityThresholdInMinutes;
|
||||
}
|
||||
@ -720,6 +730,7 @@ public class Meeting {
|
||||
private boolean isBreakout;
|
||||
private String guestPolicy;
|
||||
private Boolean authenticatedGuest;
|
||||
private String meetingLayout;
|
||||
private BreakoutRoomsParams breakoutRoomsParams;
|
||||
private LockSettingsParams lockSettingsParams;
|
||||
private Boolean allowDuplicateExtUserid;
|
||||
@ -732,7 +743,7 @@ public class Meeting {
|
||||
this.internalId = internalId;
|
||||
this.createdTime = createTime;
|
||||
}
|
||||
|
||||
|
||||
public Builder withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
@ -742,17 +753,17 @@ public class Meeting {
|
||||
duration = minutes;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withMaxUsers(int n) {
|
||||
maxUsers = n;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withRecording(boolean record) {
|
||||
this.record = record;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withAutoStartRecording(boolean start) {
|
||||
this.autoStartRecording = start;
|
||||
return this;
|
||||
@ -762,37 +773,37 @@ public class Meeting {
|
||||
this.allowStartStopRecording = allow;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withWebcamsOnlyForModerator(boolean only) {
|
||||
this.webcamsOnlyForModerator = only;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withWebVoice(String w) {
|
||||
this.webVoice = w;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withTelVoice(String t) {
|
||||
this.telVoice = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withDialNumber(String d) {
|
||||
this.dialNumber = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withModeratorPass(String p) {
|
||||
this.moderatorPass = p;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withViewerPass(String p) {
|
||||
|
||||
public Builder withViewerPass(String p) {
|
||||
this.viewerPass = p;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withWelcomeMessage(String w) {
|
||||
welcomeMsg = w;
|
||||
return this;
|
||||
@ -802,12 +813,12 @@ public class Meeting {
|
||||
welcomeMsgTemplate = w;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withDefaultAvatarURL(String w) {
|
||||
defaultAvatarURL = w;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder isBreakout(Boolean b) {
|
||||
isBreakout = b;
|
||||
return this;
|
||||
@ -817,22 +828,22 @@ public class Meeting {
|
||||
logoutUrl = l;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withLogoutTimer(int l) {
|
||||
logoutTimer = l;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withBannerColor(String c) {
|
||||
bannerColor = c;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withBannerText(String t) {
|
||||
bannerText = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder withMetadata(Map<String, String> m) {
|
||||
metadata = m;
|
||||
return this;
|
||||
@ -841,13 +852,18 @@ public class Meeting {
|
||||
public Builder withGuestPolicy(String policy) {
|
||||
guestPolicy = policy;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Builder withAuthenticatedGuest(Boolean authGuest) {
|
||||
authenticatedGuest = authGuest;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withMeetingLayout(String layout) {
|
||||
meetingLayout = layout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withBreakoutRoomsParams(BreakoutRoomsParams params) {
|
||||
breakoutRoomsParams = params;
|
||||
return this;
|
||||
@ -877,7 +893,7 @@ public class Meeting {
|
||||
html5InstanceId = instanceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Meeting build() {
|
||||
return new Meeting(this);
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package org.bigbluebutton.api.domain;
|
||||
|
||||
public class MeetingLayout {
|
||||
public static final String FOCUS_ON_PRESENTATION = "FOCUS_ON_PRESENTATION";
|
||||
public static final String FOCUS_ON_WEBCAMS = "FOCUS_ON_WEBCAMS";
|
||||
public static final String SMART_LAYOUT = "SMART_LAYOUT";
|
||||
}
|
@ -19,7 +19,7 @@ public interface IBbbWebApiGWApp {
|
||||
Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator,
|
||||
String moderatorPass, String viewerPass, Long createTime,
|
||||
String createDate, Boolean isBreakout, Integer sequence, Boolean freejoin, Map<String, String> metadata,
|
||||
String guestPolicy, Boolean authenticatedGuest, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage,
|
||||
String guestPolicy, Boolean authenticatedGuest, String meetingLayout, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage,
|
||||
String dialNumber, Integer maxUsers,
|
||||
Integer meetingExpireIfNoUserJoinedInMinutes,
|
||||
Integer meetingExpireWhenLastUserLeftInMinutes,
|
||||
|
@ -5,6 +5,7 @@ import java.util.Map;
|
||||
|
||||
public class UsersProp2 {
|
||||
public final String guestPolicy;
|
||||
public final String meetingLayout;
|
||||
public final boolean authenticatedGuest;
|
||||
public final boolean userHasJoined;
|
||||
public final boolean webcamsOnlyForModerator;
|
||||
@ -16,6 +17,7 @@ public class UsersProp2 {
|
||||
public UsersProp2(int maxUsers,
|
||||
boolean webcamsOnlyForModerator,
|
||||
String guestPolicy,
|
||||
String meetingLayout,
|
||||
boolean authenticatedGuest,
|
||||
boolean userHasJoined,
|
||||
Map<String, String> userCustomData,
|
||||
@ -24,6 +26,7 @@ public class UsersProp2 {
|
||||
this.maxUsers = maxUsers;
|
||||
this.webcamsOnlyForModerator = webcamsOnlyForModerator;
|
||||
this.guestPolicy = guestPolicy;
|
||||
this.meetingLayout = meetingLayout;
|
||||
this.authenticatedGuest = authenticatedGuest;
|
||||
this.userHasJoined = userHasJoined;
|
||||
this.userCustomData = userCustomData;
|
||||
|
@ -127,7 +127,7 @@ class BbbWebApiGWApp(
|
||||
viewerPass: String, createTime: java.lang.Long, createDate: String, isBreakout: java.lang.Boolean,
|
||||
sequence: java.lang.Integer,
|
||||
freeJoin: java.lang.Boolean,
|
||||
metadata: java.util.Map[String, String], guestPolicy: String, authenticatedGuest: java.lang.Boolean,
|
||||
metadata: java.util.Map[String, String], guestPolicy: String, authenticatedGuest: java.lang.Boolean, meetingLayout: String,
|
||||
welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String,
|
||||
dialNumber: String, maxUsers: java.lang.Integer,
|
||||
meetingExpireIfNoUserJoinedInMinutes: java.lang.Integer,
|
||||
@ -176,7 +176,7 @@ class BbbWebApiGWApp(
|
||||
modOnlyMessage = modOnlyMessage)
|
||||
val voiceProp = VoiceProp(telVoice = voiceBridge, voiceConf = voiceBridge, dialNumber = dialNumber, muteOnStart = muteOnStart.booleanValue())
|
||||
val usersProp = UsersProp(maxUsers = maxUsers.intValue(), webcamsOnlyForModerator = webcamsOnlyForModerator.booleanValue(),
|
||||
guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(), authenticatedGuest = authenticatedGuest.booleanValue())
|
||||
guestPolicy = guestPolicy, meetingLayout = meetingLayout, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(), authenticatedGuest = authenticatedGuest.booleanValue())
|
||||
val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap)
|
||||
val screenshareProps = ScreenshareProps(
|
||||
screenshareConf = voiceBridge + screenshareConfSuffix,
|
||||
|
@ -67,6 +67,7 @@
|
||||
# 2020-05-20 NJH Add port 443 to --Network and clean up tmp file.
|
||||
# 2020-06-23 JFS Remove defaultGuestPolicy warning for HTML5 client
|
||||
# 2020-10-22 AGG Removing Flash/Red5 related code (yay!)
|
||||
# 2021-07-16 JFS Add defaultMeetingLayout information
|
||||
|
||||
#set -x
|
||||
#set -e
|
||||
@ -439,7 +440,7 @@ display_bigbluebutton_status () {
|
||||
for ((i = 1 ; i <= $NUMBER_OF_BACKEND_NODEJS_PROCESSES; i++)); do
|
||||
units="$units bbb-html5-backend@$i"
|
||||
done
|
||||
|
||||
|
||||
for ((i = 1; i <= $NUMBER_OF_FRONTEND_NODEJS_PROCESSES; i++)); do
|
||||
units="$units bbb-html5-frontend@$i"
|
||||
done
|
||||
@ -1276,8 +1277,8 @@ check_state() {
|
||||
else
|
||||
STUN_SERVER="$STUN_SERVER 3478"
|
||||
fi
|
||||
|
||||
if which stunclient > /dev/null 2>&1; then
|
||||
|
||||
if which stunclient > /dev/null 2>&1; then
|
||||
if stunclient --mode full --localport 30000 $STUN_SERVER | grep -q "fail\|Unable\ to\ resolve"; then
|
||||
echo
|
||||
echo "#"
|
||||
@ -1340,6 +1341,7 @@ if [ $CHECK ]; then
|
||||
echo " bigbluebutton.web.serverURL: $(get_bbb_web_config_value bigbluebutton.web.serverURL)"
|
||||
echo " defaultGuestPolicy: $(get_bbb_web_config_value defaultGuestPolicy)"
|
||||
echo " svgImagesRequired: $(get_bbb_web_config_value svgImagesRequired)"
|
||||
echo " defaultMeetingLayout: $(get_bbb_web_config_value defaultMeetingLayout)"
|
||||
|
||||
echo
|
||||
echo "/etc/nginx/sites-available/bigbluebutton (nginx)"
|
||||
|
@ -12,6 +12,7 @@ import handleRecordingTimerChange from './handlers/recordingTimerChange';
|
||||
import handleTimeRemainingUpdate from './handlers/timeRemainingUpdate';
|
||||
import handleChangeWebcamOnlyModerator from './handlers/webcamOnlyModerator';
|
||||
import handleSelectRandomViewer from './handlers/selectRandomViewer';
|
||||
import handleBroadcastLayout from './handlers/broadcastLayout';
|
||||
|
||||
RedisPubSub.on('MeetingCreatedEvtMsg', handleMeetingCreation);
|
||||
RedisPubSub.on('SyncGetMeetingInfoRespMsg', handleGetAllMeetings);
|
||||
@ -27,3 +28,4 @@ RedisPubSub.on('GuestPolicyChangedEvtMsg', handleGuestPolicyChanged);
|
||||
RedisPubSub.on('GuestLobbyMessageChangedEvtMsg', handleGuestLobbyMessageChanged);
|
||||
RedisPubSub.on('MeetingTimeRemainingUpdateEvtMsg', handleTimeRemainingUpdate);
|
||||
RedisPubSub.on('SelectRandomViewerRespMsg', handleSelectRandomViewer);
|
||||
RedisPubSub.on('BroadcastLayoutEvtMsg', handleBroadcastLayout);
|
||||
|
@ -0,0 +1,7 @@
|
||||
import changeLayout from '../modifiers/changeLayout';
|
||||
|
||||
export default function broadcastLayout({ body }, meetingId) {
|
||||
const { layout, setByUserId, applyTo } = body;
|
||||
|
||||
changeLayout(meetingId, layout, setByUserId, applyTo);
|
||||
}
|
@ -1,30 +1,24 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Meetings from '/imports/api/meetings';
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { extractCredentials } from '/imports/api/common/server/helpers';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
export default function changeLayout(newLayout) {
|
||||
export default function changeLayout(layout) {
|
||||
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'BroadcastLayoutMsg';
|
||||
|
||||
try {
|
||||
const { meetingId, requesterUserId } = extractCredentials(this.userId);
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
const payload = {
|
||||
layout,
|
||||
};
|
||||
|
||||
const modifier = {
|
||||
$set: {
|
||||
layout: newLayout
|
||||
},
|
||||
};
|
||||
|
||||
const numberAffected = Meetings.update(selector, modifier);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Changed layout from meeting=${meetingId} by id=${requesterUserId}`);
|
||||
}
|
||||
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method changeLayout ${err.stack}`);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import { initPads } from '/imports/api/common/server/etherpad';
|
||||
import { addAnnotationsStreamer } from '/imports/api/annotations/server/streamer';
|
||||
import { addCursorStreamer } from '/imports/api/cursor/server/streamer';
|
||||
import { addExternalVideoStreamer } from '/imports/api/external-videos/server/streamer';
|
||||
import { LAYOUT_TYPE } from '/imports/ui/components/layout/enums';
|
||||
|
||||
const addExternalVideo = (meetingId) => {
|
||||
const selector = { meetingId };
|
||||
@ -59,6 +60,7 @@ export default function addMeeting(meeting) {
|
||||
authenticatedGuest: Boolean,
|
||||
maxUsers: Number,
|
||||
allowModsToUnmuteUsers: Boolean,
|
||||
meetingLayout: String,
|
||||
},
|
||||
durationProps: {
|
||||
createdTime: Number,
|
||||
@ -169,7 +171,7 @@ export default function addMeeting(meeting) {
|
||||
$set: Object.assign({
|
||||
meetingId,
|
||||
meetingEnded,
|
||||
layout: 'smart',
|
||||
layout: LAYOUT_TYPE[meeting.usersProp.meetingLayout] || 'smart',
|
||||
publishedPoll: false,
|
||||
guestLobbyMessage: '',
|
||||
randomlySelectedUser: [],
|
||||
|
@ -0,0 +1,31 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Meetings from '/imports/api/meetings';
|
||||
import { check } from 'meteor/check';
|
||||
import { LAYOUT_TYPE } from '/imports/ui/components/layout/enums';
|
||||
|
||||
export default function changeLayout(meetingId, layout, requesterUserId, affectedUsers) {
|
||||
try {
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(layout, String);
|
||||
check(affectedUsers, Match.Maybe([String]));
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
};
|
||||
|
||||
const modifier = {
|
||||
$set: {
|
||||
layout: LAYOUT_TYPE[layout] || 'smart',
|
||||
},
|
||||
};
|
||||
|
||||
const numberAffected = Meetings.update(selector, modifier);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Meeting layout changed to ${layout} for meeting=${meetingId} requested by user=${requesterUserId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method changeLayout ${err.stack}`);
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
# These are the default properites for BigBlueButton Web application
|
||||
|
||||
# Default loglevel.
|
||||
# Default loglevel.
|
||||
appLogLevel=DEBUG
|
||||
|
||||
#----------------------------------------------------
|
||||
@ -178,6 +178,11 @@ defaultGuestPolicy=ALWAYS_ACCEPT
|
||||
# Enables or disables authenticated guest
|
||||
authenticatedGuest=true
|
||||
|
||||
#---------------------------------------------------
|
||||
# Default Meeting Layout
|
||||
# Valid values are LEGACY, CUSTOM_LAYOUT, SMART_LAYOUT, PRESENTATION_FOCUS, VIDEO_FOCUS
|
||||
defaultMeetingLayout=SMART_LAYOUT
|
||||
|
||||
#
|
||||
#----------------------------------------------------
|
||||
# Default welcome message to display when the participant joins the web
|
||||
@ -225,14 +230,14 @@ userInactivityThresholdInMinutes=30
|
||||
# warning before being logged out.
|
||||
userActivitySignResponseDelayInMinutes=5
|
||||
|
||||
# Disable recording by default.
|
||||
# Disable recording by default.
|
||||
# true - don't record even if record param in the api call is set to record
|
||||
# false - when record param is passed from api, override this default
|
||||
disableRecordingDefault=false
|
||||
|
||||
# Start recording when first user joins the meeting.
|
||||
# For backward compatibility with 0.81 where whole meeting
|
||||
# is recorded.
|
||||
# is recorded.
|
||||
autoStartRecording=false
|
||||
|
||||
# Allow the user to start/stop recording.
|
||||
|
@ -23,7 +23,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util-2.0.xsd">
|
||||
|
||||
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
|
||||
@ -108,7 +108,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
</bean>
|
||||
|
||||
<bean id="html5LoadBalancingService" class="org.bigbluebutton.api.HTML5LoadBalancingService" init-method="init" />
|
||||
|
||||
|
||||
<bean id="configServiceHelper" class="org.bigbluebutton.api.ClientConfigServiceHelperImp"/>
|
||||
|
||||
<bean id="configService" class="org.bigbluebutton.api.ClientConfigService" init-method="init">
|
||||
@ -151,6 +151,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<property name="defaultAvatarURL" value="${defaultAvatarURL}"/>
|
||||
<property name="defaultGuestPolicy" value="${defaultGuestPolicy}"/>
|
||||
<property name="authenticatedGuest" value="${authenticatedGuest}"/>
|
||||
<property name="defaultMeetingLayout" value="${defaultMeetingLayout}"/>
|
||||
<property name="meetingExpireIfNoUserJoinedInMinutes" value="${meetingExpireIfNoUserJoinedInMinutes}"/>
|
||||
<property name="meetingExpireWhenLastUserLeftInMinutes" value="${meetingExpireWhenLastUserLeftInMinutes}"/>
|
||||
<property name="userInactivityInspectTimerInMinutes" value="${userInactivityInspectTimerInMinutes}"/>
|
||||
|
@ -294,6 +294,7 @@ class ApiController {
|
||||
us.authed = authenticated
|
||||
us.guestStatus = guestStatusVal
|
||||
us.logoutUrl = meeting.getLogoutUrl()
|
||||
us.defaultLayout = meeting.getMeetingLayout()
|
||||
|
||||
if (!StringUtils.isEmpty(params.defaultLayout)) {
|
||||
us.defaultLayout = params.defaultLayout;
|
||||
|
Loading…
Reference in New Issue
Block a user