session-desktop/ts/components/leftpane/LeftPaneMessageSection.tsx

152 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;
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 conversations 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>
);
}
}