| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -35,7 +35,7 @@ interface State {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				interface Props {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  selectedMessages: Array<string>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  conversationKey: string;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  messages: Array<SortedMessageModelProps>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  messagesProps: Array<SortedMessageModelProps>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  conversation: ConversationType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ourPrimary: string;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  messageContainerRef: React.RefObject<any>;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -98,8 +98,11 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  public componentDidUpdate(prevProps: Props, _prevState: State) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const isSameConvo = prevProps.conversationKey === this.props.conversationKey;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const messageLengthChanged = prevProps.messages.length !== this.props.messages.length;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!isSameConvo || (prevProps.messages.length === 0 && this.props.messages.length !== 0)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const messageLengthChanged = prevProps.messagesProps.length !== this.props.messagesProps.length;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      !isSameConvo ||
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      (prevProps.messagesProps.length === 0 && this.props.messagesProps.length !== 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      // displayed conversation changed. We have a bit of cleaning to do here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      this.scrollOffsetBottomPx = Number.MAX_VALUE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      this.ignoreScrollEvents = true;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -133,7 +136,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  public render() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { conversationKey, conversation, messages } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { conversationKey, conversation, messagesProps } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { showScrollButton } = this.state;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let displayedName = null;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -157,7 +160,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          key="typing-bubble"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        />
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {this.renderMessages(messages)}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {this.renderMessages()}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        <SessionScrollButton
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          show={showScrollButton}
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -206,8 +209,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return findFirstUnreadIndex;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  private renderMessages(messagesProps: Array<SortedMessageModelProps>) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { selectedMessages } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  private renderMessages() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { selectedMessages, messagesProps } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const multiSelectMode = Boolean(selectedMessages.length);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let currentMessageIndex = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let playableMessageIndex = 0;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -367,9 +370,9 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // ~~~~~~~~~~~~~ MESSAGE HANDLING ~~~~~~~~~~~~~
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  private updateReadMessages() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messages, conversationKey } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messagesProps, conversationKey } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!messages || messages.length === 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!messagesProps || messagesProps.length === 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -384,7 +387,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (this.getScrollOffsetBottomPx() === 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      void conversation.markRead(messages[0].propsForMessage.receivedAt);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      void conversation.markRead(messagesProps[0].propsForMessage.receivedAt);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -393,11 +396,11 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   * @param index index of message that just completed
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  private readonly playNextMessage = (index: any) => {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messages } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messagesProps } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let nextIndex: number | undefined = index - 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // to prevent autoplaying as soon as a message is received.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const latestMessagePlayed = index <= 0 || messages.length < index - 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const latestMessagePlayed = index <= 0 || messagesProps.length < index - 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (latestMessagePlayed) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      nextIndex = undefined;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      this.setState({
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -407,8 +410,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // stop auto-playing when the audio messages change author.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const prevAuthorNumber = messages[index].propsForMessage.authorPhoneNumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const nextAuthorNumber = messages[index - 1].propsForMessage.authorPhoneNumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const prevAuthorNumber = messagesProps[index].propsForMessage.authorPhoneNumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const nextAuthorNumber = messagesProps[index - 1].propsForMessage.authorPhoneNumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const differentAuthor = prevAuthorNumber !== nextAuthorNumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (differentAuthor) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      nextIndex = undefined;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -464,28 +467,27 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const shouldFetchMoreMessages = scrollTop <= Constants.UI.MESSAGE_CONTAINER_BUFFER_OFFSET_PX;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (shouldFetchMoreMessages) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const { messages } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const numMessages =
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        this.props.messages.length + Constants.CONVERSATION.DEFAULT_MESSAGE_FETCH_COUNT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const oldLen = messages.length;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const previousTopMessage = messages[oldLen - 1]?.propsForMessage.id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const { messagesProps } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const numMessages = messagesProps.length + Constants.CONVERSATION.DEFAULT_MESSAGE_FETCH_COUNT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const oldLen = messagesProps.length;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const previousTopMessage = messagesProps[oldLen - 1]?.propsForMessage.id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      fetchMessagesForConversation({ conversationKey, count: numMessages });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (previousTopMessage && oldLen !== messages.length) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (previousTopMessage && oldLen !== messagesProps.length) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        this.scrollToMessage(previousTopMessage);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  private scrollToUnread() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messages, conversation } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messagesProps, conversation } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (conversation.unreadCount > 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      let message;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (messages.length > conversation.unreadCount) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (messagesProps.length > conversation.unreadCount) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // if we have enough message to show one more message, show one more to include the unread banner
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        message = messages[conversation.unreadCount - 1];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        message = messagesProps[conversation.unreadCount - 1];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      } else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        message = messages[conversation.unreadCount - 1];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        message = messagesProps[conversation.unreadCount - 1];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (message) {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -493,7 +495,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (this.ignoreScrollEvents && messages.length > 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (this.ignoreScrollEvents && messagesProps.length > 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      this.ignoreScrollEvents = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      this.updateReadMessages();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -563,6 +565,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  private async scrollToQuoteMessage(options: QuoteClickOptions) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { quoteAuthor, quoteId, referencedMessageNotFound } = options;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const { messagesProps } = this.props;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // For simplicity's sake, we show the 'not found' toast no matter what if we were
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    //   not able to find the referenced message when the quote was received.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (referencedMessageNotFound) {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -570,7 +574,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // Look for message in memory first, which would tell us if we could scroll to it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const targetMessage = this.props.messages.find(item => {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const targetMessage = messagesProps.find(item => {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      const messageAuthor = item.propsForMessage?.authorPhoneNumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (!messageAuthor || quoteAuthor !== messageAuthor) {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |