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.
		
		
		
		
		
			
		
			
				
	
	
		
			155 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			155 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			TypeScript
		
	
import React from 'react';
 | 
						|
import { AutoSizer, List, ListRowProps } from 'react-virtualized';
 | 
						|
import {
 | 
						|
  ConversationListItemProps,
 | 
						|
  MemoConversationListItemWithDetails,
 | 
						|
} from './conversation-list-item/ConversationListItem';
 | 
						|
import { ReduxConversationType } from '../../state/ducks/conversations';
 | 
						|
import { SearchResults, SearchResultsProps } from '../search/SearchResults';
 | 
						|
import { LeftPaneSectionHeader } from './LeftPaneSectionHeader';
 | 
						|
import autoBind from 'auto-bind';
 | 
						|
import _ from 'lodash';
 | 
						|
import { MessageRequestsBanner } from './MessageRequestsBanner';
 | 
						|
 | 
						|
import { SessionSearchInput } from '../SessionSearchInput';
 | 
						|
import { OverlayCommunity } from './overlay/OverlayCommunity';
 | 
						|
import { OverlayMessageRequest } from './overlay/OverlayMessageRequest';
 | 
						|
import { OverlayMessage } from './overlay/OverlayMessage';
 | 
						|
import { OverlayClosedGroup } from './overlay/OverlayClosedGroup';
 | 
						|
import { OverlayMode, setOverlayMode } from '../../state/ducks/section';
 | 
						|
import { OverlayChooseAction } from './overlay/choose-action/OverlayChooseAction';
 | 
						|
import styled from 'styled-components';
 | 
						|
import { useSelector } from 'react-redux';
 | 
						|
import { getOverlayMode } from '../../state/selectors/section';
 | 
						|
import { StyledLeftPaneList } from './LeftPaneList';
 | 
						|
 | 
						|
export interface Props {
 | 
						|
  contacts: Array<ReduxConversationType>;
 | 
						|
  conversations?: Array<ConversationListItemProps>;
 | 
						|
  searchResults?: SearchResultsProps;
 | 
						|
 | 
						|
  messageRequestsEnabled?: boolean;
 | 
						|
  overlayMode: OverlayMode | undefined;
 | 
						|
}
 | 
						|
 | 
						|
const StyledLeftPaneContent = styled.div`
 | 
						|
  display: flex;
 | 
						|
  flex-direction: column;
 | 
						|
  flex: 1;
 | 
						|
  overflow: hidden;
 | 
						|
`;
 | 
						|
 | 
						|
const StyledConversationListContent = styled.div`
 | 
						|
  background: var(--background-primary-color);
 | 
						|
  overflow-x: hidden;
 | 
						|
  display: flex;
 | 
						|
  flex-direction: column;
 | 
						|
  flex-grow: 1;
 | 
						|
  transition: none;
 | 
						|
`;
 | 
						|
 | 
						|
const ClosableOverlay = () => {
 | 
						|
  const overlayMode = useSelector(getOverlayMode);
 | 
						|
 | 
						|
  switch (overlayMode) {
 | 
						|
    case 'choose-action':
 | 
						|
      return <OverlayChooseAction />;
 | 
						|
    case 'open-group':
 | 
						|
      return <OverlayCommunity />;
 | 
						|
    case 'closed-group':
 | 
						|
      return <OverlayClosedGroup />;
 | 
						|
    case 'message':
 | 
						|
      return <OverlayMessage />;
 | 
						|
    case 'message-requests':
 | 
						|
      return <OverlayMessageRequest />;
 | 
						|
    default:
 | 
						|
      return null;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
export class LeftPaneMessageSection extends React.Component<Props> {
 | 
						|
  public constructor(props: Props) {
 | 
						|
    super(props);
 | 
						|
 | 
						|
    autoBind(this);
 | 
						|
  }
 | 
						|
 | 
						|
  public renderRow = ({ index, key, style }: ListRowProps): JSX.Element | null => {
 | 
						|
    const { conversations } = this.props;
 | 
						|
 | 
						|
    //assume conversations that have been marked unapproved should be filtered out by selector.
 | 
						|
    if (!conversations) {
 | 
						|
      throw new Error('renderRow: Tried to render without conversations');
 | 
						|
    }
 | 
						|
 | 
						|
    const conversation = conversations[index];
 | 
						|
    if (!conversation) {
 | 
						|
      throw new Error('renderRow: conversations selector returned element containing falsy value.');
 | 
						|
    }
 | 
						|
 | 
						|
    return <MemoConversationListItemWithDetails key={key} style={style} {...conversation} />;
 | 
						|
  };
 | 
						|
 | 
						|
  public renderList(): JSX.Element {
 | 
						|
    const { conversations, searchResults } = this.props;
 | 
						|
 | 
						|
    if (searchResults) {
 | 
						|
      return <SearchResults {...searchResults} />;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!conversations) {
 | 
						|
      throw new Error('render: must provided conversations if no search results are provided');
 | 
						|
    }
 | 
						|
 | 
						|
    const length = conversations.length;
 | 
						|
 | 
						|
    // Note: conversations is not a known prop for List, but it is required to ensure that
 | 
						|
    //   it re-renders when our conversation data changes. Otherwise it would just render
 | 
						|
    //   on startup and scroll.
 | 
						|
 | 
						|
    return (
 | 
						|
      <StyledLeftPaneList key={0}>
 | 
						|
        <AutoSizer>
 | 
						|
          {({ height, width }) => (
 | 
						|
            <List
 | 
						|
              className="module-left-pane__virtual-list"
 | 
						|
              conversations={conversations}
 | 
						|
              height={height}
 | 
						|
              rowCount={length}
 | 
						|
              rowHeight={64}
 | 
						|
              rowRenderer={this.renderRow}
 | 
						|
              width={width}
 | 
						|
              autoHeight={false}
 | 
						|
            />
 | 
						|
          )}
 | 
						|
        </AutoSizer>
 | 
						|
      </StyledLeftPaneList>
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  public render(): JSX.Element {
 | 
						|
    const { overlayMode } = this.props;
 | 
						|
 | 
						|
    return (
 | 
						|
      <StyledLeftPaneContent>
 | 
						|
        <LeftPaneSectionHeader />
 | 
						|
        {overlayMode ? <ClosableOverlay /> : this.renderConversations()}
 | 
						|
      </StyledLeftPaneContent>
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  public renderConversations() {
 | 
						|
    return (
 | 
						|
      <StyledConversationListContent>
 | 
						|
        <SessionSearchInput />
 | 
						|
        <MessageRequestsBanner
 | 
						|
          handleOnClick={() => {
 | 
						|
            window.inboxStore?.dispatch(setOverlayMode('message-requests'));
 | 
						|
          }}
 | 
						|
        />
 | 
						|
        {this.renderList()}
 | 
						|
      </StyledConversationListContent>
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |