bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/chat/service.js

236 lines
6.3 KiB
JavaScript
Raw Normal View History

2017-07-12 20:42:16 +08:00
import Chats from '/imports/api/2.0/chat';
import Users from '/imports/api/2.0/users';
2016-06-14 01:00:38 +08:00
import Auth from '/imports/ui/services/auth';
2016-07-05 02:53:47 +08:00
import UnreadMessages from '/imports/ui/services/unread-messages';
2017-03-01 06:40:16 +08:00
import Storage from '/imports/ui/services/storage/session';
2017-04-26 21:47:44 +08:00
import { makeCall } from '/imports/ui/services/api';
2017-03-22 05:52:10 +08:00
import _ from 'lodash';
const CHAT_CONFIG = Meteor.settings.public.chat;
const GROUPING_MESSAGES_WINDOW = CHAT_CONFIG.grouping_messages_window;
2016-06-02 00:33:19 +08:00
const SYSTEM_CHAT_TYPE = CHAT_CONFIG.type_system;
2016-06-02 00:33:19 +08:00
const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id;
const PUBLIC_CHAT_USERID = CHAT_CONFIG.public_userid;
const PUBLIC_CHAT_USERNAME = CHAT_CONFIG.public_username;
2016-07-01 01:10:36 +08:00
const ScrollCollection = new Mongo.Collection(null);
// session for closed chat list
const CLOSED_CHAT_LIST_KEY = 'closedChatList';
/* TODO: Same map is done in the user-list/service we should share this someway */
2017-06-03 03:25:02 +08:00
const mapUser = user => ({
2017-07-26 22:09:07 +08:00
id: user.userId,
name: user.name,
2016-07-09 03:09:16 +08:00
emoji: {
2017-07-13 21:15:42 +08:00
status: user.emoji,
2017-07-26 22:09:07 +08:00
changedAt: user.emojiTime,
2016-07-09 03:09:16 +08:00
},
isPresenter: user.presenter,
isModerator: user.role === 'MODERATOR',
2017-07-26 22:09:07 +08:00
isCurrent: user.userId === Auth.userID,
isVoiceUser: false, // FIXME user.voiceUser.joined,
isOnline: user.connectionStatus === 'online',
isMuted: false, // FIXME user.voiceUser.muted,
isListenOnly: user.listenOnly,
2017-07-26 22:09:07 +08:00
isSharingWebcam: 0, // FIXME user.webcam_stream.length,
2016-06-14 01:00:38 +08:00
isLocked: user.locked,
2016-10-26 01:22:55 +08:00
});
2017-07-12 21:18:26 +08:00
const getUser = (userID) => {
const user = Users.findOne({ userId: userID });
if (!user) {
return null;
}
2017-07-26 22:09:07 +08:00
return mapUser(user);
2017-07-12 21:18:26 +08:00
};
const mapMessage = (messagePayload) => {
2016-07-11 20:34:58 +08:00
const { message } = messagePayload;
2017-06-03 03:25:02 +08:00
const mappedMessage = {
2016-07-11 20:34:58 +08:00
id: messagePayload._id,
content: messagePayload.content,
2017-07-12 21:18:26 +08:00
time: message.fromTime, // + message.from_tz_offset,
sender: null,
};
2016-06-03 02:40:27 +08:00
if (message.chat_type !== SYSTEM_CHAT_TYPE) {
2017-07-13 00:47:58 +08:00
mappedMessage.sender = getUser(message.fromUserId, message.fromUsername);
2016-06-02 00:33:19 +08:00
}
return mappedMessage;
};
2017-07-12 21:18:26 +08:00
const reduceMessages = (previous, current) => {
2017-06-03 03:25:02 +08:00
const lastMessage = previous[previous.length - 1];
const currentPayload = current.message;
2017-07-12 21:18:26 +08:00
const reducedMessages = current;
reducedMessages.content = [];
reducedMessages.content.push({
2016-07-12 04:10:55 +08:00
id: current._id,
text: currentPayload.message,
2017-07-12 20:42:16 +08:00
time: currentPayload.fromTime,
});
2017-07-12 21:18:26 +08:00
if (!lastMessage || !reducedMessages.message.chatType === SYSTEM_CHAT_TYPE) {
return previous.concat(reducedMessages);
}
2017-06-03 03:25:02 +08:00
const lastPayload = lastMessage.message;
// Check if the last message is from the same user and time discrepancy
// between the two messages exceeds window and then group current message
// with the last one
2017-07-13 00:47:58 +08:00
if (lastPayload.fromUserId === currentPayload.fromUserId
2017-07-12 20:42:16 +08:00
&& (currentPayload.fromTime - lastPayload.fromTime) <= GROUPING_MESSAGES_WINDOW) {
2017-07-12 21:18:26 +08:00
lastMessage.content.push(reducedMessages.content.pop());
return previous;
}
2017-07-12 21:18:26 +08:00
return previous.concat(reducedMessages);
2016-06-03 02:40:27 +08:00
};
2016-06-02 00:33:19 +08:00
const getPublicMessages = () => {
2017-06-03 03:25:02 +08:00
const publicMessages = Chats.find({
2017-07-13 04:22:26 +08:00
'message.toUsername': { $in: [PUBLIC_CHAT_USERNAME, SYSTEM_CHAT_TYPE] },
}, {
2017-07-12 20:42:16 +08:00
sort: ['message.fromTime'],
2017-07-12 21:54:54 +08:00
}).fetch();
2016-07-12 03:42:54 +08:00
return publicMessages
.reduce(reduceMessages, [])
.map(mapMessage);
2016-06-02 00:33:19 +08:00
};
const getPrivateMessages = (userID) => {
2017-06-03 03:25:02 +08:00
const messages = Chats.find({
2017-07-13 04:22:26 +08:00
'message.toUsername': { $ne: PUBLIC_CHAT_USERNAME },
$or: [
2017-07-12 21:54:54 +08:00
{ 'message.toUserId': userID },
{ 'message.fromUserId': userID },
],
}, {
2017-07-12 20:42:16 +08:00
sort: ['message.fromTime'],
2017-06-03 03:25:02 +08:00
}).fetch();
2016-06-02 00:33:19 +08:00
return messages.reduce(reduceMessages, []).map(mapMessage);
2016-06-02 00:33:19 +08:00
};
2016-06-14 01:00:38 +08:00
const isChatLocked = (receiverID) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
const currentUser = getUser(Auth.userID);
2016-06-14 01:00:38 +08:00
const lockSettings = false;
2017-07-13 04:02:55 +08:00
// FIX ME
/* meeting.roomLockSettings || {
2016-06-14 01:00:38 +08:00
disablePublicChat: false,
disablePrivateChat: false,
};*/
2016-06-14 01:00:38 +08:00
if (!currentUser.isLocked || currentUser.isPresenter) {
return false;
}
return isPublic ? lockSettings.disablePublicChat : lockSettings.disablePrivateChat;
};
2016-07-05 02:53:47 +08:00
const hasUnreadMessages = (receiverID) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
2017-07-12 21:18:26 +08:00
const chatType = isPublic ? PUBLIC_CHAT_USERID : receiverID;
2016-07-05 02:53:47 +08:00
2017-07-12 21:18:26 +08:00
return UnreadMessages.count(chatType) > 0;
2016-07-05 02:53:47 +08:00
};
2016-07-12 03:42:54 +08:00
const lastReadMessageTime = (receiverID) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
2017-07-12 21:18:26 +08:00
const chatType = isPublic ? PUBLIC_CHAT_USERID : receiverID;
2016-07-12 03:42:54 +08:00
2017-07-12 21:18:26 +08:00
return UnreadMessages.get(chatType);
2016-07-12 03:42:54 +08:00
};
2016-06-03 02:40:27 +08:00
const sendMessage = (receiverID, message) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
const sender = getUser(Auth.userID);
2016-06-03 02:40:27 +08:00
const receiver = !isPublic ? getUser(receiverID) : {
2016-07-05 02:53:47 +08:00
id: PUBLIC_CHAT_USERID,
name: PUBLIC_CHAT_USERNAME,
2016-06-03 02:40:27 +08:00
};
/* FIX: Why we need all this payload to send a message?
* The server only really needs the message, from_userid, to_userid and from_lang
*/
2017-06-03 03:25:02 +08:00
const messagePayload = {
message,
2017-07-12 20:42:16 +08:00
fromUserId: sender.id,
fromUsername: sender.name,
fromTimezoneOffset: (new Date()).getTimezoneOffset(),
toUsername: receiver.name,
toUserId: receiver.id,
fromTime: Date.now(),
fromColor: 0,
2016-06-03 02:40:27 +08:00
};
2016-06-02 00:33:19 +08:00
2017-06-03 03:25:02 +08:00
const currentClosedChats = Storage.getItem(CLOSED_CHAT_LIST_KEY);
2017-03-03 05:42:39 +08:00
// Remove the chat that user send messages from the session.
2017-03-22 05:52:10 +08:00
if (_.indexOf(currentClosedChats, receiver.id) > -1) {
Storage.setItem(CLOSED_CHAT_LIST_KEY, _.without(currentClosedChats, receiver.id));
2017-03-01 06:40:16 +08:00
}
return makeCall('sendChat', messagePayload);
2016-06-02 00:33:19 +08:00
};
2016-07-01 01:10:36 +08:00
const getScrollPosition = (receiverID) => {
2017-06-03 03:25:02 +08:00
const scroll = ScrollCollection.findOne({ receiver: receiverID }) || { position: null };
2016-07-01 01:10:36 +08:00
return scroll.position;
};
2016-07-05 02:53:47 +08:00
const updateScrollPosition =
(receiverID, position) => ScrollCollection.upsert(
{ receiver: receiverID },
2017-06-03 03:25:02 +08:00
{ $set: { position } },
2016-07-05 02:53:47 +08:00
);
const updateUnreadMessage = (receiverID, timestamp) => {
const isPublic = receiverID === PUBLIC_CHAT_ID;
2017-07-12 21:18:26 +08:00
const chatType = isPublic ? PUBLIC_CHAT_USERID : receiverID;
return UnreadMessages.update(chatType, timestamp);
2016-07-01 01:10:36 +08:00
};
const closePrivateChat = (chatID) => {
2017-06-03 03:25:02 +08:00
const currentClosedChats = Storage.getItem(CLOSED_CHAT_LIST_KEY) || [];
2017-03-03 04:33:49 +08:00
2017-03-22 05:52:10 +08:00
if (_.indexOf(currentClosedChats, chatID) < 0) {
2017-03-03 04:33:49 +08:00
currentClosedChats.push(chatID);
Storage.setItem(CLOSED_CHAT_LIST_KEY, currentClosedChats);
}
2017-03-03 04:33:49 +08:00
};
2016-06-02 00:33:19 +08:00
export default {
getPublicMessages,
getPrivateMessages,
2016-06-07 22:19:19 +08:00
getUser,
2016-07-01 01:10:36 +08:00
getScrollPosition,
2016-07-05 02:53:47 +08:00
hasUnreadMessages,
2016-07-12 03:42:54 +08:00
lastReadMessageTime,
2016-06-14 01:00:38 +08:00
isChatLocked,
2016-07-05 02:53:47 +08:00
updateScrollPosition,
updateUnreadMessage,
2016-06-02 00:33:19 +08:00
sendMessage,
closePrivateChat,
2016-06-02 00:33:19 +08:00
};