One last lesson in QuickBlox's JavaScript SDK before I call the client-side alpha I'm working on ready for testing... Unread counts.

One of the first things I do when someone logs in is pull back their active dialogs and then, on callback, get 10 messages for each of those dialogs. Then I have pretty much everything I need to display to the user as they switch from dialog to dialog.

As new messages come in to the active conversation (where "conversation" here is a synonym for a QuickBlox "dialog"), they're displayed and marked read. If they come into a backgrounded conversation, I put them into a separate array and add the count to the unread count for that conversation. If the user foregrounds that previously backgrounded conversation, I iterate through that "new but unread" array and let QB know they've been read now, because, at the very least, they've been displayed.

The snafu comes when you reload conversations who have unread messages in their ten most recent messages. That's the state you're in if new messages come into a backgrounded conversation, and the user never makes that conversation active.

By default, simply calling QB.chat.message.list marks all the retrieved messages as read. Since I'm pulling them back before they're necessarily displayed, so we're not swapping conversations and being immediately greeted by a spinner (annoying and a poor user experience), I don't want them marked read yet.

That much is easy-ish. QB.chat.message.list takes a parameters object, and you can send params.mark_as_read = 0 as one of the params. Now I do that when I get my list of messages for non-active conversations, and the server doesn't mark those read.

The problem now is splitting up which are read and which aren't when I load up the conversation. I want to take the unread ones and put them into the "new but unread" array I use for newly received messages. Then, if they make that conversation active, I can let the server know that now they should be marked read.

Here's an example unread message that QB.chat.message.list returns. See if you can find the potential trouble.

{
    "_id": "mfn8211a99f2581a3b000000",
    "attachments": [],
    "chat_dialog_id": "mfnf0d2739de29f4db160077",
    "created_at": "2017-03-02T13:41:46Z",
    "date_sent": 1488462106,
    "delivered_ids": [
        1114,
        1115
    ],
    "message": "test",
    "read_ids": [
        1114
    ],
    "recipient_id": 1115,
    "sender_id": 1114,
    "updated_at": "2017-03-02T13:41:47Z",
    "read": 1
}

That's right. read is 1, or "true". But look at delivered_ids (the message was received), recipient_id, and sender_id. Now compare to read_ids. See what I mean?

The sender has had the message marked read for them, but not the receiver. Yet I'm retrieving as the receiver here. My id is not in the read_ids list, yet read is still 1.

That means the message's read seems to equate to read_by_anyone_including_the_sender. That's not real useful.

I guess I'll just wrap this the way I talked about wrapping properties before, and add XReadByMe or readByAll or something similar.

Yuck.

Labels: , ,