add users-typing collection

This commit is contained in:
KDSBrowne 2019-08-02 18:18:33 +00:00
parent f139afe69b
commit 8a51a099d8
15 changed files with 59 additions and 60 deletions

View File

@ -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 };

View File

@ -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);
}
}

View File

@ -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,
};

View File

@ -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);
}
}

View File

@ -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) => {

View File

@ -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,
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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -62,8 +62,6 @@ export default function addUser(meetingId, user) {
inactivityCheck: false,
responseDelay: 0,
loggedOut: false,
isTyping: false,
isTypingTo: '',
},
flat(user),
),

View File

@ -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;

View File

@ -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,

View File

@ -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';

View File

@ -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 {

View File

@ -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';

View File

@ -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;