Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
5eff7578cb
@ -17,6 +17,27 @@ object BreakoutHdlrHelpers extends SystemConfiguration {
|
||||
roomSequence: String,
|
||||
breakoutId: String
|
||||
) {
|
||||
for {
|
||||
(redirectToHtml5JoinURL, redirectJoinURL) <- getRedirectUrls(liveMeeting, userId, externalMeetingId, roomSequence)
|
||||
} yield {
|
||||
sendJoinURLMsg(
|
||||
outGW,
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
breakoutId,
|
||||
externalMeetingId,
|
||||
userId,
|
||||
redirectJoinURL,
|
||||
redirectToHtml5JoinURL
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def getRedirectUrls(
|
||||
liveMeeting: LiveMeeting,
|
||||
userId: String,
|
||||
externalMeetingId: String,
|
||||
roomSequence: String
|
||||
): Option[(String, String)] = {
|
||||
for {
|
||||
user <- Users2x.findWithIntId(liveMeeting.users2x, userId)
|
||||
apiCall = "join"
|
||||
@ -31,15 +52,7 @@ object BreakoutHdlrHelpers extends SystemConfiguration {
|
||||
redirectToHtml5JoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, redirectToHtml5BaseString,
|
||||
BreakoutRoomsUtil.calculateChecksum(apiCall, redirectToHtml5BaseString, bbbWebSharedSecret))
|
||||
} yield {
|
||||
sendJoinURLMsg(
|
||||
outGW,
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
breakoutId,
|
||||
externalMeetingId,
|
||||
userId,
|
||||
redirectJoinURL,
|
||||
redirectToHtml5JoinURL
|
||||
)
|
||||
(redirectToHtml5JoinURL, redirectJoinURL)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ trait BreakoutRoomCreatedMsgHdlr {
|
||||
if (updatedModel.hasAllStarted()) {
|
||||
updatedModel = updatedModel.copy(startedOn = Some(System.currentTimeMillis()))
|
||||
updatedModel = sendBreakoutRoomsList(updatedModel)
|
||||
updatedModel = sendBreakoutInvitations(updatedModel)
|
||||
}
|
||||
updatedModel
|
||||
}
|
||||
@ -36,25 +35,6 @@ trait BreakoutRoomCreatedMsgHdlr {
|
||||
}
|
||||
}
|
||||
|
||||
def sendBreakoutInvitations(breakoutModel: BreakoutModel): BreakoutModel = {
|
||||
log.debug("Sending breakout invitations")
|
||||
breakoutModel.rooms.values.foreach { room =>
|
||||
log.debug("Sending invitations for room {} with num users {}", room.name, room.assignedUsers.toVector.length)
|
||||
room.assignedUsers.foreach { user =>
|
||||
BreakoutHdlrHelpers.sendJoinURL(
|
||||
liveMeeting,
|
||||
outGW,
|
||||
user,
|
||||
room.externalId,
|
||||
room.sequence.toString(),
|
||||
room.id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
breakoutModel
|
||||
}
|
||||
|
||||
def buildBreakoutRoomsListEvtMsg(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(BreakoutRoomsListEvtMsg.NAME, routing)
|
||||
@ -63,12 +43,16 @@ trait BreakoutRoomCreatedMsgHdlr {
|
||||
val body = BreakoutRoomsListEvtMsgBody(meetingId, rooms, roomsReady)
|
||||
val event = BreakoutRoomsListEvtMsg(header, body)
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
|
||||
}
|
||||
|
||||
def sendBreakoutRoomsList(breakoutModel: BreakoutModel): BreakoutModel = {
|
||||
val breakoutRooms = breakoutModel.rooms.values.toVector map { r =>
|
||||
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin)
|
||||
val html5JoinUrls = for {
|
||||
user <- r.assignedUsers
|
||||
(redirectToHtml5JoinURL, redirectJoinURL) <- BreakoutHdlrHelpers.getRedirectUrls(liveMeeting, user, r.externalId, r.sequence.toString())
|
||||
} yield (user -> redirectToHtml5JoinURL)
|
||||
|
||||
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin, html5JoinUrls.toMap)
|
||||
}
|
||||
|
||||
log.info("Sending breakout rooms list to {} with containing {} room(s)", liveMeeting.props.meetingProp.intId, breakoutRooms.length)
|
||||
@ -95,7 +79,7 @@ trait BreakoutRoomCreatedMsgHdlr {
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence, room.shortName, room.isDefaultName, room.freeJoin)
|
||||
val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence, room.shortName, room.isDefaultName, room.freeJoin, Map())
|
||||
val event = build(liveMeeting.props.meetingProp.intId, breakoutInfo)
|
||||
outGW.send(event)
|
||||
|
||||
|
@ -28,7 +28,7 @@ trait BreakoutRoomsListMsgHdlr {
|
||||
breakoutModel <- state.breakout
|
||||
} yield {
|
||||
val rooms = breakoutModel.rooms.values.toVector map { r =>
|
||||
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin)
|
||||
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin, Map())
|
||||
}
|
||||
val ready = breakoutModel.hasAllStarted()
|
||||
broadcastEvent(rooms, ready)
|
||||
|
@ -101,8 +101,6 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender)
|
||||
msgSender.send(fromAkkaAppsPresRedisChannel, json)
|
||||
case BreakoutRoomsListEvtMsg.NAME =>
|
||||
msgSender.send(fromAkkaAppsPresRedisChannel, json)
|
||||
case BreakoutRoomJoinURLEvtMsg.NAME =>
|
||||
msgSender.send(fromAkkaAppsPresRedisChannel, json)
|
||||
case BreakoutRoomsTimeRemainingUpdateEvtMsg.NAME =>
|
||||
msgSender.send(fromAkkaAppsPresRedisChannel, json)
|
||||
case BreakoutRoomStartedEvtMsg.NAME =>
|
||||
|
@ -35,7 +35,7 @@ case class User(
|
||||
name: String,
|
||||
isModerator: Boolean,
|
||||
isDialIn: Boolean = false,
|
||||
answers: Map[String,String] = Map(),
|
||||
answers: Map[String,Vector[String]] = Map(),
|
||||
talk: Talk = Talk(),
|
||||
emojis: Vector[Emoji] = Vector(),
|
||||
webcams: Vector[Webcam] = Vector(),
|
||||
@ -48,6 +48,7 @@ case class Poll(
|
||||
pollId: String,
|
||||
pollType: String,
|
||||
anonymous: Boolean,
|
||||
multiple: Boolean,
|
||||
question: String,
|
||||
options: Vector[String] = Vector(),
|
||||
anonymousAnswers: Vector[String] = Vector(),
|
||||
@ -390,7 +391,7 @@ class LearningDashboardActor(
|
||||
meeting <- meetings.values.find(m => m.intId == msg.header.meetingId)
|
||||
} yield {
|
||||
val options = msg.body.poll.answers.map(answer => answer.key)
|
||||
val newPoll = Poll(msg.body.pollId, msg.body.pollType, msg.body.secretPoll, msg.body.question, options.toVector)
|
||||
val newPoll = Poll(msg.body.pollId, msg.body.pollType, msg.body.secretPoll, msg.body.poll.isMultipleResponse, msg.body.question, options.toVector)
|
||||
|
||||
val updatedMeeting = meeting.copy(polls = meeting.polls + (newPoll.pollId -> newPoll))
|
||||
meetings += (updatedMeeting.intId -> updatedMeeting)
|
||||
@ -413,7 +414,7 @@ class LearningDashboardActor(
|
||||
}
|
||||
} else {
|
||||
//Store Public Poll in `user.answers`
|
||||
val updatedUser = user.copy(answers = user.answers + (msg.body.pollId -> msg.body.answer))
|
||||
val updatedUser = user.copy(answers = user.answers + (msg.body.pollId -> (user.answers.get(msg.body.pollId).getOrElse(Vector()) :+ msg.body.answer)))
|
||||
val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.intId -> updatedUser))
|
||||
meetings += (updatedMeeting.intId -> updatedMeeting)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ case class BreakoutRoomJoinURLEvtMsgBody(parentId: String, breakoutId: String, e
|
||||
object BreakoutRoomsListEvtMsg { val NAME = "BreakoutRoomsListEvtMsg" }
|
||||
case class BreakoutRoomsListEvtMsg(header: BbbClientMsgHeader, body: BreakoutRoomsListEvtMsgBody) extends BbbCoreMsg
|
||||
case class BreakoutRoomsListEvtMsgBody(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean)
|
||||
case class BreakoutRoomInfo(name: String, externalId: String, breakoutId: String, sequence: Int, shortName: String, isDefaultName: Boolean, freeJoin: Boolean)
|
||||
case class BreakoutRoomInfo(name: String, externalId: String, breakoutId: String, sequence: Int, shortName: String, isDefaultName: Boolean, freeJoin: Boolean, html5JoinUrls: Map[String, String])
|
||||
|
||||
object BreakoutRoomsListMsg { val NAME = "BreakoutRoomsListMsg" }
|
||||
case class BreakoutRoomsListMsg(header: BbbClientMsgHeader, body: BreakoutRoomsListMsgBody) extends StandardMsg
|
||||
@ -81,14 +81,6 @@ object RequestBreakoutJoinURLReqMsg { val NAME = "RequestBreakoutJoinURLReqMsg"
|
||||
case class RequestBreakoutJoinURLReqMsg(header: BbbClientMsgHeader, body: RequestBreakoutJoinURLReqMsgBody) extends StandardMsg
|
||||
case class RequestBreakoutJoinURLReqMsgBody(meetingId: String, breakoutId: String, userId: String)
|
||||
|
||||
/**
|
||||
* Response sent to client for a join url for a user.
|
||||
*/
|
||||
object RequestBreakoutJoinURLRespMsg { val NAME = "RequestBreakoutJoinURLRespMsg" }
|
||||
case class RequestBreakoutJoinURLRespMsg(header: BbbClientMsgHeader, body: RequestBreakoutJoinURLRespMsgBody) extends BbbCoreMsg
|
||||
case class RequestBreakoutJoinURLRespMsgBody(parentId: String, breakoutId: String,
|
||||
userId: String, redirectJoinURL: String, redirectToHtml5JoinURL: String)
|
||||
|
||||
object TransferUserToMeetingEvtMsg { val NAME = "TransferUserToMeetingEvtMsg" }
|
||||
case class TransferUserToMeetingEvtMsg(header: BbbClientMsgHeader, body: TransferUserToMeetingEvtMsgBody) extends BbbCoreMsg
|
||||
case class TransferUserToMeetingEvtMsgBody(fromVoiceConf: String, toVoiceConf: String, userId: String)
|
||||
|
@ -11,7 +11,7 @@ class PollsTable extends React.Component {
|
||||
if (typeof user.answers[poll.pollId] !== 'undefined') {
|
||||
return user.answers[poll.pollId];
|
||||
}
|
||||
return '';
|
||||
return [];
|
||||
}
|
||||
|
||||
if (typeof polls === 'object' && Object.values(polls).length === 0) {
|
||||
@ -96,9 +96,11 @@ class PollsTable extends React.Component {
|
||||
</td>
|
||||
|
||||
{typeof polls === 'object' && Object.values(polls || {}).length > 0 ? (
|
||||
Object.values(polls || {}).map((poll) => (
|
||||
Object.values(polls || {})
|
||||
.sort((a, b) => ((a.createdOn > b.createdOn) ? 1 : -1))
|
||||
.map((poll) => (
|
||||
<td className="px-4 py-3 text-sm text-center">
|
||||
{ getUserAnswer(user, poll) }
|
||||
{ getUserAnswer(user, poll).map((answer) => <p>{answer}</p>) }
|
||||
{ poll.anonymous
|
||||
? (
|
||||
<span title={intl.formatMessage({
|
||||
@ -162,7 +164,9 @@ class PollsTable extends React.Component {
|
||||
</div>
|
||||
</td>
|
||||
{typeof polls === 'object' && Object.values(polls || {}).length > 0 ? (
|
||||
Object.values(polls || {}).map((poll) => (
|
||||
Object.values(polls || {})
|
||||
.sort((a, b) => ((a.createdOn > b.createdOn) ? 1 : -1))
|
||||
.map((poll) => (
|
||||
<td className="px-4 py-3 text-sm text-center">
|
||||
{ poll.anonymousAnswers.map((answer) => <p>{answer}</p>) }
|
||||
</td>
|
||||
|
@ -48,6 +48,8 @@ FILE_SUDOERS_CHECK=`[ -f /etc/sudoers.d/zzz-bbb-docker-libreoffice ] && echo 1 |
|
||||
if [ "$FILE_SUDOERS_CHECK" = "0" ]; then
|
||||
echo "Sudoers file doesn't exists, installing"
|
||||
cp assets/zzz-bbb-docker-libreoffice /etc/sudoers.d/zzz-bbb-docker-libreoffice
|
||||
chmod 0440 /etc/sudoers.d/zzz-bbb-docker-libreoffice
|
||||
chown root:root /etc/sudoers.d/zzz-bbb-docker-libreoffice
|
||||
else
|
||||
echo "Sudoers file already exists"
|
||||
fi;
|
||||
|
@ -1,15 +1,12 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import handleBreakoutJoinURL from './handlers/breakoutJoinURL';
|
||||
import handleBreakoutStarted from './handlers/breakoutStarted';
|
||||
import handleBreakoutRoomsList from './handlers/breakoutList';
|
||||
import handleUpdateTimeRemaining from './handlers/updateTimeRemaining';
|
||||
import handleBreakoutClosed from './handlers/breakoutClosed';
|
||||
import joinedUsersChanged from './handlers/joinedUsersChanged';
|
||||
import handleBreakoutRoomsList from '/imports/api/breakouts-history/server/handlers/breakoutRoomsList';
|
||||
|
||||
RedisPubSub.on('BreakoutRoomStartedEvtMsg', handleBreakoutStarted);
|
||||
RedisPubSub.on('BreakoutRoomsListEvtMsg', handleBreakoutRoomsList);
|
||||
RedisPubSub.on('BreakoutRoomJoinURLEvtMsg', handleBreakoutJoinURL);
|
||||
RedisPubSub.on('RequestBreakoutJoinURLRespMsg', handleBreakoutJoinURL);
|
||||
RedisPubSub.on('BreakoutRoomsTimeRemainingUpdateEvtMsg', handleUpdateTimeRemaining);
|
||||
RedisPubSub.on('BreakoutRoomEndedEvtMsg', handleBreakoutClosed);
|
||||
RedisPubSub.on('UpdateBreakoutUsersEvtMsg', joinedUsersChanged);
|
||||
RedisPubSub.on('BreakoutRoomsListEvtMsg', handleBreakoutRoomsList);
|
||||
|
@ -0,0 +1,60 @@
|
||||
import Breakouts from '/imports/api/breakouts';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
import flat from 'flat';
|
||||
import handleBreakoutRoomsListHist from '/imports/api/breakouts-history/server/handlers/breakoutRoomsList';
|
||||
|
||||
export default function handleBreakoutRoomsList({ body }, meetingId) {
|
||||
// 0 seconds default breakout time, forces use of real expiration time
|
||||
const DEFAULT_TIME_REMAINING = 0;
|
||||
|
||||
const {
|
||||
meetingId: parentMeetingId,
|
||||
rooms,
|
||||
} = body;
|
||||
|
||||
// set firstly the last seq, then client will know when receive all
|
||||
rooms.sort((a, b) => ((a.sequence < b.sequence) ? 1 : -1)).forEach((breakout) => {
|
||||
const { breakoutId, html5JoinUrls, ...breakoutWithoutUrls } = breakout;
|
||||
|
||||
check(meetingId, String);
|
||||
|
||||
const selector = {
|
||||
breakoutId,
|
||||
};
|
||||
|
||||
const urls = {};
|
||||
if (typeof html5JoinUrls === 'object' && Object.keys(html5JoinUrls).length > 0) {
|
||||
Object.keys(html5JoinUrls).forEach((userId) => {
|
||||
urls[`url_${userId}`] = {
|
||||
redirectToHtml5JoinURL: html5JoinUrls[userId],
|
||||
insertedTime: new Date().getTime(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const modifier = {
|
||||
$set: {
|
||||
breakoutId,
|
||||
joinedUsers: [],
|
||||
timeRemaining: DEFAULT_TIME_REMAINING,
|
||||
parentMeetingId,
|
||||
...flat(breakoutWithoutUrls),
|
||||
...urls,
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const { numberAffected } = Breakouts.upsert(selector, modifier);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info('Updated timeRemaining and externalMeetingId '
|
||||
+ `for breakout id=${breakoutId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`updating breakout: ${err}`);
|
||||
}
|
||||
});
|
||||
|
||||
handleBreakoutRoomsListHist({ body });
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import Breakouts from '/imports/api/breakouts';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
import flat from 'flat';
|
||||
|
||||
export default function handleBreakoutRoomStarted({ body }, meetingId) {
|
||||
// 0 seconds default breakout time, forces use of real expiration time
|
||||
const DEFAULT_TIME_REMAINING = 0;
|
||||
|
||||
const {
|
||||
parentMeetingId,
|
||||
breakout,
|
||||
} = body;
|
||||
|
||||
const { breakoutId } = breakout;
|
||||
|
||||
check(meetingId, String);
|
||||
|
||||
const selector = {
|
||||
breakoutId,
|
||||
};
|
||||
|
||||
const modifier = {
|
||||
$set: Object.assign(
|
||||
{
|
||||
joinedUsers: [],
|
||||
},
|
||||
{ timeRemaining: DEFAULT_TIME_REMAINING },
|
||||
{ parentMeetingId },
|
||||
flat(breakout),
|
||||
),
|
||||
};
|
||||
|
||||
try {
|
||||
const { numberAffected } = Breakouts.upsert(selector, modifier);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info('Updated timeRemaining and externalMeetingId '
|
||||
+ `for breakout id=${breakoutId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`updating breakout: ${err}`);
|
||||
}
|
||||
}
|
@ -66,25 +66,27 @@ class BreakoutRoomInvitation extends Component {
|
||||
const hasBreakouts = breakouts.length > 0;
|
||||
|
||||
if (hasBreakouts && !breakoutUserIsIn && BreakoutService.checkInviteModerators()) {
|
||||
// Have to check for freeJoin breakouts first because currentBreakoutUrlData will
|
||||
// populate after a room has been joined
|
||||
const freeJoinRooms = breakouts.filter((breakout) => breakout.freeJoin);
|
||||
|
||||
if (currentBreakoutUrlData) {
|
||||
const breakoutRoom = getBreakoutByUrlData(currentBreakoutUrlData);
|
||||
const freeJoinBreakout = breakouts.find((breakout) => breakout.freeJoin);
|
||||
if (freeJoinBreakout) {
|
||||
if (!didSendBreakoutInvite) {
|
||||
this.inviteUserToBreakout(breakoutRoom || freeJoinBreakout);
|
||||
this.setState({ didSendBreakoutInvite: true });
|
||||
}
|
||||
} else if (currentBreakoutUrlData) {
|
||||
const currentInsertedTime = currentBreakoutUrlData.insertedTime;
|
||||
const oldCurrentUrlData = oldProps.currentBreakoutUrlData || {};
|
||||
const oldInsertedTime = oldCurrentUrlData.insertedTime;
|
||||
if (currentInsertedTime !== oldInsertedTime) {
|
||||
const breakoutId = Session.get('lastBreakoutOpened');
|
||||
if (breakoutRoom.breakoutId !== breakoutId) {
|
||||
const lastBreakoutId = Session.get('lastBreakoutOpened');
|
||||
if (breakoutRoom.breakoutId !== lastBreakoutId) {
|
||||
this.inviteUserToBreakout(breakoutRoom);
|
||||
}
|
||||
}
|
||||
} else if (freeJoinRooms.length > 0 && !didSendBreakoutInvite) {
|
||||
const maxSeq = Math.max(...freeJoinRooms.map(((room) => room.sequence)));
|
||||
// Check if received all rooms and Pick a room randomly
|
||||
if (maxSeq === freeJoinRooms.length) {
|
||||
const randomRoom = freeJoinRooms[Math.floor(Math.random() * freeJoinRooms.length)];
|
||||
this.inviteUserToBreakout(randomRoom);
|
||||
this.setState({ didSendBreakoutInvite: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
import { colorDanger, colorGrayDark } from '/imports/ui/stylesheets/styled-components/palette';
|
||||
import { borderSize } from '/imports/ui/stylesheets/styled-components/general';
|
||||
import { fontSizeSmaller, fontSizeMD, fontSizeBase } from '/imports/ui/stylesheets/styled-components/typography';
|
||||
import { fontSizeSmaller, fontSizeBase } from '/imports/ui/stylesheets/styled-components/typography';
|
||||
|
||||
const SingleTyper = styled.span`
|
||||
overflow: hidden;
|
||||
@ -29,7 +29,6 @@ const TypingIndicator = styled.span`
|
||||
display: block;
|
||||
margin-right: 0.05rem;
|
||||
margin-left: 0.05rem;
|
||||
line-height: ${fontSizeMD};
|
||||
}
|
||||
|
||||
text-align: left;
|
||||
|
@ -22,7 +22,7 @@ export default withTracker((params) => {
|
||||
} = params;
|
||||
|
||||
const fetchFunc = published
|
||||
? AnnotationGroupService.getCurrentAnnotationsInfo : AnnotationGroupService.getUnsetAnnotations;
|
||||
? AnnotationGroupService.getCurrentAnnotationsInfo : AnnotationGroupService.getUnsentAnnotations;
|
||||
|
||||
const annotationsInfo = fetchFunc(whiteboardId);
|
||||
return {
|
||||
|
@ -16,7 +16,7 @@ const getCurrentAnnotationsInfo = (whiteboardId) => {
|
||||
).fetch();
|
||||
};
|
||||
|
||||
const getUnsetAnnotations = (whiteboardId) => {
|
||||
const getUnsentAnnotations = (whiteboardId) => {
|
||||
if (!whiteboardId) {
|
||||
return null;
|
||||
}
|
||||
@ -34,5 +34,5 @@ const getUnsetAnnotations = (whiteboardId) => {
|
||||
|
||||
export default {
|
||||
getCurrentAnnotationsInfo,
|
||||
getUnsetAnnotations,
|
||||
getUnsentAnnotations,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user