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.
		
		
		
		
		
			
		
			
				
	
	
		
			176 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			176 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			TypeScript
		
	
import React, { useLayoutEffect, useState } from 'react';
 | 
						|
import { useSelector } from 'react-redux';
 | 
						|
 | 
						|
import useKey from 'react-use/lib/useKey';
 | 
						|
import {
 | 
						|
  PropsForDataExtractionNotification,
 | 
						|
  PropsForMessageRequestResponse,
 | 
						|
} from '../../models/messageType';
 | 
						|
import {
 | 
						|
  PropsForCallNotification,
 | 
						|
  PropsForExpirationTimer,
 | 
						|
  PropsForGroupInvitation,
 | 
						|
  PropsForGroupUpdate,
 | 
						|
  PropsForInteractionNotification,
 | 
						|
} from '../../state/ducks/conversations';
 | 
						|
import {
 | 
						|
  getOldBottomMessageId,
 | 
						|
  getOldTopMessageId,
 | 
						|
  getSortedMessagesTypesOfSelectedConversation,
 | 
						|
} from '../../state/selectors/conversations';
 | 
						|
import { useSelectedConversationKey } from '../../state/selectors/selectedConversation';
 | 
						|
import { MessageDateBreak } from './message/message-item/DateBreak';
 | 
						|
import { GroupInvitation } from './message/message-item/GroupInvitation';
 | 
						|
import { GroupUpdateMessage } from './message/message-item/GroupUpdateMessage';
 | 
						|
import { Message } from './message/message-item/Message';
 | 
						|
import { MessageRequestResponse } from './message/message-item/MessageRequestResponse';
 | 
						|
import { CallNotification } from './message/message-item/notification-bubble/CallNotification';
 | 
						|
 | 
						|
import { DataExtractionNotification } from './message/message-item/DataExtractionNotification';
 | 
						|
import { SessionLastSeenIndicator } from './SessionLastSeenIndicator';
 | 
						|
import { TimerNotification } from './TimerNotification';
 | 
						|
import { InteractionNotification } from './message/message-item/InteractionNotification';
 | 
						|
 | 
						|
function isNotTextboxEvent(e: KeyboardEvent) {
 | 
						|
  return (e?.target as any)?.type === undefined;
 | 
						|
}
 | 
						|
 | 
						|
let previousRenderedConvo: string | undefined;
 | 
						|
 | 
						|
