You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			132 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			TypeScript
		
	
| import React, { useCallback, useEffect, useState } from 'react';
 | |
| import { useDispatch } from 'react-redux';
 | |
| import { useInterval } from 'react-use';
 | |
| import styled from 'styled-components';
 | |
| import { Data } from '../../../../data/data';
 | |
| import { MessageModelType } from '../../../../models/messageType';
 | |
| import { getConversationController } from '../../../../session/conversations';
 | |
| import { messagesExpired, PropsForExpiringMessage } from '../../../../state/ducks/conversations';
 | |
| import { getIncrement } from '../../../../util/timer';
 | |
| import { ExpireTimer } from '../../ExpireTimer';
 | |
| import { ReadableMessage, ReadableMessageProps } from './ReadableMessage';
 | |
| 
 | |
| const EXPIRATION_CHECK_MINIMUM = 2000;
 | |
| 
 | |
| function useIsExpired(props: PropsForExpiringMessage) {
 | |
|   const {
 | |
|     convoId,
 | |
|     messageId,
 | |
|     expirationLength,
 | |
|     expirationTimestamp,
 | |
|     isExpired: isExpiredProps,
 | |
|   } = props;
 | |
| 
 | |
|   const dispatch = useDispatch();
 | |
| 
 | |
|   const [isExpired] = useState(isExpiredProps);
 | |
| 
 | |
|   const checkExpired = useCallback(async () => {
 | |
|     const now = Date.now();
 | |
| 
 | |
|     if (!expirationTimestamp || !expirationLength) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (isExpired || now >= expirationTimestamp) {
 | |
|       await Data.removeMessage(messageId);
 | |
|       if (convoId) {
 | |
|         dispatch(
 | |
|           messagesExpired([
 | |
|             {
 | |
|               conversationKey: convoId,
 | |
|               messageId,
 | |
|             },
 | |
|           ])
 | |
|         );
 | |
|         const convo = getConversationController().get(convoId);
 | |
|         convo?.updateLastMessage();
 | |
|       }
 | |
|     }
 | |
|   }, [expirationTimestamp, expirationLength, isExpired, messageId, convoId]);
 | |
| 
 | |
|   let checkFrequency: number | null = null;
 | |
|   if (expirationLength) {
 | |
|     const increment = getIncrement(expirationLength || EXPIRATION_CHECK_MINIMUM);
 | |
|     checkFrequency = Math.max(EXPIRATION_CHECK_MINIMUM, increment);
 | |
|   }
 | |
| 
 | |
|   useEffect(() => {
 | |
|     void checkExpired();
 | |
|   }, []); // check on mount
 | |
| 
 | |
|   useInterval(checkExpired, checkFrequency); // check every 2sec or sooner if needed
 | |
| 
 | |
|   return { isExpired };
 | |
| }
 | |
| 
 | |
| const StyledReadableMessage = styled(ReadableMessage)<{ isIncoming: boolean }>`
 | |
|   display: flex;
 | |
|   justify-content: ${props => (props.isIncoming ? 'flex-start' : 'flex-end')};
 | |
|   align-items: center;
 | |
|   width: 100%;
 | |
| `;
 | |
| 
 | |
| export interface ExpirableReadableMessageProps
 | |
|   extends ReadableMessageProps,
 | |
|     PropsForExpiringMessage {
 | |
|   direction: MessageModelType;
 | |
| }
 | |
| 
 | |
| export const ExpirableReadableMessage = (props: ExpirableReadableMessageProps) => {
 | |
|   const {
 | |
|     convoId,
 | |
|     messageId,
 | |
|     direction,
 | |
|     receivedAt,
 | |
|     isUnread,
 | |
|     expirationLength,
 | |
|     expirationTimestamp,
 | |
|   } = props;
 | |
| 
 | |
|   const expiringProps: PropsForExpiringMessage = {
 | |
|     convoId,
 | |
|     messageId,
 | |
|     expirationLength,
 | |
|     expirationTimestamp,
 | |
|     isExpired: props.isExpired,
 | |
|     direction,
 | |
|   };
 | |
|   const { isExpired } = useIsExpired(expiringProps);
 | |
|   const isIncoming = direction === 'incoming';
 | |
| 
 | |
|   if (isExpired) {
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   return (
 | |
|     <StyledReadableMessage
 | |
|       messageId={messageId}
 | |
|       receivedAt={receivedAt}
 | |
|       isUnread={!!isUnread}
 | |
|       isIncoming={isIncoming}
 | |
|       key={`readable-message-${messageId}`}
 | |
|     >
 | |
|       {expirationLength && expirationTimestamp && (
 | |
|         <ExpireTimer
 | |
|           isCorrectSide={!isIncoming}
 | |
|           expirationLength={expirationLength}
 | |
|           expirationTimestamp={expirationTimestamp}
 | |
|         />
 | |
|       )}
 | |
|       {props.children}
 | |
|       {expirationLength && expirationTimestamp && (
 | |
|         <ExpireTimer
 | |
|           isCorrectSide={isIncoming}
 | |
|           expirationLength={expirationLength}
 | |
|           expirationTimestamp={expirationTimestamp}
 | |
|         />
 | |
|       )}
 | |
|     </StyledReadableMessage>
 | |
|   );
 | |
| };
 |