fix timer expiring sometimes missing a sec

pull/1381/head
Audric Ackermann 5 years ago
parent 1fd15ac977
commit bb87eb0f52
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -34,11 +34,10 @@
Message: Whisper.Message, Message: Whisper.Message,
}); });
Whisper.events.trigger( Whisper.events.trigger('messageExpired', {
'messageExpired', conversationKey: message.attributes.conversationId,
message.id, messageId: message.id,
message.conversationId });
);
const conversation = message.getConversation(); const conversation = message.getConversation();
if (conversation) { if (conversation) {

@ -1,80 +1,59 @@
import React from 'react'; import React, { useState } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { getIncrement, getTimerBucket } from '../../util/timer'; import { getIncrement, getTimerBucket } from '../../util/timer';
import { useInterval } from '../../hooks/useInterval';
interface Props { type Props = {
withImageNoCaption: boolean; withImageNoCaption: boolean;
expirationLength: number; expirationLength: number;
expirationTimestamp: number; expirationTimestamp: number;
direction: 'incoming' | 'outgoing'; direction: 'incoming' | 'outgoing';
} };
export class ExpireTimer extends React.Component<Props> { export const ExpireTimer = (props: Props) => {
private interval: any; const [lastUpdated, setLastUpdated] = useState(Date.now());
const update = () => {
constructor(props: Props) { setLastUpdated(Date.now());
super(props); };
const {
this.interval = null; direction,
} expirationLength,
expirationTimestamp,
public componentDidMount() { withImageNoCaption,
const { expirationLength } = this.props; } = props;
const increment = getIncrement(expirationLength);
const updateFrequency = Math.max(increment, 500); const increment = getIncrement(expirationLength);
const updateFrequency = Math.max(increment, 500);
const update = () => {
this.setState({ useInterval(update, updateFrequency);
lastUpdated: Date.now(),
}); const bucket = getTimerBucket(expirationTimestamp, expirationLength);
}; let timeLeft = Math.round((expirationTimestamp - Date.now()) / 1000);
this.interval = setInterval(update, updateFrequency); timeLeft = timeLeft >= 0 ? timeLeft : 0;
} if (timeLeft <= 60) {
public componentWillUnmount() {
if (this.interval) {
clearInterval(this.interval);
}
}
public render() {
const {
direction,
expirationLength,
expirationTimestamp,
withImageNoCaption,
} = this.props;
const bucket = getTimerBucket(expirationTimestamp, expirationLength);
let timeLeft = Math.round((expirationTimestamp - Date.now()) / 1000);
timeLeft = timeLeft >= 0 ? timeLeft : 0;
if (timeLeft <= 60) {
return (
<span
className={classNames(
'module-expire-timer-margin',
'module-message__metadata__date',
`module-message__metadata__date--${direction}`
)}
>
{timeLeft}
</span>
);
}
return ( return (
<div <span
className={classNames( className={classNames(
'module-expire-timer',
'module-expire-timer-margin', 'module-expire-timer-margin',
`module-expire-timer--${bucket}`, 'module-message__metadata__date',
`module-expire-timer--${direction}`, `module-message__metadata__date--${direction}`
withImageNoCaption
? 'module-expire-timer--with-image-no-caption'
: null
)} )}
/> >
{timeLeft}
</span>
); );
} }
}
return (
<div
className={classNames(
'module-expire-timer',
'module-expire-timer-margin',
`module-expire-timer--${bucket}`,
`module-expire-timer--${direction}`,
withImageNoCaption ? 'module-expire-timer--with-image-no-caption' : null
)}
/>
);
};

@ -189,8 +189,8 @@ export type RemoveAllConversationsActionType = {
export type MessageExpiredActionType = { export type MessageExpiredActionType = {
type: 'MESSAGE_EXPIRED'; type: 'MESSAGE_EXPIRED';
payload: { payload: {
id: string; messageId: string;
conversationId: string; conversationKey: string;
}; };
}; };
export type MessageChangedActionType = { export type MessageChangedActionType = {
@ -294,15 +294,18 @@ function removeAllConversations(): RemoveAllConversationsActionType {
}; };
} }
function messageExpired( function messageExpired({
id: string, conversationKey,
conversationId: string messageId,
): MessageExpiredActionType { }: {
conversationKey: string;
messageId: string;
}): MessageExpiredActionType {
return { return {
type: 'MESSAGE_EXPIRED', type: 'MESSAGE_EXPIRED',
payload: { payload: {
id, conversationKey,
conversationId, messageId,
}, },
}; };
} }
@ -445,9 +448,7 @@ export function reducer(
if (action.type === 'CONVERSATIONS_REMOVE_ALL') { if (action.type === 'CONVERSATIONS_REMOVE_ALL') {
return getEmptyState(); return getEmptyState();
} }
if (action.type === 'MESSAGE_EXPIRED') {
// nothing to do here
}
if (action.type === 'SELECTED_CONVERSATION_CHANGED') { if (action.type === 'SELECTED_CONVERSATION_CHANGED') {
const { payload } = action; const { payload } = action;
const { id } = payload; const { id } = payload;
@ -527,8 +528,7 @@ export function reducer(
} }
return state; return state;
} }
if (action.type === 'MESSAGE_EXPIRED' || action.type === 'MESSAGE_DELETED') {
if (action.type === 'MESSAGE_DELETED') {
const { conversationKey, messageId } = action.payload; const { conversationKey, messageId } = action.payload;
if (conversationKey === state.selectedConversation) { if (conversationKey === state.selectedConversation) {
// search if we find this message id. // search if we find this message id.

@ -391,11 +391,11 @@ export function reducer(
} }
const { payload } = action; const { payload } = action;
const { id } = payload; const { messageId } = payload;
return { return {
...state, ...state,
messages: reject(messages, message => id === message.id), messages: reject(messages, message => messageId === message.id),
messageLookup: omit(messageLookup, ['id']), messageLookup: omit(messageLookup, ['id']),
}; };
} }

@ -4,6 +4,10 @@ export function getIncrement(length: number): number {
if (length < 0) { if (length < 0) {
return 1000; return 1000;
} }
// if less than one minute, default to 500 ms so that UI counter is accurate
if (length <= 60000) {
return 500;
}
return Math.ceil(length / 12); return Math.ceil(length / 12);
} }

Loading…
Cancel
Save