Opinions on the schema behind this UI? (chat ui psd inside)

If you split this UI into three columns, ignore the far right column. I’m interested in the schema for the far-left and middle columns (cols 1 and 2 with the chat-specific features).

So right now I have a few collections. Users, Chatrooms and Messages. Users is obvious. Chatrooms are what encompass a chat conversation. So I query for a list of chatrooms to populate that left sidebar showing all the conversations. Then I use the chatroom’s _id to find messages related to a specific chatroom (i.e. thread or conversation). I know there is a good atmosphere package for user status (user is online) but I’m wondering the best way to track read/unread messages (the number is shown as a badge on the avatar, in the list items in that left column).

At this point, there will only be two people per chatroom. Here’s my current schemas that works so far:

Chatrooms.schema = new SimpleSchema({
  participantIds: {
    type: [String],
    optional: true
  },
  ownerId: {
    type: String,
    autoValue: function() {
        if (this.isInsert && (!this.isSet || this.value.length === 0)) {  // only set on insert
           return Meteor.userId();   
        }
    }
   },
  createdAt: {
    type: Date,
    autoValue: function() {
      // only set on insert
        if (this.isInsert && (!this.isSet || this.value.length === 0)) {
            return new Date()
        }
    }
  },
  updatedAt: {
    type: Date,
    // returns a new date on any update-- e.g. the last updated date
    autoValue: function() {
            return new Date()
    }
  },
});

participantIds holds an array of user _ids. I have a publication that uses an $in query to get all the chat rooms for listing in the UI:

Meteor.publish('Chatrooms.myChatrooms', function(){
	return Chatrooms.find({participantIds: { $in: [this.userId]}})
});

Then I have messages:

Messages.schema = new SimpleSchema({
  value: {
    type: String,
  },
  senderId: { 
    type: String,
     // I use this in the UI to decipher between which react.js message component to show (e.g. blue background vs white)
  },
  chatroomId: {
    type: String,
  },
  ownerId: {
    type: String,
    autoValue: function() {
        if (this.isInsert && (!this.isSet || this.value.length === 0)) {  // only set on insert
           return Meteor.userId();   
        }
    }
   },
  createdAt: {
    type: Date,
    autoValue: function() {
      // only set on insert
        if (this.isInsert && (!this.isSet || this.value.length === 0)) {
            return new Date()
        }
    }
  },
  updatedAt: {
    type: Date,
    // returns a new date on any update-- e.g. the last updated date
    autoValue: function() {
            return new Date()
    }
  },
});

How should I track unread messages?

Can I avoid another collection (e.g. “Notifications”) and store it on the message record?

Remember I have to track this for both users. Then I also show the last message in the left column of the UI, but I can simple sort the latest message for a given chatroomId.

Maybe I add a recipientId and messageWasRead:

 recipientId: {
    type: String,
  },
  messageWasRead: { 
    type: Boolean,
     autoValue: function() {
            return false
    }
  },

Then I can fire a method to flag the boolean when the react component renders for XYZ user?

Not sure if you’re still looking into this but I had a similar situation and solved it by keep a time stamp in the user’s profile Everytime they visited the chat window, then I did a mongo query based on messages created after that time stamp in the user’s profile. It worked pretty well for my needs. Hope that helps.