From 8e89c188998504c32ef5142901703a0f7bb85552 Mon Sep 17 00:00:00 2001 From: jainkuniya Date: Sun, 11 Aug 2019 14:00:25 +0530 Subject: [PATCH] queueMarkAsRead: Set timeout if there is mark request in less than 2s. If there are multiple requests to mark messages as read with interval less than 2s, and if there is no further request then later were stuck in the queue. Becuase there was only one caller to `messagesFlags`, which was only called by user scroll event. So even after reaching at the end of message list, unread banner is visible with some unread count. So now set timeout to send read message flag to server. Fixes: #3509 --- src/api/__tests__/queueMarkAsRead-test.js | 21 ++++++++++++++++++++- src/api/queueMarkAsRead.js | 12 ++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/api/__tests__/queueMarkAsRead-test.js b/src/api/__tests__/queueMarkAsRead-test.js index 8b221f45fc6..1d96426493c 100644 --- a/src/api/__tests__/queueMarkAsRead-test.js +++ b/src/api/__tests__/queueMarkAsRead-test.js @@ -6,6 +6,8 @@ import { eg } from '../../__tests__/exampleData'; // $FlowFixMe Make flow understand about mocking messagesFlags.default = jest.fn(() => {}); +jest.useFakeTimers(); + describe('queueMarkAsRead', () => { beforeEach(() => { resetAll(); @@ -13,12 +15,13 @@ describe('queueMarkAsRead', () => { jest.clearAllTimers(); }); - test('should not call messagesFlags on consecutive calls of queueMarkAsRead', () => { + test('should not call messagesFlags on consecutive calls of queueMarkAsRead, setTimout on further calls', () => { queueMarkAsRead(eg.selfAuth, [1, 2, 3]); queueMarkAsRead(eg.selfAuth, [4, 5, 6]); queueMarkAsRead(eg.selfAuth, [7, 8, 9]); queueMarkAsRead(eg.selfAuth, [10, 11, 12]); + expect(setTimeout).toHaveBeenCalledTimes(1); expect(messagesFlags.default).toHaveBeenCalledTimes(1); }); @@ -37,4 +40,20 @@ describe('queueMarkAsRead', () => { expect(messagesFlags.default).toHaveBeenCalledTimes(2); }); + + test('should call messagesFlags after 2s to clear queue', async () => { + const currentDate = Date.now(); + const secondCall = currentDate + 2100; + // $FlowFixMe Make flow understand about mocking + Date.now = jest.fn().mockReturnValue(currentDate); + + queueMarkAsRead(eg.selfAuth, [1, 2, 3]); + queueMarkAsRead(eg.selfAuth, [4, 5, 6]); + + // $FlowFixMe Make flow understand about mocking + Date.now = jest.fn().mockReturnValue(secondCall); + jest.runOnlyPendingTimers(); + + expect(messagesFlags.default).toHaveBeenCalledTimes(2); + }); }); diff --git a/src/api/queueMarkAsRead.js b/src/api/queueMarkAsRead.js index 3d7a0db4ae7..8ecd3b19998 100644 --- a/src/api/queueMarkAsRead.js +++ b/src/api/queueMarkAsRead.js @@ -2,8 +2,10 @@ import type { Auth } from './transportTypes'; import messagesFlags from './messages/messagesFlags'; +const TIME_INTERVAL_BETWEEN_CONSECUTIVE_CALLS_MS = 2000; let unsentMessageIds = []; let lastSentTime = 0; +let timeout = null; /** * Exported so that it can be used in test @@ -12,13 +14,19 @@ let lastSentTime = 0; export const resetAll = () => { unsentMessageIds = []; lastSentTime = 0; + timeout = null; }; -const processQueue = (auth: Auth) => { - if (Date.now() - lastSentTime > 2000) { +export const processQueue = (auth: Auth) => { + if (Date.now() - lastSentTime > TIME_INTERVAL_BETWEEN_CONSECUTIVE_CALLS_MS) { messagesFlags(auth, unsentMessageIds, 'add', 'read'); unsentMessageIds = []; lastSentTime = Date.now(); + } else if (timeout === null) { + timeout = setTimeout(() => { + timeout = null; + processQueue(auth); + }, TIME_INTERVAL_BETWEEN_CONSECUTIVE_CALLS_MS); } };