Skip to content

Commit 3263f10

Browse files
authored
fix: adjust cooldown interval calculation for messages coming from future (#2101)
1 parent 3d4bdf9 commit 3263f10

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

src/components/MessageInput/CooldownTimer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const CooldownTimer = ({ cooldownInterval, setCooldownRemaining }: Cooldo
2121

2222
return (
2323
<div className='str-chat__message-input-cooldown' data-testid='cooldown-timer'>
24-
{seconds === 0 ? null : seconds}
24+
{seconds}
2525
</div>
2626
);
2727
};

src/components/MessageInput/hooks/__tests__/useCooldownTimer.test.js

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,89 @@ async function renderUseCooldownTimerHook({ channel, chatContext }) {
2020
const cid = 'cid';
2121
const cooldown = 30;
2222
describe('useCooldownTimer', () => {
23-
it('should set remaining cooldown time to if no channel.cooldown', async () => {
23+
it('should set remaining cooldown time to 0 if no channel.cooldown', async () => {
2424
const channel = { cid };
2525
const chatContext = { latestMessageDatesByChannels: {} };
2626
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
2727
expect(result.current.cooldownRemaining).toBe(0);
2828
});
29+
30+
it('should set remaining cooldown time to 0 if no channel.cooldown and latest message time is in the future', async () => {
31+
const channel = { cid };
32+
const lastSentSecondsAhead = 5;
33+
const chatContext = {
34+
latestMessageDatesByChannels: {
35+
cid: new Date(new Date().getTime() + lastSentSecondsAhead * 1000),
36+
},
37+
};
38+
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
39+
expect(result.current.cooldownRemaining).toBe(0);
40+
});
41+
42+
it('should set remaining cooldown time to 0 if no channel.cooldown and latest message time is in the past', async () => {
43+
const channel = { cid };
44+
const lastSentSecondsAgo = 5;
45+
const chatContext = {
46+
latestMessageDatesByChannels: {
47+
cid: new Date(new Date().getTime() - lastSentSecondsAgo * 1000),
48+
},
49+
};
50+
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
51+
expect(result.current.cooldownRemaining).toBe(0);
52+
});
53+
54+
it('should set remaining cooldown time to 0 if channel.cooldown is 0', async () => {
55+
const channel = { cid, data: { cooldown: 0 } };
56+
const chatContext = { latestMessageDatesByChannels: {} };
57+
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
58+
expect(result.current.cooldownRemaining).toBe(0);
59+
});
60+
61+
it('should set remaining cooldown time to 0 if channel.cooldown is 0 and latest message time is in the future', async () => {
62+
const channel = { cid, data: { cooldown: 0 } };
63+
const lastSentSecondsAhead = 5;
64+
const chatContext = {
65+
latestMessageDatesByChannels: {
66+
cid: new Date(new Date().getTime() + lastSentSecondsAhead * 1000),
67+
},
68+
};
69+
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
70+
expect(result.current.cooldownRemaining).toBe(0);
71+
});
72+
73+
it('should set remaining cooldown time to 0 if channel.cooldown is 0 and latest message time is in the past', async () => {
74+
const channel = { cid, data: { cooldown: 0 } };
75+
const lastSentSecondsAgo = 5;
76+
const chatContext = {
77+
latestMessageDatesByChannels: {
78+
cid: new Date(new Date().getTime() - lastSentSecondsAgo * 1000),
79+
},
80+
};
81+
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
82+
expect(result.current.cooldownRemaining).toBe(0);
83+
});
84+
2985
it('should set remaining cooldown time to 0 if skip-slow-mode is among own_capabilities', async () => {
3086
const channel = { cid, data: { cooldown, own_capabilities: ['skip-slow-mode'] } };
3187
const chatContext = { latestMessageDatesByChannels: { cid: new Date() } };
3288
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
3389
expect(result.current.cooldownRemaining).toBe(0);
3490
});
91+
3592
it('should set remaining cooldown time to 0 if no previous messages sent', async () => {
3693
const channel = { cid, data: { cooldown } };
3794
const chatContext = { latestMessageDatesByChannels: {} };
3895
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
3996
expect(result.current.cooldownRemaining).toBe(0);
4097
});
98+
4199
it('should set remaining cooldown time to 0 if previous messages sent earlier than channel.cooldown', async () => {
42100
const channel = { cid, data: { cooldown } };
43101
const chatContext = { latestMessageDatesByChannels: { cid: new Date('1970-1-1') } };
44102
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
45103
expect(result.current.cooldownRemaining).toBe(0);
46104
});
105+
47106
it('should set remaining cooldown time to time left from previous messages sent', async () => {
48107
const channel = { cid, data: { cooldown } };
49108
const lastSentSecondsAgo = 5;
@@ -55,4 +114,16 @@ describe('useCooldownTimer', () => {
55114
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
56115
expect(result.current.cooldownRemaining).toBe(cooldown - lastSentSecondsAgo);
57116
});
117+
118+
it('should consider last message with timestamp from future as created now', async () => {
119+
const channel = { cid, data: { cooldown } };
120+
const lastSentSecondsAhead = 5;
121+
const chatContext = {
122+
latestMessageDatesByChannels: {
123+
cid: new Date(new Date().getTime() + lastSentSecondsAhead * 1000),
124+
},
125+
};
126+
const { result } = await renderUseCooldownTimerHook({ channel, chatContext });
127+
expect(result.current.cooldownRemaining).toBe(cooldown);
128+
});
58129
});

src/components/MessageInput/hooks/useCooldownTimer.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ export const useCooldownTimer = <
3636

3737
useEffect(() => {
3838
const timeSinceOwnLastMessage = ownLatestMessageDate
39-
? (new Date().getTime() - ownLatestMessageDate.getTime()) / 1000
39+
? // prevent negative values
40+
Math.max(0, (new Date().getTime() - ownLatestMessageDate.getTime()) / 1000)
4041
: undefined;
4142

4243
setCooldownRemaining(
43-
!skipCooldown && timeSinceOwnLastMessage && cooldownInterval > timeSinceOwnLastMessage
44+
!skipCooldown &&
45+
typeof timeSinceOwnLastMessage !== 'undefined' &&
46+
cooldownInterval > timeSinceOwnLastMessage
4447
? Math.round(cooldownInterval - timeSinceOwnLastMessage)
4548
: 0,
4649
);

0 commit comments

Comments
 (0)