Merge remote-tracking branch 'origin/update-breakout-duration' into update-breakout-duration
This commit is contained in:
commit
6839a424c1
@ -24,14 +24,14 @@ case class MonitorNumberOfUsersInternalMsg(meetingID: String) extends InMessage
|
||||
* Audit message sent to meeting to trigger updating clients of meeting time remaining.
|
||||
* @param meetingId
|
||||
*/
|
||||
case class SendTimeRemainingAuditInternalMsg(meetingId: String) extends InMessage
|
||||
case class SendTimeRemainingAuditInternalMsg(meetingId: String, timeUpdatedInMinutes: Int) extends InMessage
|
||||
|
||||
/**
|
||||
* Parent message sent to breakout rooms to trigger updating clients of meeting time remaining.
|
||||
* @param meetingId
|
||||
* @param timeLeftInSec
|
||||
*/
|
||||
case class SendBreakoutTimeRemainingInternalMsg(meetingId: String, timeLeftInSec: Long) extends InMessage
|
||||
case class SendBreakoutTimeRemainingInternalMsg(meetingId: String, timeLeftInSec: Long, timeUpdatedInMinutes: Int) extends InMessage
|
||||
|
||||
case class SendRecordingTimerInternalMsg(meetingId: String) extends InMessage
|
||||
|
||||
@ -76,12 +76,12 @@ case class BreakoutRoomUsersUpdateInternalMsg(parentId: String, breakoutId: Stri
|
||||
case class EndBreakoutRoomInternalMsg(parentId: String, breakoutId: String, reason: String) extends InMessage
|
||||
|
||||
/**
|
||||
* Sent by parent meeting to breakout room to extend time.
|
||||
* Sent by parent meeting to breakout room to update time.
|
||||
* @param parentId
|
||||
* @param breakoutId
|
||||
* @param extendTimeInMinutes
|
||||
* @param durationInSeconds
|
||||
*/
|
||||
case class ExtendBreakoutRoomTimeInternalMsg(parentId: String, breakoutId: String, extendTimeInMinutes: Int) extends InMessage
|
||||
case class UpdateBreakoutRoomTimeInternalMsg(parentId: String, breakoutId: String, durationInSeconds: Int) extends InMessage
|
||||
|
||||
/**
|
||||
* Sent by parent meeting to breakout room to extend time.
|
||||
|
@ -22,7 +22,7 @@ object BreakoutModel {
|
||||
|
||||
case class BreakoutModel(
|
||||
startedOn: Option[Long],
|
||||
durationInMinutes: Int,
|
||||
durationInSeconds: Int,
|
||||
rooms: Map[String, BreakoutRoom2x]
|
||||
) {
|
||||
|
||||
@ -78,8 +78,8 @@ case class BreakoutModel(
|
||||
copy(rooms = rooms - id)
|
||||
}
|
||||
|
||||
def extendTime(timeToExtendInMinutes: Int): BreakoutModel = {
|
||||
copy(durationInMinutes = durationInMinutes + timeToExtendInMinutes)
|
||||
def setTime(newDurationInSeconds: Int): BreakoutModel = {
|
||||
copy(durationInSeconds = newDurationInSeconds)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,14 +10,14 @@ trait BreakoutApp2x extends BreakoutRoomCreatedMsgHdlr
|
||||
with BreakoutRoomUsersUpdateMsgHdlr
|
||||
with CreateBreakoutRoomsCmdMsgHdlr
|
||||
with EndAllBreakoutRoomsMsgHdlr
|
||||
with ExtendBreakoutRoomsTimeMsgHdlr
|
||||
with UpdateBreakoutRoomsTimeMsgHdlr
|
||||
with SendMessageToAllBreakoutRoomsMsgHdlr
|
||||
with SendMessageToBreakoutRoomInternalMsgHdlr
|
||||
with RequestBreakoutJoinURLReqMsgHdlr
|
||||
with SendBreakoutUsersUpdateMsgHdlr
|
||||
with TransferUserToMeetingRequestHdlr
|
||||
with EndBreakoutRoomInternalMsgHdlr
|
||||
with ExtendBreakoutRoomTimeInternalMsgHdlr
|
||||
with UpdateBreakoutRoomTimeInternalMsgHdlr
|
||||
with BreakoutRoomEndedInternalMsgHdlr {
|
||||
|
||||
this: MeetingActor =>
|
||||
|
@ -61,7 +61,7 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait {
|
||||
breakout.freeJoin,
|
||||
liveMeeting.props.voiceProp.dialNumber,
|
||||
breakout.voiceConf,
|
||||
msg.body.durationInMinutes,
|
||||
msg.body.durationInMinutes * 60,
|
||||
liveMeeting.props.password.moderatorPass,
|
||||
liveMeeting.props.password.viewerPass,
|
||||
presId, presSlide, msg.body.record,
|
||||
@ -72,7 +72,7 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait {
|
||||
outGW.send(event)
|
||||
}
|
||||
|
||||
val breakoutModel = new BreakoutModel(None, msg.body.durationInMinutes, rooms)
|
||||
val breakoutModel = new BreakoutModel(None, msg.body.durationInMinutes * 60, rooms)
|
||||
state.update(Some(breakoutModel))
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ trait SendBreakoutTimeRemainingInternalMsgHdlr {
|
||||
val outGW: OutMsgRouter
|
||||
|
||||
def handleSendBreakoutTimeRemainingInternalMsg(msg: SendBreakoutTimeRemainingInternalMsg): Unit = {
|
||||
val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, msg.timeLeftInSec.toInt)
|
||||
val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, msg.timeLeftInSec.toInt, msg.timeUpdatedInMinutes)
|
||||
outGW.send(event)
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
package org.bigbluebutton.core.apps.breakout
|
||||
|
||||
import org.bigbluebutton.core.api.{ ExtendBreakoutRoomTimeInternalMsg }
|
||||
import org.bigbluebutton.core.api.{ UpdateBreakoutRoomTimeInternalMsg }
|
||||
import org.bigbluebutton.core.domain.{ MeetingState2x }
|
||||
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
|
||||
|
||||
trait ExtendBreakoutRoomTimeInternalMsgHdlr {
|
||||
trait UpdateBreakoutRoomTimeInternalMsgHdlr {
|
||||
this: MeetingActor =>
|
||||
|
||||
val outGW: OutMsgRouter
|
||||
|
||||
def handleExtendBreakoutRoomTimeInternalMsgHdlr(msg: ExtendBreakoutRoomTimeInternalMsg, state: MeetingState2x): MeetingState2x = {
|
||||
def handleUpdateBreakoutRoomTimeInternalMsgHdlr(msg: UpdateBreakoutRoomTimeInternalMsg, state: MeetingState2x): MeetingState2x = {
|
||||
|
||||
val breakoutModel = for {
|
||||
model <- state.breakout
|
||||
} yield {
|
||||
val updatedBreakoutModel = model.extendTime(msg.extendTimeInMinutes)
|
||||
val updatedBreakoutModel = model.setTime(msg.durationInSeconds)
|
||||
updatedBreakoutModel
|
||||
}
|
||||
|
@ -1,37 +1,38 @@
|
||||
package org.bigbluebutton.core.apps.breakout
|
||||
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.api.{ ExtendBreakoutRoomTimeInternalMsg, SendTimeRemainingAuditInternalMsg }
|
||||
import org.bigbluebutton.core.api.{ UpdateBreakoutRoomTimeInternalMsg, SendTimeRemainingAuditInternalMsg }
|
||||
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
||||
import org.bigbluebutton.core.bus.BigBlueButtonEvent
|
||||
import org.bigbluebutton.core.domain.MeetingState2x
|
||||
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
|
||||
import org.bigbluebutton.core.util.TimeUtil
|
||||
|
||||
trait ExtendBreakoutRoomsTimeMsgHdlr extends RightsManagementTrait {
|
||||
trait UpdateBreakoutRoomsTimeMsgHdlr extends RightsManagementTrait {
|
||||
this: MeetingActor =>
|
||||
|
||||
val outGW: OutMsgRouter
|
||||
|
||||
def handleExtendBreakoutRoomsTimeMsg(msg: ExtendBreakoutRoomsTimeReqMsg, state: MeetingState2x): MeetingState2x = {
|
||||
def handleUpdateBreakoutRoomsTimeMsg(msg: UpdateBreakoutRoomsTimeReqMsg, state: MeetingState2x): MeetingState2x = {
|
||||
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to extend time for breakout rooms for meeting."
|
||||
val reason = "No permission to update time for breakout rooms for meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
state
|
||||
} else if (msg.body.extendTimeInMinutes <= 0) {
|
||||
log.error("Error while trying to extend {} minutes for breakout rooms time in meeting {}. Only positive values are allowed!", msg.body.extendTimeInMinutes, props.meetingProp.intId)
|
||||
} else if (msg.body.timeInMinutes <= 0) {
|
||||
log.error("Error while trying to update {} minutes for breakout rooms time in meeting {}. Only positive values are allowed!", msg.body.timeInMinutes, props.meetingProp.intId)
|
||||
state
|
||||
} else {
|
||||
val updatedModel = for {
|
||||
breakoutModel <- state.breakout
|
||||
startedOn <- breakoutModel.startedOn
|
||||
} yield {
|
||||
val breakoutRoomEndTime = TimeUtil.millisToSeconds(startedOn) + TimeUtil.minutesToSeconds(breakoutModel.durationInMinutes)
|
||||
val breakoutRoomSecsRemaining = breakoutRoomEndTime - TimeUtil.millisToSeconds(System.currentTimeMillis())
|
||||
val newSecsRemaining = msg.body.timeInMinutes * 60
|
||||
val breakoutRoomSecsElapsed = TimeUtil.millisToSeconds(System.currentTimeMillis()) - TimeUtil.millisToSeconds(startedOn);
|
||||
val newDurationInSeconds = breakoutRoomSecsElapsed.toInt + newSecsRemaining
|
||||
|
||||
var isExtendTimeHigherThanMeetingRemaining = false
|
||||
var isNewTimeHigherThanMeetingRemaining = false
|
||||
|
||||
if (state.expiryTracker.durationInMs > 0) {
|
||||
val mainRoomEndTime = state.expiryTracker.startedOnInMs + state.expiryTracker.durationInMs
|
||||
@ -40,28 +41,28 @@ trait ExtendBreakoutRoomsTimeMsgHdlr extends RightsManagementTrait {
|
||||
|
||||
//Avoid breakout room end later than main room
|
||||
//Keep 5 seconds of margin to finish breakout room and send informations to parent meeting
|
||||
if (breakoutRoomSecsRemaining + TimeUtil.minutesToSeconds(msg.body.extendTimeInMinutes) > (mainRoomSecsRemaining - 5)) {
|
||||
log.error("Error while trying to extend {} minutes for breakout rooms time in meeting {}. Parent meeting will end up in {} minutes!", msg.body.extendTimeInMinutes, props.meetingProp.intId, mainRoomTimeRemainingInMinutes)
|
||||
isExtendTimeHigherThanMeetingRemaining = true
|
||||
if (newSecsRemaining > (mainRoomSecsRemaining - 5)) {
|
||||
log.error("Error while trying to update {} minutes for breakout rooms time in meeting {}. Parent meeting will end up in {} minutes!", msg.body.timeInMinutes, props.meetingProp.intId, mainRoomTimeRemainingInMinutes)
|
||||
isNewTimeHigherThanMeetingRemaining = true
|
||||
}
|
||||
}
|
||||
|
||||
if (isExtendTimeHigherThanMeetingRemaining) {
|
||||
if (isNewTimeHigherThanMeetingRemaining) {
|
||||
breakoutModel
|
||||
} else {
|
||||
breakoutModel.rooms.values.foreach { room =>
|
||||
eventBus.publish(BigBlueButtonEvent(room.id, ExtendBreakoutRoomTimeInternalMsg(props.breakoutProps.parentId, room.id, msg.body.extendTimeInMinutes)))
|
||||
eventBus.publish(BigBlueButtonEvent(room.id, UpdateBreakoutRoomTimeInternalMsg(props.breakoutProps.parentId, room.id, newDurationInSeconds)))
|
||||
}
|
||||
log.debug("Extending {} minutes for breakout rooms time in meeting {}", msg.body.extendTimeInMinutes, props.meetingProp.intId)
|
||||
breakoutModel.extendTime(msg.body.extendTimeInMinutes)
|
||||
log.debug("Updating {} minutes for breakout rooms time in meeting {}", msg.body.timeInMinutes, props.meetingProp.intId)
|
||||
breakoutModel.setTime(newDurationInSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
val event = buildExtendBreakoutRoomsTimeEvtMsg(msg.body.extendTimeInMinutes)
|
||||
val event = buildUpdateBreakoutRoomsTimeEvtMsg(msg.body.timeInMinutes)
|
||||
outGW.send(event)
|
||||
|
||||
//Force Update time remaining in the clients
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingAuditInternalMsg(props.meetingProp.intId)))
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingAuditInternalMsg(props.meetingProp.intId, msg.body.timeInMinutes)))
|
||||
|
||||
updatedModel match {
|
||||
case Some(model) => state.update(Some(model))
|
||||
@ -70,13 +71,13 @@ trait ExtendBreakoutRoomsTimeMsgHdlr extends RightsManagementTrait {
|
||||
}
|
||||
}
|
||||
|
||||
def buildExtendBreakoutRoomsTimeEvtMsg(extendTimeInMinutes: Int): BbbCommonEnvCoreMsg = {
|
||||
def buildUpdateBreakoutRoomsTimeEvtMsg(timeInMinutes: Int): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(ExtendBreakoutRoomsTimeEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(ExtendBreakoutRoomsTimeEvtMsg.NAME, liveMeeting.props.meetingProp.intId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(UpdateBreakoutRoomsTimeEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(UpdateBreakoutRoomsTimeEvtMsg.NAME, liveMeeting.props.meetingProp.intId, "not-used")
|
||||
|
||||
val body = ExtendBreakoutRoomsTimeEvtMsgBody(props.meetingProp.intId, extendTimeInMinutes)
|
||||
val event = ExtendBreakoutRoomsTimeEvtMsg(header, body)
|
||||
val body = UpdateBreakoutRoomsTimeEvtMsgBody(props.meetingProp.intId, timeInMinutes)
|
||||
val event = UpdateBreakoutRoomsTimeEvtMsg(header, body)
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
@ -223,8 +223,8 @@ class ReceivedJsonMsgHandlerActor(
|
||||
routeGenericMsg[EndAllBreakoutRoomsMsg](envelope, jsonNode)
|
||||
case TransferUserToMeetingRequestMsg.NAME =>
|
||||
routeGenericMsg[TransferUserToMeetingRequestMsg](envelope, jsonNode)
|
||||
case ExtendBreakoutRoomsTimeReqMsg.NAME =>
|
||||
routeGenericMsg[ExtendBreakoutRoomsTimeReqMsg](envelope, jsonNode)
|
||||
case UpdateBreakoutRoomsTimeReqMsg.NAME =>
|
||||
routeGenericMsg[UpdateBreakoutRoomsTimeReqMsg](envelope, jsonNode)
|
||||
case SendMessageToAllBreakoutRoomsReqMsg.NAME =>
|
||||
routeGenericMsg[SendMessageToAllBreakoutRoomsReqMsg](envelope, jsonNode)
|
||||
|
||||
|
@ -283,7 +283,7 @@ class MeetingActor(
|
||||
case msg: SendBreakoutUsersAuditInternalMsg => handleSendBreakoutUsersUpdateInternalMsg(msg)
|
||||
case msg: BreakoutRoomUsersUpdateInternalMsg => state = handleBreakoutRoomUsersUpdateInternalMsg(msg, state)
|
||||
case msg: EndBreakoutRoomInternalMsg => handleEndBreakoutRoomInternalMsg(msg)
|
||||
case msg: ExtendBreakoutRoomTimeInternalMsg => state = handleExtendBreakoutRoomTimeInternalMsgHdlr(msg, state)
|
||||
case msg: UpdateBreakoutRoomTimeInternalMsg => state = handleUpdateBreakoutRoomTimeInternalMsgHdlr(msg, state)
|
||||
case msg: BreakoutRoomEndedInternalMsg => state = handleBreakoutRoomEndedInternalMsg(msg, state)
|
||||
case msg: SendMessageToBreakoutRoomInternalMsg => state = handleSendMessageToBreakoutRoomInternalMsg(msg, state, liveMeeting, msgBus)
|
||||
case msg: SendBreakoutTimeRemainingInternalMsg => handleSendBreakoutTimeRemainingInternalMsg(msg)
|
||||
@ -454,7 +454,7 @@ class MeetingActor(
|
||||
case m: EndAllBreakoutRoomsMsg => state = handleEndAllBreakoutRoomsMsg(m, state)
|
||||
case m: RequestBreakoutJoinURLReqMsg => state = handleRequestBreakoutJoinURLReqMsg(m, state)
|
||||
case m: TransferUserToMeetingRequestMsg => state = handleTransferUserToMeetingRequestMsg(m, state)
|
||||
case m: ExtendBreakoutRoomsTimeReqMsg => state = handleExtendBreakoutRoomsTimeMsg(m, state)
|
||||
case m: UpdateBreakoutRoomsTimeReqMsg => state = handleUpdateBreakoutRoomsTimeMsg(m, state)
|
||||
case m: SendMessageToAllBreakoutRoomsReqMsg => state = handleSendMessageToAllBreakoutRoomsMsg(m, state)
|
||||
|
||||
// Voice
|
||||
|
@ -73,7 +73,7 @@ class MeetingActorAudit(
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, MonitorNumberOfUsersInternalMsg(props.meetingProp.intId)))
|
||||
|
||||
// Trigger updating users of time remaining on meeting.
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingAuditInternalMsg(props.meetingProp.intId)))
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingAuditInternalMsg(props.meetingProp.intId, 0)))
|
||||
|
||||
if (props.meetingProp.isBreakout) {
|
||||
// This is a breakout room. Update the main meeting with list of users in this breakout room.
|
||||
|
@ -60,7 +60,7 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging {
|
||||
case m: RequestBreakoutJoinURLReqMsg => logMessage(msg)
|
||||
case m: EndAllBreakoutRoomsMsg => logMessage(msg)
|
||||
case m: TransferUserToMeetingRequestMsg => logMessage(msg)
|
||||
case m: ExtendBreakoutRoomsTimeReqMsg => logMessage(msg)
|
||||
case m: UpdateBreakoutRoomsTimeReqMsg => logMessage(msg)
|
||||
case m: SendMessageToAllBreakoutRoomsReqMsg => logMessage(msg)
|
||||
case m: UserLeftVoiceConfToClientEvtMsg => logMessage(msg)
|
||||
case m: UserLeftVoiceConfEvtMsg => logMessage(msg)
|
||||
|
@ -18,19 +18,19 @@ trait SendBreakoutTimeRemainingMsgHdlr {
|
||||
model <- state.breakout
|
||||
startedOn <- model.startedOn
|
||||
} yield {
|
||||
val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + TimeUtil.minutesToSeconds(model.durationInMinutes)
|
||||
val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + model.durationInSeconds
|
||||
val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis())
|
||||
|
||||
if (!liveMeeting.props.meetingProp.isBreakout) {
|
||||
// Notify parent meeting users of breakout rooms time remaining
|
||||
val event = buildBreakoutRoomsTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt)
|
||||
val event = buildBreakoutRoomsTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt, 0)
|
||||
outGW.send(event)
|
||||
}
|
||||
|
||||
// Tell all breakout rooms of time remaining so they can notify their users.
|
||||
// This syncs all rooms about time remaining.
|
||||
model.rooms.values.foreach { room =>
|
||||
eventBus.publish(BigBlueButtonEvent(room.id, SendBreakoutTimeRemainingInternalMsg(props.breakoutProps.parentId, timeRemaining.toInt)))
|
||||
eventBus.publish(BigBlueButtonEvent(room.id, SendBreakoutTimeRemainingInternalMsg(props.breakoutProps.parentId, timeRemaining.toInt, msg.timeUpdatedInMinutes)))
|
||||
}
|
||||
|
||||
if (timeRemaining < 0) {
|
||||
@ -41,7 +41,7 @@ trait SendBreakoutTimeRemainingMsgHdlr {
|
||||
state
|
||||
}
|
||||
|
||||
def buildBreakoutRoomsTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
|
||||
def buildBreakoutRoomsTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long, timeUpdatedInMinutes: Int = 0): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(BreakoutRoomsTimeRemainingUpdateEvtMsg.NAME, routing)
|
||||
val body = BreakoutRoomsTimeRemainingUpdateEvtMsgBody(timeLeftInSec)
|
||||
|
@ -545,10 +545,10 @@ object MsgBuilder {
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
|
||||
def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long, timeUpdatedInMinutes: Int = 0): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(MeetingTimeRemainingUpdateEvtMsg.NAME, routing)
|
||||
val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec)
|
||||
val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec, timeUpdatedInMinutes)
|
||||
val header = BbbClientMsgHeader(MeetingTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used")
|
||||
val event = MeetingTimeRemainingUpdateEvtMsg(header, body)
|
||||
|
||||
|
@ -31,7 +31,7 @@ case class BreakoutRoomsTimeRemainingUpdateEvtMsg(
|
||||
header: BbbClientMsgHeader,
|
||||
body: BreakoutRoomsTimeRemainingUpdateEvtMsgBody
|
||||
) extends BbbCoreMsg
|
||||
case class BreakoutRoomsTimeRemainingUpdateEvtMsgBody(timeRemaining: Long)
|
||||
case class BreakoutRoomsTimeRemainingUpdateEvtMsgBody(timeRemaining: Long, timeUpdatedInMinutes: Int)
|
||||
|
||||
/**
|
||||
* Sent to bbb-web to create breakout rooms.
|
||||
@ -94,13 +94,13 @@ object UpdateBreakoutUsersEvtMsg { val NAME = "UpdateBreakoutUsersEvtMsg" }
|
||||
case class UpdateBreakoutUsersEvtMsg(header: BbbClientMsgHeader, body: UpdateBreakoutUsersEvtMsgBody) extends BbbCoreMsg
|
||||
case class UpdateBreakoutUsersEvtMsgBody(parentId: String, breakoutId: String, users: Vector[BreakoutUserVO])
|
||||
|
||||
object ExtendBreakoutRoomsTimeReqMsg { val NAME = "ExtendBreakoutRoomsTimeReqMsg" }
|
||||
case class ExtendBreakoutRoomsTimeReqMsg(header: BbbClientMsgHeader, body: ExtendBreakoutRoomsTimeReqMsgBody) extends StandardMsg
|
||||
case class ExtendBreakoutRoomsTimeReqMsgBody(meetingId: String, extendTimeInMinutes: Int)
|
||||
object UpdateBreakoutRoomsTimeReqMsg { val NAME = "UpdateBreakoutRoomsTimeReqMsg" }
|
||||
case class UpdateBreakoutRoomsTimeReqMsg(header: BbbClientMsgHeader, body: UpdateBreakoutRoomsTimeReqMsgBody) extends StandardMsg
|
||||
case class UpdateBreakoutRoomsTimeReqMsgBody(meetingId: String, timeInMinutes: Int)
|
||||
|
||||
object ExtendBreakoutRoomsTimeEvtMsg { val NAME = "ExtendBreakoutRoomsTimeEvtMsg" }
|
||||
case class ExtendBreakoutRoomsTimeEvtMsg(header: BbbClientMsgHeader, body: ExtendBreakoutRoomsTimeEvtMsgBody) extends BbbCoreMsg
|
||||
case class ExtendBreakoutRoomsTimeEvtMsgBody(meetingId: String, extendTimeInMinutes: Int)
|
||||
object UpdateBreakoutRoomsTimeEvtMsg { val NAME = "UpdateBreakoutRoomsTimeEvtMsg" }
|
||||
case class UpdateBreakoutRoomsTimeEvtMsg(header: BbbClientMsgHeader, body: UpdateBreakoutRoomsTimeEvtMsgBody) extends BbbCoreMsg
|
||||
case class UpdateBreakoutRoomsTimeEvtMsgBody(meetingId: String, timeInMinutes: Int)
|
||||
|
||||
object SendMessageToAllBreakoutRoomsReqMsg { val NAME = "SendMessageToAllBreakoutRoomsReqMsg" }
|
||||
case class SendMessageToAllBreakoutRoomsReqMsg(header: BbbClientMsgHeader, body: SendMessageToAllBreakoutRoomsReqMsgBody) extends StandardMsg
|
||||
|
@ -2,13 +2,13 @@ import { Meteor } from 'meteor/meteor';
|
||||
import createBreakoutRoom from '/imports/api/breakouts/server/methods/createBreakout';
|
||||
import requestJoinURL from './methods/requestJoinURL';
|
||||
import endAllBreakouts from './methods/endAllBreakouts';
|
||||
import extendBreakoutsTime from './methods/extendBreakoutsTime';
|
||||
import setBreakoutsTime from '/imports/api/breakouts/server/methods/setBreakoutsTime';
|
||||
import sendMessageToAllBreakouts from './methods/sendMessageToAllBreakouts';
|
||||
|
||||
Meteor.methods({
|
||||
requestJoinURL,
|
||||
createBreakoutRoom,
|
||||
endAllBreakouts,
|
||||
extendBreakoutsTime,
|
||||
setBreakoutsTime,
|
||||
sendMessageToAllBreakouts,
|
||||
});
|
||||
|
@ -4,10 +4,10 @@ import { extractCredentials } from '/imports/api/common/server/helpers';
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default function extendBreakoutsTime({ extendTimeInMinutes }) {
|
||||
export default function setBreakoutsTime({ timeInMinutes }) {
|
||||
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'ExtendBreakoutRoomsTimeReqMsg';
|
||||
const EVENT_NAME = 'UpdateBreakoutRoomsTimeReqMsg';
|
||||
|
||||
try {
|
||||
const { meetingId, requesterUserId } = extractCredentials(this.userId);
|
||||
@ -15,14 +15,14 @@ export default function extendBreakoutsTime({ extendTimeInMinutes }) {
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
|
||||
return RedisPubSub.publishUserMessage(
|
||||
RedisPubSub.publishUserMessage(
|
||||
CHANNEL, EVENT_NAME, meetingId, requesterUserId,
|
||||
{
|
||||
meetingId,
|
||||
extendTimeInMinutes,
|
||||
timeInMinutes,
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method extendBreakoutsTime ${err.stack}`);
|
||||
Logger.error(`Exception while invoking method setBreakoutsTime ${err.stack}`);
|
||||
}
|
||||
}
|
@ -24,7 +24,8 @@ export default function addSystemMsg(meetingId, chatId, msg) {
|
||||
timestamp: Number,
|
||||
sender: Object,
|
||||
message: String,
|
||||
extra: Object,
|
||||
messageValues: Match.Maybe(Object),
|
||||
extra: Match.Maybe(Object),
|
||||
correlationId: Match.Maybe(String),
|
||||
});
|
||||
const msgDocument = {
|
||||
|
@ -1,14 +1,16 @@
|
||||
import { check } from 'meteor/check';
|
||||
import { MeetingTimeRemaining } from '/imports/api/meetings';
|
||||
import Meetings, { MeetingTimeRemaining } from '/imports/api/meetings';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import addSystemMsg from '/imports/api/group-chat-msg/server/modifiers/addSystemMsg';
|
||||
|
||||
export default function handleTimeRemainingUpdate({ body }, meetingId) {
|
||||
check(meetingId, String);
|
||||
|
||||
check(body, {
|
||||
timeLeftInSec: Number,
|
||||
timeUpdatedInMinutes: Number,
|
||||
});
|
||||
const { timeLeftInSec } = body;
|
||||
const { timeLeftInSec, timeUpdatedInMinutes } = body;
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
@ -25,4 +27,34 @@ export default function handleTimeRemainingUpdate({ body }, meetingId) {
|
||||
} catch (err) {
|
||||
Logger.error(`Changing recording time: ${err}`);
|
||||
}
|
||||
|
||||
if (timeUpdatedInMinutes > 0) {
|
||||
const Meeting = Meetings.findOne({ meetingId });
|
||||
|
||||
if (Meeting.meetingProp.isBreakout) {
|
||||
const CHAT_CONFIG = Meteor.settings.public.chat;
|
||||
const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id;
|
||||
const PUBLIC_CHAT_SYSTEM_ID = CHAT_CONFIG.system_userid;
|
||||
const PUBLIC_CHAT_INFO = CHAT_CONFIG.system_messages_keys.chat_info;
|
||||
const SYSTEM_CHAT_TYPE = CHAT_CONFIG.type_system;
|
||||
|
||||
const messageValues = {
|
||||
0: timeUpdatedInMinutes,
|
||||
};
|
||||
|
||||
const payload = {
|
||||
id: `${SYSTEM_CHAT_TYPE}-${PUBLIC_CHAT_INFO}`,
|
||||
timestamp: Date.now(),
|
||||
correlationId: `${PUBLIC_CHAT_SYSTEM_ID}-${Date.now()}`,
|
||||
sender: {
|
||||
id: PUBLIC_CHAT_SYSTEM_ID,
|
||||
name: '',
|
||||
},
|
||||
message: 'breakoutDurationUpdated',
|
||||
messageValues,
|
||||
};
|
||||
|
||||
addSystemMsg(meetingId, PUBLIC_GROUP_CHAT_ID, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,21 +63,21 @@ const intlMessages = defineMessages({
|
||||
id: 'app.createBreakoutRoom.alreadyConnected',
|
||||
description: 'label for the user that is already connected to breakout room',
|
||||
},
|
||||
extendTimeInMinutes: {
|
||||
id: 'app.createBreakoutRoom.extendTimeInMinutes',
|
||||
description: 'Label for input to extend time (minutes)',
|
||||
setTimeInMinutes: {
|
||||
id: 'app.createBreakoutRoom.setTimeInMinutes',
|
||||
description: 'Label for input to set time (minutes)',
|
||||
},
|
||||
extendTimeLabel: {
|
||||
id: 'app.createBreakoutRoom.extendTimeLabel',
|
||||
description: 'Button label to incresce breakout rooms time',
|
||||
setTimeLabel: {
|
||||
id: 'app.createBreakoutRoom.setTimeLabel',
|
||||
description: 'Button label to set breakout rooms time',
|
||||
},
|
||||
extendTimeCancel: {
|
||||
id: 'app.createBreakoutRoom.extendTimeCancel',
|
||||
description: 'Button label to cancel extend breakout rooms time',
|
||||
setTimeCancel: {
|
||||
id: 'app.createBreakoutRoom.setTimeCancel',
|
||||
description: 'Button label to cancel set breakout rooms time',
|
||||
},
|
||||
extendTimeHigherThanMeetingTimeError: {
|
||||
id: 'app.createBreakoutRoom.extendTimeHigherThanMeetingTimeError',
|
||||
description: 'Label for error when extend breakout rooms time would be higher than remaining time in parent meeting',
|
||||
setTimeHigherThanMeetingTimeError: {
|
||||
id: 'app.createBreakoutRoom.setTimeHigherThanMeetingTimeError',
|
||||
description: 'Label for error when new breakout rooms time would be higher than remaining time in parent meeting',
|
||||
},
|
||||
});
|
||||
|
||||
@ -104,9 +104,9 @@ class BreakoutRoom extends PureComponent {
|
||||
this.getBreakoutLabel = this.getBreakoutLabel.bind(this);
|
||||
this.renderDuration = this.renderDuration.bind(this);
|
||||
this.transferUserToBreakoutRoom = this.transferUserToBreakoutRoom.bind(this);
|
||||
this.changeExtendTime = this.changeExtendTime.bind(this);
|
||||
this.showExtendTimeForm = this.showExtendTimeForm.bind(this);
|
||||
this.resetExtendTimeForm = this.resetExtendTimeForm.bind(this);
|
||||
this.changeSetTime = this.changeSetTime.bind(this);
|
||||
this.showSetTimeForm = this.showSetTimeForm.bind(this);
|
||||
this.resetSetTimeForm = this.resetSetTimeForm.bind(this);
|
||||
this.renderUserActions = this.renderUserActions.bind(this);
|
||||
this.returnBackToMeeeting = this.returnBackToMeeeting.bind(this);
|
||||
this.closePanel = this.closePanel.bind(this);
|
||||
@ -116,9 +116,9 @@ class BreakoutRoom extends PureComponent {
|
||||
generated: false,
|
||||
joinedAudioOnly: false,
|
||||
breakoutId: '',
|
||||
visibleExtendTimeForm: false,
|
||||
visibleExtendTimeHigherThanMeetingTimeError: false,
|
||||
extendTime: 5,
|
||||
visibleSetTimeForm: false,
|
||||
visibleSetTimeHigherThanMeetingTimeError: false,
|
||||
newTime: 15,
|
||||
};
|
||||
}
|
||||
|
||||
@ -219,21 +219,21 @@ class BreakoutRoom extends PureComponent {
|
||||
this.setState({ joinedAudioOnly: false });
|
||||
}
|
||||
|
||||
changeExtendTime(event) {
|
||||
const newExtendTime = Number.parseInt(event.target.value, 10) || 0;
|
||||
this.setState({ extendTime: newExtendTime >= 0 ? newExtendTime : 0 });
|
||||
changeSetTime(event) {
|
||||
const newSetTime = Number.parseInt(event.target.value, 10) || 0;
|
||||
this.setState({ newTime: newSetTime >= 0 ? newSetTime : 0 });
|
||||
}
|
||||
|
||||
showExtendTimeForm() {
|
||||
this.setState({ visibleExtendTimeForm: true });
|
||||
showSetTimeForm() {
|
||||
this.setState({ visibleSetTimeForm: true });
|
||||
}
|
||||
|
||||
showExtendTimeHigherThanMeetingTimeError(show) {
|
||||
this.setState({ visibleExtendTimeHigherThanMeetingTimeError: show });
|
||||
showSetTimeHigherThanMeetingTimeError(show) {
|
||||
this.setState({ visibleSetTimeHigherThanMeetingTimeError: show });
|
||||
}
|
||||
|
||||
resetExtendTimeForm() {
|
||||
this.setState({ visibleExtendTimeForm: false, extendTime: 5 });
|
||||
resetSetTimeForm() {
|
||||
this.setState({ visibleSetTimeForm: false, newTime: 5 });
|
||||
}
|
||||
|
||||
transferUserToBreakoutRoom(breakoutId) {
|
||||
@ -436,35 +436,35 @@ class BreakoutRoom extends PureComponent {
|
||||
breakoutRooms,
|
||||
amIModerator,
|
||||
isMeteorConnected,
|
||||
extendBreakoutsTime,
|
||||
isExtendTimeHigherThanMeetingRemaining,
|
||||
setBreakoutsTime,
|
||||
isNewTimeHigherThanMeetingRemaining,
|
||||
} = this.props;
|
||||
const {
|
||||
extendTime,
|
||||
visibleExtendTimeForm,
|
||||
visibleExtendTimeHigherThanMeetingTimeError,
|
||||
newTime,
|
||||
visibleSetTimeForm,
|
||||
visibleSetTimeHigherThanMeetingTimeError,
|
||||
} = this.state;
|
||||
return (
|
||||
<Styled.DurationContainer>
|
||||
{amIModerator && visibleExtendTimeForm ? (
|
||||
<Styled.ExtendTimeContainer>
|
||||
<label htmlFor="inputExtendTimeSelector" >
|
||||
{intl.formatMessage(intlMessages.extendTimeInMinutes)}
|
||||
{amIModerator && visibleSetTimeForm ? (
|
||||
<Styled.SetTimeContainer>
|
||||
<label htmlFor="inputSetTimeSelector" >
|
||||
{intl.formatMessage(intlMessages.setTimeInMinutes)}
|
||||
</label>
|
||||
<br />
|
||||
<Styled.ExtendDurationInput
|
||||
id="inputExtendTimeSelector"
|
||||
<Styled.SetDurationInput
|
||||
id="inputSetTimeSelector"
|
||||
type="number"
|
||||
min="1"
|
||||
value={extendTime}
|
||||
onChange={this.changeExtendTime}
|
||||
aria-label={intl.formatMessage(intlMessages.extendTimeInMinutes)}
|
||||
value={newTime}
|
||||
onChange={this.changeSetTime}
|
||||
aria-label={intl.formatMessage(intlMessages.setTimeInMinutes)}
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
{visibleExtendTimeHigherThanMeetingTimeError ? (
|
||||
{visibleSetTimeHigherThanMeetingTimeError ? (
|
||||
<Styled.WithError>
|
||||
{intl.formatMessage(intlMessages.extendTimeHigherThanMeetingTimeError)}
|
||||
{intl.formatMessage(intlMessages.setTimeHigherThanMeetingTimeError)}
|
||||
<br />
|
||||
<br />
|
||||
</Styled.WithError>
|
||||
@ -473,42 +473,42 @@ class BreakoutRoom extends PureComponent {
|
||||
color="default"
|
||||
disabled={!isMeteorConnected}
|
||||
size="sm"
|
||||
label={intl.formatMessage(intlMessages.extendTimeCancel)}
|
||||
onClick={this.resetExtendTimeForm}
|
||||
label={intl.formatMessage(intlMessages.setTimeCancel)}
|
||||
onClick={this.resetSetTimeForm}
|
||||
/>
|
||||
<Styled.EndButton
|
||||
color="primary"
|
||||
disabled={!isMeteorConnected}
|
||||
size="sm"
|
||||
label={intl.formatMessage(intlMessages.extendTimeLabel)}
|
||||
label={intl.formatMessage(intlMessages.setTimeLabel)}
|
||||
onClick={() => {
|
||||
this.showExtendTimeHigherThanMeetingTimeError(false);
|
||||
this.showSetTimeHigherThanMeetingTimeError(false);
|
||||
|
||||
if (isExtendTimeHigherThanMeetingRemaining(extendTime)) {
|
||||
this.showExtendTimeHigherThanMeetingTimeError(true);
|
||||
} else if (extendBreakoutsTime(extendTime)) {
|
||||
this.resetExtendTimeForm();
|
||||
if (isNewTimeHigherThanMeetingRemaining(newTime)) {
|
||||
this.showSetTimeHigherThanMeetingTimeError(true);
|
||||
} else if (setBreakoutsTime(newTime)) {
|
||||
this.resetSetTimeForm();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Styled.ExtendTimeContainer>
|
||||
</Styled.SetTimeContainer>
|
||||
) : null}
|
||||
<Styled.Duration>
|
||||
<BreakoutRoomContainer
|
||||
messageDuration={intlMessages.breakoutDuration}
|
||||
breakoutRoom={breakoutRooms[0]}
|
||||
/>
|
||||
{amIModerator && !visibleExtendTimeForm
|
||||
{amIModerator && !visibleSetTimeForm
|
||||
? (
|
||||
<Button
|
||||
onClick={this.showExtendTimeForm}
|
||||
onClick={this.showSetTimeForm}
|
||||
color="default"
|
||||
icon="add"
|
||||
icon="more"
|
||||
circle
|
||||
hideLabel
|
||||
size="sm"
|
||||
label={intl.formatMessage(intlMessages.extendTimeLabel)}
|
||||
aria-label={intl.formatMessage(intlMessages.extendTimeLabel)}
|
||||
label={intl.formatMessage(intlMessages.setTimeInMinutes)}
|
||||
aria-label={intl.formatMessage(intlMessages.setTimeInMinutes)}
|
||||
disabled={!isMeteorConnected}
|
||||
/>
|
||||
)
|
||||
|
@ -24,9 +24,9 @@ export default withTracker((props) => {
|
||||
const {
|
||||
endAllBreakouts,
|
||||
requestJoinURL,
|
||||
extendBreakoutsTime,
|
||||
setBreakoutsTime,
|
||||
sendMessageToAllBreakouts,
|
||||
isExtendTimeHigherThanMeetingRemaining,
|
||||
isNewTimeHigherThanMeetingRemaining,
|
||||
findBreakouts,
|
||||
getBreakoutRoomUrl,
|
||||
transferUserToMeeting,
|
||||
@ -50,9 +50,9 @@ export default withTracker((props) => {
|
||||
breakoutRooms,
|
||||
endAllBreakouts,
|
||||
requestJoinURL,
|
||||
extendBreakoutsTime,
|
||||
setBreakoutsTime,
|
||||
sendMessageToAllBreakouts,
|
||||
isExtendTimeHigherThanMeetingRemaining,
|
||||
isNewTimeHigherThanMeetingRemaining,
|
||||
getBreakoutRoomUrl,
|
||||
transferUserToMeeting,
|
||||
transferToBreakout,
|
||||
|
@ -47,7 +47,7 @@ const requestJoinURL = (breakoutId) => {
|
||||
});
|
||||
};
|
||||
|
||||
const isExtendTimeHigherThanMeetingRemaining = (extendTimeInMinutes) => {
|
||||
const isNewTimeHigherThanMeetingRemaining = (newTimeInMinutes) => {
|
||||
const meetingId = Auth.meetingID;
|
||||
const meetingTimeRemaining = MeetingTimeRemaining.findOne({ meetingId });
|
||||
|
||||
@ -55,10 +55,7 @@ const isExtendTimeHigherThanMeetingRemaining = (extendTimeInMinutes) => {
|
||||
const { timeRemaining } = meetingTimeRemaining;
|
||||
|
||||
if (timeRemaining) {
|
||||
const breakoutRooms = findBreakouts();
|
||||
const breakoutRoomsTimeRemaining = breakoutRooms[0].timeRemaining;
|
||||
const newBreakoutRoomsRemainingTime =
|
||||
breakoutRoomsTimeRemaining + extendTimeInMinutes * 60;
|
||||
const newBreakoutRoomsRemainingTime = newTimeInMinutes * 60;
|
||||
// Keep margin of 5 seconds for breakout rooms end before parent meeting
|
||||
const meetingTimeRemainingWithMargin = timeRemaining - 5;
|
||||
|
||||
@ -71,11 +68,11 @@ const isExtendTimeHigherThanMeetingRemaining = (extendTimeInMinutes) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const extendBreakoutsTime = (extendTimeInMinutes) => {
|
||||
if (extendTimeInMinutes <= 0) return false;
|
||||
const setBreakoutsTime = (timeInMinutes) => {
|
||||
if (timeInMinutes <= 0) return false;
|
||||
|
||||
makeCall('extendBreakoutsTime', {
|
||||
extendTimeInMinutes,
|
||||
makeCall('setBreakoutsTime', {
|
||||
timeInMinutes,
|
||||
});
|
||||
|
||||
return true;
|
||||
@ -209,10 +206,10 @@ const isUserInBreakoutRoom = (joinedUsers) => {
|
||||
export default {
|
||||
findBreakouts,
|
||||
endAllBreakouts,
|
||||
extendBreakoutsTime,
|
||||
setBreakoutsTime,
|
||||
sendMessageToAllBreakouts,
|
||||
getUserMessagesToAllBreakouts,
|
||||
isExtendTimeHigherThanMeetingRemaining,
|
||||
isNewTimeHigherThanMeetingRemaining,
|
||||
requestJoinURL,
|
||||
getBreakoutRoomUrl,
|
||||
transferUserToMeeting,
|
||||
|
@ -154,13 +154,13 @@ const DurationContainer = styled.div`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const ExtendTimeContainer = styled.div`
|
||||
const SetTimeContainer = styled.div`
|
||||
border-top: 1px solid ${systemMessageBorderColor};
|
||||
border-bottom: 1px solid ${systemMessageBorderColor};
|
||||
padding: 10px 0px;
|
||||
`;
|
||||
|
||||
const ExtendDurationInput = styled.input`
|
||||
const SetDurationInput = styled.input`
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
padding: .25rem;
|
||||
@ -253,8 +253,8 @@ export default {
|
||||
BreakoutColumn,
|
||||
BreakoutScrollableList,
|
||||
DurationContainer,
|
||||
ExtendTimeContainer,
|
||||
ExtendDurationInput,
|
||||
SetTimeContainer,
|
||||
SetDurationInput,
|
||||
WithError,
|
||||
EndButton,
|
||||
Duration,
|
||||
|
@ -50,7 +50,11 @@ const intlMessages = defineMessages({
|
||||
[CHAT_CLEAR_MESSAGE]: {
|
||||
id: 'app.chat.clearPublicChatMessage',
|
||||
description: 'message of when clear the public chat',
|
||||
}
|
||||
},
|
||||
breakoutDurationUpdated: {
|
||||
id: 'app.chat.breakoutDurationUpdated',
|
||||
description: 'used when the breakout duration is updated',
|
||||
},
|
||||
});
|
||||
|
||||
class TimeWindowChatItem extends PureComponent {
|
||||
@ -89,6 +93,7 @@ class TimeWindowChatItem extends PureComponent {
|
||||
renderSystemMessage() {
|
||||
const {
|
||||
messages,
|
||||
messageValues,
|
||||
chatAreaId,
|
||||
handleReadMessage,
|
||||
messageKey,
|
||||
@ -104,13 +109,16 @@ class TimeWindowChatItem extends PureComponent {
|
||||
key={`time-window-chat-item-${messageKey}`}
|
||||
ref={element => this.itemRef = element} >
|
||||
<Styled.Messages>
|
||||
{messages.map(message => (
|
||||
{messages.map((message) => (
|
||||
message.text !== ''
|
||||
? (
|
||||
<Styled.SystemMessageChatItem
|
||||
border={message.id}
|
||||
key={message.id ? message.id : _.uniqueId('id-')}
|
||||
text={intlMessages[message.text] ? intl.formatMessage(intlMessages[message.text]) : message.text }
|
||||
text={intlMessages[message.text] ? intl.formatMessage(
|
||||
intlMessages[message.text],
|
||||
messageValues || {},
|
||||
) : message.text}
|
||||
time={message.time}
|
||||
isSystemMessage={message.id ? true : false}
|
||||
systemMessageType={message.text === CHAT_CLEAR_MESSAGE ? 'chatClearMessageText' : 'chatWelcomeMessageText'}
|
||||
|
@ -24,6 +24,7 @@ const TimeWindowChatItemContainer = (props) => {
|
||||
timestamp,
|
||||
content,
|
||||
extra,
|
||||
messageValues,
|
||||
} = message;
|
||||
const messages = content;
|
||||
|
||||
@ -49,6 +50,7 @@ const TimeWindowChatItemContainer = (props) => {
|
||||
read: message.read,
|
||||
messages,
|
||||
extra,
|
||||
messageValues,
|
||||
getPollResultString: PollService.getPollResultString,
|
||||
user,
|
||||
timestamp,
|
||||
|
@ -20,6 +20,7 @@
|
||||
"app.chat.label": "Chat",
|
||||
"app.chat.offline": "Offline",
|
||||
"app.chat.pollResult": "Poll Results",
|
||||
"app.chat.breakoutDurationUpdated": "Breakout time is now {0} minutes",
|
||||
"app.chat.emptyLogLabel": "Chat log empty",
|
||||
"app.chat.clearPublicChatMessage": "The public chat history was cleared by a moderator",
|
||||
"app.chat.multi.typing": "Multiple users are typing",
|
||||
@ -891,10 +892,10 @@
|
||||
"app.createBreakoutRoom.numberOfRoomsError": "The number of rooms is invalid.",
|
||||
"app.createBreakoutRoom.duplicatedRoomNameError": "Room name can't be duplicated.",
|
||||
"app.createBreakoutRoom.emptyRoomNameError": "Room name can't be empty.",
|
||||
"app.createBreakoutRoom.extendTimeInMinutes": "Time to extend (minutes)",
|
||||
"app.createBreakoutRoom.extendTimeLabel": "Extend",
|
||||
"app.createBreakoutRoom.extendTimeCancel": "Cancel",
|
||||
"app.createBreakoutRoom.extendTimeHigherThanMeetingTimeError": "The breakout rooms duration can't exceed the meeting remaining time.",
|
||||
"app.createBreakoutRoom.setTimeInMinutes": "Set duration to (minutes)",
|
||||
"app.createBreakoutRoom.setTimeLabel": "Apply",
|
||||
"app.createBreakoutRoom.setTimeCancel": "Cancel",
|
||||
"app.createBreakoutRoom.setTimeHigherThanMeetingTimeError": "The breakout rooms duration can't exceed the meeting remaining time.",
|
||||
"app.createBreakoutRoom.roomNameInputDesc": "Updates breakout room name",
|
||||
"app.externalVideo.start": "Share a new video",
|
||||
"app.externalVideo.title": "Share an external video",
|
||||
|
Loading…
Reference in New Issue
Block a user