export const SessionMessagesList = (props: {
 | 
						|
  scrollAfterLoadMore: (
 | 
						|
    messageIdToScrollTo: string,
 | 
						|
    type: 'load-more-top' | 'load-more-bottom'
 | 
						|
  ) => void;
 | 
						|
  onPageUpPressed: () => void;
 | 
						|
  onPageDownPressed: () => void;
 | 
						|
  onHomePressed: () => void;
 | 
						|
  onEndPressed: () => void;
 | 
						|
}) => {
 | 
						|
  const messagesProps = useSelector(getSortedMessagesTypesOfSelectedConversation);
 | 
						|
  const convoKey = useSelectedConversationKey();
 | 
						|
 | 
						|
  const [didScroll, setDidScroll] = useState(false);
 | 
						|
  const oldTopMessageId = useSelector(getOldTopMessageId);
 | 
						|
  const oldBottomMessageId = useSelector(getOldBottomMessageId);
 | 
						|
 | 
						|
  useLayoutEffect(() => {
 | 
						|
    const newTopMessageId = messagesProps.length
 | 
						|
      ? messagesProps[messagesProps.length - 1].message.props.messageId
 | 
						|
      : undefined;
 | 
						|
 | 
						|
    if (oldTopMessageId !== newTopMessageId && oldTopMessageId && newTopMessageId) {
 | 
						|
      props.scrollAfterLoadMore(oldTopMessageId, 'load-more-top');
 | 
						|
    }
 | 
						|
 | 
						|
    const newBottomMessageId = messagesProps.length
 | 
						|
      ? messagesProps[0].message.props.messageId
 | 
						|
      : undefined;
 | 
						|
 | 
						|
    if (newBottomMessageId !== oldBottomMessageId && oldBottomMessageId && newBottomMessageId) {
 | 
						|
      props.scrollAfterLoadMore(oldBottomMessageId, 'load-more-bottom');
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  useKey('PageUp', () => {
 | 
						|
    props.onPageUpPressed();
 | 
						|
  });
 | 
						|
 | 
						|
  useKey('PageDown', () => {
 | 
						|
    props.onPageDownPressed();
 | 
						|
  });
 | 
						|
 | 
						|
  useKey('Home', e => {
 | 
						|
    if (isNotTextboxEvent(e)) {
 | 
						|
      props.onHomePressed();
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  useKey('End', e => {
 | 
						|
    if (isNotTextboxEvent(e)) {
 | 
						|
      props.onEndPressed();
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  if (didScroll && previousRenderedConvo !== convoKey) {
 | 
						|
    setDidScroll(false);
 | 
						|
    previousRenderedConvo = convoKey;
 | 
						|
  }
 | 
						|
 | 
						|
  return (
 | 
						|
    <>
 | 
						|
      {messagesProps.map(messageProps => {
 | 
						|
        const messageId = messageProps.message.props.messageId;
 | 
						|
        const unreadIndicator = messageProps.showUnreadIndicator ? (
 | 
						|
          <SessionLastSeenIndicator
 | 
						|
            key={'unread-indicator'}
 | 
						|
            messageId={messageId}
 | 
						|
            didScroll={didScroll}
 | 
						|
            setDidScroll={setDidScroll}
 | 
						|
          />
 | 
						|
        ) : null;
 | 
						|
 | 
						|
        const dateBreak =
 | 
						|
          messageProps.showDateBreak !== undefined ? (
 | 
						|
            <MessageDateBreak
 | 
						|
              key={`date-break-${messageId}`}
 | 
						|
              timestamp={messageProps.showDateBreak}
 | 
						|
              messageId={messageId}
 | 
						|
            />
 | 
						|
          ) : null;
 | 
						|
 | 
						|
        const componentToMerge = [dateBreak, unreadIndicator];
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'group-notification') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForGroupUpdate;
 | 
						|
          return [<GroupUpdateMessage key={messageId} {...msgProps} />, ...componentToMerge];
 | 
						|
        }
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'group-invitation') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForGroupInvitation;
 | 
						|
          return [<GroupInvitation key={messageId} {...msgProps} />, ...componentToMerge];
 | 
						|
        }
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'message-request-response') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForMessageRequestResponse;
 | 
						|
 | 
						|
          return [<MessageRequestResponse key={messageId} {...msgProps} />, ...componentToMerge];
 | 
						|
        }
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'data-extraction') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForDataExtractionNotification;
 | 
						|
 | 
						|
          return [
 | 
						|
            <DataExtractionNotification key={messageId} {...msgProps} />,
 | 
						|
            ...componentToMerge,
 | 
						|
          ];
 | 
						|
        }
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'timer-notification') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForExpirationTimer;
 | 
						|
 | 
						|
          return [<TimerNotification key={messageId} {...msgProps} />, ...componentToMerge];
 | 
						|
        }
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'call-notification') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForCallNotification;
 | 
						|
 | 
						|
          return [<CallNotification key={messageId} {...msgProps} />, ...componentToMerge];
 | 
						|
        }
 | 
						|
 | 
						|
        if (messageProps.message?.messageType === 'interaction-notification') {
 | 
						|
          const msgProps = messageProps.message.props as PropsForInteractionNotification;
 | 
						|
 | 
						|
          return [<InteractionNotification key={messageId} {...msgProps} />, ...componentToMerge];
 | 
						|
        }
 | 
						|
 | 
						|
        if (!messageProps) {
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
 | 
						|
        return [<Message messageId={messageId} key={messageId} />, ...componentToMerge];
 | 
						|
      })}
 | 
						|
    </>
 | 
						|
  );
 | 
						|
};
 |