diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/index.js b/bigbluebutton-html5/imports/api/group-chat-msg/index.js
index 8a0e3b5fff..6d6b838d7d 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/index.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/index.js
@@ -1,9 +1,11 @@
import { Meteor } from 'meteor/meteor';
const GroupChatMsg = new Mongo.Collection('group-chat-msg');
+const UsersTyping = new Mongo.Collection('users-typing');
if (Meteor.isServer) {
GroupChatMsg._ensureIndex({ meetingId: 1, chatId: 1 });
+ UsersTyping._ensureIndex({ meetingId: 1, userId: 1 });
}
-export default GroupChatMsg;
+export { GroupChatMsg, UsersTyping };
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/handlers/userTyping.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/handlers/userTyping.js
index 6991677840..24456ec547 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/handlers/userTyping.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/handlers/userTyping.js
@@ -1,5 +1,5 @@
import { check } from 'meteor/check';
-import Users from '/imports/api/users';
+import { UsersTyping } from '/imports/api/group-chat-msg';
import startTyping from '../modifiers/startTyping';
export default function handleUserTyping({ body }, meetingId) {
@@ -9,16 +9,5 @@ export default function handleUserTyping({ body }, meetingId) {
check(userId, String);
check(chatId, String);
- const user = Users.findOne({
- userId,
- meetingId,
- }, {
- fields: {
- isTyping: 1,
- },
- });
-
- if (user && !user.isTyping) {
- startTyping(meetingId, userId, chatId);
- }
+ startTyping(meetingId, userId, chatId);
}
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/startUserTyping.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/startUserTyping.js
index 4b88e07055..0823891959 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/startUserTyping.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/startUserTyping.js
@@ -1,5 +1,6 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
+import { UsersTyping } from '/imports/api/group-chat-msg';
import RedisPubSub from '/imports/startup/server/redis';
export default function startUserTyping(credentials, chatId) {
@@ -14,6 +15,13 @@ export default function startUserTyping(credentials, chatId) {
check(requesterUserId, String);
check(chatId, String);
+ const userTyping = UsersTyping.findOne({
+ meetingId,
+ userId: requesterUserId,
+ });
+
+ if (userTyping) return;
+
const payload = {
chatId: chatId || PUBLIC_GROUP_CHAT_ID,
};
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/stopUserTyping.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/stopUserTyping.js
index d219d8096f..31cc951a9a 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/stopUserTyping.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/methods/stopUserTyping.js
@@ -1,5 +1,5 @@
import { check } from 'meteor/check';
-import Users from '/imports/api/users';
+import { UsersTyping } from '/imports/api/group-chat-msg';
import stopTyping from '../modifiers/stopTyping';
export default function stopUserTyping(credentials) {
@@ -8,16 +8,12 @@ export default function stopUserTyping(credentials) {
check(meetingId, String);
check(requesterUserId, String);
- const user = Users.findOne({
- userId: requesterUserId,
+ const userTyping = UsersTyping.findOne({
meetingId,
- }, {
- fields: {
- isTyping: 1,
- },
+ userId: requesterUserId,
});
- if (user && user.isTyping) {
+ if (userTyping) {
stopTyping(meetingId, requesterUserId);
}
}
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/addGroupChatMsg.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/addGroupChatMsg.js
index 60377b0e45..05d60b1073 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/addGroupChatMsg.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/addGroupChatMsg.js
@@ -1,7 +1,7 @@
import flat from 'flat';
import { Match, check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
-import GroupChatMsg from '/imports/api/group-chat-msg';
+import { GroupChatMsg } from '/imports/api/group-chat-msg';
import { BREAK_LINE } from '/imports/utils/lineEndings';
const parseMessage = (message) => {
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/startTyping.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/startTyping.js
index 0632830896..618a6fc35d 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/startTyping.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/startTyping.js
@@ -1,6 +1,7 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Users from '/imports/api/users';
+import { UsersTyping } from '/imports/api/group-chat-msg';
export default function startTyping(meetingId, userId, chatId) {
check(meetingId, String);
@@ -11,11 +12,13 @@ export default function startTyping(meetingId, userId, chatId) {
userId,
};
- const modifier = {
- $set: {
- isTyping: true,
- isTypingTo: chatId,
- },
+ const user = Users.findOne(selector);
+
+ const mod = {
+ meetingId,
+ userId,
+ name: user.name,
+ isTypingTo: chatId,
};
const cb = (err) => {
@@ -25,5 +28,5 @@ export default function startTyping(meetingId, userId, chatId) {
return Logger.info(`Typing indicator update for userId={${userId}} chatId={${chatId}}`);
};
- return Users.update(selector, modifier, cb);
+ return UsersTyping.upsert(selector, mod, cb);
}
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/stopTyping.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/stopTyping.js
index b08328333e..7e538f1138 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/stopTyping.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/modifiers/stopTyping.js
@@ -1,6 +1,6 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
-import Users from '/imports/api/users';
+import { UsersTyping } from '/imports/api/group-chat-msg';
export default function stopTyping(meetingId, userId) {
check(meetingId, String);
@@ -9,22 +9,14 @@ export default function stopTyping(meetingId, userId) {
const selector = {
meetingId,
userId,
- isTyping: true,
- };
-
- const modifier = {
- $set: {
- isTyping: false,
- isTypingTo: '',
- },
};
const cb = (err) => {
if (err) {
return Logger.error(`Stop user=${userId} typing indicator error: ${err}`);
}
- return Logger.info(`Stopped user=${userId} typing indicator`);
+ return Logger.info(`Stopped typing indicator for user=${userId}`);
};
- return Users.update(selector, modifier, cb);
+ return UsersTyping.remove(selector, cb);
}
diff --git a/bigbluebutton-html5/imports/api/group-chat-msg/server/publishers.js b/bigbluebutton-html5/imports/api/group-chat-msg/server/publishers.js
index d5cc4fd5ba..cc9282cdfe 100644
--- a/bigbluebutton-html5/imports/api/group-chat-msg/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/group-chat-msg/server/publishers.js
@@ -1,4 +1,4 @@
-import GroupChatMsg from '/imports/api/group-chat-msg';
+import { GroupChatMsg, UsersTyping } from '/imports/api/group-chat-msg';
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
@@ -30,3 +30,20 @@ function publish(...args) {
}
Meteor.publish('group-chat-msg', publish);
+
+function usersTyping(credentials) {
+ const { meetingId, requesterUserId, requesterToken } = credentials;
+
+ check(meetingId, String);
+ check(requesterUserId, String);
+ check(requesterToken, String);
+
+ return UsersTyping.find({ meetingId });
+}
+
+function pubishUsersTyping(...args) {
+ const boundUsersTyping = usersTyping.bind(this);
+ return boundUsersTyping(...args);
+}
+
+Meteor.publish('users-typing', pubishUsersTyping);
diff --git a/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js b/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
index aaf00a1fbc..f07769e758 100755
--- a/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
+++ b/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
@@ -62,8 +62,6 @@ export default function addUser(meetingId, user) {
inactivityCheck: false,
responseDelay: 0,
loggedOut: false,
- isTyping: false,
- isTypingTo: '',
},
flat(user),
),
diff --git a/bigbluebutton-html5/imports/ui/components/chat/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/component.jsx
index ad942295a4..8ae1877821 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/component.jsx
@@ -54,7 +54,7 @@ const Chat = (props) => {
UnsentMessagesCollection,
isMeteorConnected,
typingUsers,
- currentUser,
+ currentUserId,
startUserTyping,
stopUserTyping,
} = props;
@@ -63,13 +63,13 @@ const Chat = (props) => {
const CLOSE_CHAT_AK = shortcuts.closePrivateChat;
let names = [];
+
names = typingUsers.map((user) => {
- const { userId } = currentUser;
const { userId: typingUserId, isTypingTo, name } = user;
- if (userId === typingUserId) return null;
+ if (currentUserId === typingUserId) return null;
if (chatID !== isTypingTo) {
if (typingUserId === chatID) {
- return userId !== isTypingTo
+ return currentUserId !== isTypingTo
? null : name;
}
return null;
diff --git a/bigbluebutton-html5/imports/ui/components/chat/container.jsx b/bigbluebutton-html5/imports/ui/components/chat/container.jsx
index d18fb3837c..09c4853d37 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/container.jsx
@@ -4,6 +4,7 @@ import { withTracker } from 'meteor/react-meteor-data';
import { Session } from 'meteor/session';
import Auth from '/imports/ui/services/auth';
import Users from '/imports/api/users';
+import { UsersTyping } from '/imports/api/group-chat-msg';
import { makeCall } from '/imports/ui/services/api';
import Chat from './component';
import ChatService from './service';
@@ -149,15 +150,8 @@ export default injectIntl(withTracker(({ intl }) => {
const { connected: isMeteorConnected } = Meteor.status();
- const typingUsers = Users.find({
+ const typingUsers = UsersTyping.find({
meetingId: Auth.meetingID,
- isTyping: true,
- }, {
- fields: {
- userId: 1,
- isTypingTo: 1,
- name: 1,
- },
}).fetch();
const currentUser = Users.findOne({
@@ -172,7 +166,7 @@ export default injectIntl(withTracker(({ intl }) => {
return {
startUserTyping: chatId => makeCall('startUserTyping', chatId),
stopUserTyping: () => makeCall('stopUserTyping'),
- currentUser,
+ currentUserId: currentUser ? currentUser.userId : null,
typingUsers,
chatID,
chatName,
diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js
index ae60731d45..f1f7c7aa47 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/service.js
+++ b/bigbluebutton-html5/imports/ui/components/chat/service.js
@@ -1,6 +1,6 @@
import Users from '/imports/api/users';
import Meetings from '/imports/api/meetings';
-import GroupChatMsg from '/imports/api/group-chat-msg';
+import { GroupChatMsg } from '/imports/api/group-chat-msg';
import GroupChat from '/imports/api/group-chat';
import Auth from '/imports/ui/services/auth';
import UnreadMessages from '/imports/ui/services/unread-messages';
diff --git a/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx b/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx
index 3b2206686b..fbd017a097 100644
--- a/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx
@@ -17,7 +17,7 @@ const SUBSCRIPTIONS = [
'users', 'meetings', 'polls', 'presentations', 'slides', 'captions',
'voiceUsers', 'whiteboard-multi-user', 'screenshare', 'group-chat',
'presentation-pods', 'users-settings', 'guestUser', 'users-infos', 'note',
- 'network-information', 'ping-pong',
+ 'network-information', 'ping-pong', 'users-typing',
];
class Subscriptions extends React.Component {
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js
index 48841c0a42..d8cdaa5cae 100755
--- a/bigbluebutton-html5/imports/ui/components/user-list/service.js
+++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js
@@ -1,6 +1,6 @@
import Users from '/imports/api/users';
import GroupChat from '/imports/api/group-chat';
-import GroupChatMsg from '/imports/api/group-chat-msg';
+import { GroupChatMsg } from '/imports/api/group-chat-msg';
import Breakouts from '/imports/api/breakouts/';
import Meetings from '/imports/api/meetings';
import Auth from '/imports/ui/services/auth';
diff --git a/bigbluebutton-html5/imports/ui/services/unread-messages/index.js b/bigbluebutton-html5/imports/ui/services/unread-messages/index.js
index 70d5c1d052..7eb0f22041 100755
--- a/bigbluebutton-html5/imports/ui/services/unread-messages/index.js
+++ b/bigbluebutton-html5/imports/ui/services/unread-messages/index.js
@@ -3,7 +3,7 @@ import { Tracker } from 'meteor/tracker';
import Storage from '/imports/ui/services/storage/session';
import Auth from '/imports/ui/services/auth';
import GroupChat from '/imports/api/group-chat';
-import GroupChatMsg from '/imports/api/group-chat-msg';
+import { GroupChatMsg } from '/imports/api/group-chat-msg';
const CHAT_CONFIG = Meteor.settings.public.chat;
const STORAGE_KEY = CHAT_CONFIG.storage_key;