2021-10-20 04:35:39 +08:00
|
|
|
import Breakouts from '/imports/api/breakouts';
|
2021-11-22 22:25:21 +08:00
|
|
|
import { MeetingTimeRemaining, Meetings } from '/imports/api/meetings';
|
2018-10-24 01:18:09 +08:00
|
|
|
import { makeCall } from '/imports/ui/services/api';
|
|
|
|
import Auth from '/imports/ui/services/auth';
|
2021-10-20 04:35:39 +08:00
|
|
|
import Users from '/imports/api/users';
|
2021-04-09 04:16:36 +08:00
|
|
|
import UserListService from '/imports/ui/components/user-list/service';
|
2019-06-07 21:49:50 +08:00
|
|
|
import fp from 'lodash/fp';
|
2021-11-22 22:25:21 +08:00
|
|
|
import UsersPersistentData from '/imports/api/users-persistent-data';
|
2018-10-24 01:18:09 +08:00
|
|
|
|
2019-08-22 20:05:06 +08:00
|
|
|
const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator;
|
|
|
|
|
2018-10-30 03:36:45 +08:00
|
|
|
const findBreakouts = () => {
|
2021-10-06 01:14:46 +08:00
|
|
|
const BreakoutRooms = Breakouts.find(
|
|
|
|
{
|
|
|
|
parentMeetingId: Auth.meetingID,
|
2018-11-02 01:55:35 +08:00
|
|
|
},
|
2021-10-06 01:14:46 +08:00
|
|
|
{
|
|
|
|
sort: {
|
|
|
|
sequence: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
).fetch();
|
2018-10-24 01:18:09 +08:00
|
|
|
|
|
|
|
return BreakoutRooms;
|
|
|
|
};
|
|
|
|
|
2021-10-01 21:44:01 +08:00
|
|
|
const getBreakoutRoomUrl = (breakoutId) => {
|
2018-10-30 03:36:45 +08:00
|
|
|
const breakoutRooms = findBreakouts();
|
2021-10-06 01:14:46 +08:00
|
|
|
const breakoutRoom = breakoutRooms
|
|
|
|
.filter((breakout) => breakout.breakoutId === breakoutId)
|
|
|
|
.shift();
|
|
|
|
const breakoutUrlData =
|
|
|
|
breakoutRoom && breakoutRoom[`url_${Auth.userID}`]
|
|
|
|
? breakoutRoom[`url_${Auth.userID}`]
|
|
|
|
: null;
|
2021-10-01 21:44:01 +08:00
|
|
|
return breakoutUrlData;
|
2018-10-24 01:18:09 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const endAllBreakouts = () => {
|
|
|
|
makeCall('endAllBreakouts');
|
|
|
|
};
|
|
|
|
|
|
|
|
const requestJoinURL = (breakoutId) => {
|
|
|
|
makeCall('requestJoinURL', {
|
|
|
|
breakoutId,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2022-02-21 19:14:34 +08:00
|
|
|
const isNewTimeHigherThanMeetingRemaining = (newTimeInMinutes) => {
|
2021-06-08 01:19:20 +08:00
|
|
|
const meetingId = Auth.meetingID;
|
|
|
|
const meetingTimeRemaining = MeetingTimeRemaining.findOne({ meetingId });
|
|
|
|
|
|
|
|
if (meetingTimeRemaining) {
|
|
|
|
const { timeRemaining } = meetingTimeRemaining;
|
|
|
|
|
|
|
|
if (timeRemaining) {
|
2022-02-21 19:14:34 +08:00
|
|
|
const newBreakoutRoomsRemainingTime = newTimeInMinutes * 60;
|
2021-06-08 01:19:20 +08:00
|
|
|
// Keep margin of 5 seconds for breakout rooms end before parent meeting
|
|
|
|
const meetingTimeRemainingWithMargin = timeRemaining - 5;
|
|
|
|
|
|
|
|
if (newBreakoutRoomsRemainingTime > meetingTimeRemainingWithMargin) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2022-02-21 19:14:34 +08:00
|
|
|
const setBreakoutsTime = (timeInMinutes) => {
|
|
|
|
if (timeInMinutes <= 0) return false;
|
2021-06-08 01:19:20 +08:00
|
|
|
|
2022-02-21 19:14:34 +08:00
|
|
|
makeCall('setBreakoutsTime', {
|
|
|
|
timeInMinutes,
|
2021-06-03 02:29:40 +08:00
|
|
|
});
|
2021-06-08 01:19:20 +08:00
|
|
|
|
|
|
|
return true;
|
2021-06-03 02:29:40 +08:00
|
|
|
};
|
|
|
|
|
2022-01-27 04:02:38 +08:00
|
|
|
const sendMessageToAllBreakouts = (msg) => {
|
|
|
|
makeCall('sendMessageToAllBreakouts', {
|
|
|
|
msg,
|
|
|
|
});
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2021-10-06 01:14:46 +08:00
|
|
|
const transferUserToMeeting = (fromMeetingId, toMeetingId) =>
|
|
|
|
makeCall('transferUser', fromMeetingId, toMeetingId);
|
2018-10-24 01:18:09 +08:00
|
|
|
|
2018-11-05 20:27:56 +08:00
|
|
|
const transferToBreakout = (breakoutId) => {
|
2018-10-30 03:36:45 +08:00
|
|
|
const breakoutRooms = findBreakouts();
|
2021-10-06 01:14:46 +08:00
|
|
|
const breakoutRoom = breakoutRooms
|
|
|
|
.filter((breakout) => breakout.breakoutId === breakoutId)
|
|
|
|
.shift();
|
|
|
|
const breakoutMeeting = Meetings.findOne(
|
|
|
|
{
|
|
|
|
$and: [
|
|
|
|
{ 'breakoutProps.sequence': breakoutRoom.sequence },
|
|
|
|
{ 'breakoutProps.parentId': breakoutRoom.parentMeetingId },
|
|
|
|
{ 'meetingProp.isBreakout': true },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{ fields: { meetingId: 1 } }
|
|
|
|
);
|
2018-11-05 20:27:56 +08:00
|
|
|
transferUserToMeeting(Auth.meetingID, breakoutMeeting.meetingId);
|
2018-10-24 01:18:09 +08:00
|
|
|
};
|
|
|
|
|
2019-09-07 04:28:02 +08:00
|
|
|
const amIModerator = () => {
|
2019-08-22 20:05:06 +08:00
|
|
|
const User = Users.findOne({ intId: Auth.userID }, { fields: { role: 1 } });
|
|
|
|
return User.role === ROLE_MODERATOR;
|
2018-11-02 01:55:35 +08:00
|
|
|
};
|
|
|
|
|
2021-02-09 01:40:03 +08:00
|
|
|
const checkInviteModerators = () => {
|
|
|
|
const BREAKOUTS_CONFIG = Meteor.settings.public.app.breakouts;
|
|
|
|
|
2021-10-06 01:14:46 +08:00
|
|
|
return !(
|
|
|
|
amIModerator() && !BREAKOUTS_CONFIG.sendInvitationToIncludedModerators
|
|
|
|
);
|
2021-02-09 01:40:03 +08:00
|
|
|
};
|
|
|
|
|
2021-10-06 01:14:46 +08:00
|
|
|
const getBreakoutByUserId = (userId) =>
|
|
|
|
Breakouts.find(
|
|
|
|
{ [`url_${userId}`]: { $exists: true } },
|
2022-04-12 20:50:19 +08:00
|
|
|
{ fields: { timeRemaining: 0 } },
|
2021-10-06 01:14:46 +08:00
|
|
|
).fetch();
|
2019-06-07 21:49:50 +08:00
|
|
|
|
2022-04-12 20:50:19 +08:00
|
|
|
const getWithBreakoutUrlData = (userId) => (breakoutsArray) => breakoutsArray
|
|
|
|
.map((breakout) => {
|
|
|
|
if (typeof breakout[`url_${userId}`] === 'object') {
|
|
|
|
return Object.assign(breakout, { breakoutUrlData: breakout[`url_${userId}`] });
|
|
|
|
}
|
|
|
|
return Object.assign(breakout, { breakoutUrlData: { insertedTime: 0 } });
|
|
|
|
})
|
|
|
|
.reduce((acc, urlDataArray) => acc.concat(urlDataArray), []);
|
2021-10-06 01:14:46 +08:00
|
|
|
|
2022-04-12 20:50:19 +08:00
|
|
|
const getLastBreakoutInserted = (breakoutURLArray) => breakoutURLArray.sort((a, b) => {
|
|
|
|
return a.breakoutUrlData.insertedTime - b.breakoutUrlData.insertedTime;
|
|
|
|
}).pop();
|
2021-10-06 01:14:46 +08:00
|
|
|
|
2022-04-12 20:50:19 +08:00
|
|
|
const getLastBreakoutByUserId = (userId) => fp.pipe(
|
|
|
|
getBreakoutByUserId,
|
|
|
|
getWithBreakoutUrlData(userId),
|
|
|
|
getLastBreakoutInserted,
|
|
|
|
)(userId);
|
2021-10-06 01:14:46 +08:00
|
|
|
|
|
|
|
const getBreakouts = () =>
|
|
|
|
Breakouts.find({}, { sort: { sequence: 1 } }).fetch();
|
|
|
|
const getBreakoutsNoTime = () =>
|
|
|
|
Breakouts.find(
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
sort: { sequence: 1 },
|
|
|
|
fields: { timeRemaining: 0 },
|
|
|
|
}
|
|
|
|
).fetch();
|
2019-09-19 04:06:59 +08:00
|
|
|
|
2021-10-06 01:14:46 +08:00
|
|
|
const getBreakoutUserIsIn = (userId) =>
|
|
|
|
Breakouts.findOne(
|
|
|
|
{ 'joinedUsers.userId': new RegExp(`^${userId}`) },
|
|
|
|
{ fields: { sequence: 1 } }
|
|
|
|
);
|
2019-04-24 20:50:45 +08:00
|
|
|
|
2021-11-11 21:10:31 +08:00
|
|
|
const getBreakoutUserWasIn = (userId, extId) => {
|
|
|
|
const selector = {
|
|
|
|
meetingId: Auth.meetingID,
|
|
|
|
lastBreakoutRoom: { $exists: 1 },
|
|
|
|
};
|
|
|
|
|
|
|
|
if (extId !== null) {
|
|
|
|
selector.extId = extId;
|
|
|
|
} else {
|
|
|
|
selector.userId = userId;
|
|
|
|
}
|
|
|
|
|
|
|
|
const users = UsersPersistentData.find(
|
|
|
|
selector,
|
|
|
|
{ fields: { userId: 1, lastBreakoutRoom: 1 } },
|
|
|
|
).fetch();
|
|
|
|
|
|
|
|
if (users.length > 0) {
|
|
|
|
const hasCurrUserId = users.filter((user) => user.userId === userId);
|
|
|
|
if (hasCurrUserId.length > 0) return hasCurrUserId.pop().lastBreakoutRoom;
|
|
|
|
|
|
|
|
return users.pop().lastBreakoutRoom;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
2019-09-28 06:59:55 +08:00
|
|
|
const isUserInBreakoutRoom = (joinedUsers) => {
|
|
|
|
const userId = Auth.userID;
|
|
|
|
|
2021-10-01 21:44:01 +08:00
|
|
|
return !!joinedUsers.find((user) => user.userId.startsWith(userId));
|
2019-09-28 06:59:55 +08:00
|
|
|
};
|
2019-09-19 02:55:06 +08:00
|
|
|
|
2018-10-24 01:18:09 +08:00
|
|
|
export default {
|
2018-10-30 03:36:45 +08:00
|
|
|
findBreakouts,
|
2018-10-24 01:18:09 +08:00
|
|
|
endAllBreakouts,
|
2022-02-21 19:14:34 +08:00
|
|
|
setBreakoutsTime,
|
2022-01-27 04:02:38 +08:00
|
|
|
sendMessageToAllBreakouts,
|
2022-02-21 19:14:34 +08:00
|
|
|
isNewTimeHigherThanMeetingRemaining,
|
2018-10-24 01:18:09 +08:00
|
|
|
requestJoinURL,
|
2021-10-01 21:44:01 +08:00
|
|
|
getBreakoutRoomUrl,
|
2018-10-24 01:18:09 +08:00
|
|
|
transferUserToMeeting,
|
|
|
|
transferToBreakout,
|
2018-11-05 20:27:56 +08:00
|
|
|
meetingId: () => Auth.meetingID,
|
2019-09-07 04:28:02 +08:00
|
|
|
amIModerator,
|
2022-04-12 20:50:19 +08:00
|
|
|
getLastBreakoutByUserId,
|
2019-06-07 21:49:50 +08:00
|
|
|
getBreakouts,
|
2019-09-19 04:06:59 +08:00
|
|
|
getBreakoutsNoTime,
|
|
|
|
getBreakoutUserIsIn,
|
2021-11-11 21:10:31 +08:00
|
|
|
getBreakoutUserWasIn,
|
2021-04-09 04:16:36 +08:00
|
|
|
sortUsersByName: UserListService.sortUsersByName,
|
2019-09-19 02:55:06 +08:00
|
|
|
isUserInBreakoutRoom,
|
2021-02-09 01:40:03 +08:00
|
|
|
checkInviteModerators,
|
2018-10-24 01:18:09 +08:00
|
|
|
};
|