add contact section bottom buttons and empty list

This commit is contained in:
Audric Ackermann 2019-12-30 10:07:51 +11:00
parent c9a35ac89d
commit 571af6c654
6 changed files with 168 additions and 20 deletions

View file

@ -2415,5 +2415,14 @@
},
"lists": {
"message": "Lists"
},
"edit": {
"message": "Edit"
},
"addContact": {
"message": "Add Contact"
},
"createGroup": {
"message": "Create Group"
}
}

View file

@ -277,3 +277,25 @@ $session-compose-margin: 20px;
color: $session-color-white;
font-weight: bold;
}
.left-pane-contact {
&-section,
&-content {
display: flex;
flex-direction: column;
}
&-bottom-buttons {
display: flex;
flex-direction: row;
.session-button.square-outline.square.green,
.session-button.square-outline.square.white {
flex-grow: 1;
border: 1px solid $session-shade-8;
height: 50px;
line-height: 50px;
}
}
}

View file

@ -9,6 +9,17 @@ import { SearchOptions } from '../types/Search';
import { LeftPaneSectionHeader } from './session/LeftPaneSectionHeader';
import { LeftPaneContactSection } from './session/LeftPaneContactSection';
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
export type RowRendererParamsType = {
index: number;
isScrolling: boolean;
isVisible: boolean;
key: string;
parent: Object;
style: Object;
};
interface State {
selectedSection: SectionType;
}

View file

@ -5,7 +5,9 @@ import { PropsData as SearchResultsProps } from '../SearchResults';
import { debounce } from 'lodash';
import { cleanSearchTerm } from '../../util/cleanSearchTerm';
import { SearchOptions } from '../../types/Search';
import { LeftPane } from '../LeftPane';
import { LeftPane, RowRendererParamsType } from '../LeftPane';
import { SessionButton, SessionButtonType, SessionButtonColor } from './SessionButton';
import { AutoSizer, List } from 'react-virtualized';
export interface Props {
searchTerm: string;
@ -26,23 +28,140 @@ export class LeftPaneContactSection extends React.Component<Props, any> {
public constructor(props: Props) {
super(props);
this.state = {
showAddContactView: false,
selectedTab: 0,
};
this.debouncedSearch = debounce(this.search.bind(this), 20);
this.handleTabSelected = this.handleTabSelected.bind(this);
}
public componentWillUnmount() {
this.updateSearch('');
}
public renderHeader(): JSX.Element {
public handleTabSelected(tabType: number) {
this.setState({selectedTab: tabType});
}
public renderHeader(): JSX.Element|undefined {
const labels = [window.i18n('contactsHeader'), window.i18n('lists')];
return LeftPane.renderHeader(labels, null, undefined, null);
return LeftPane.renderHeader(labels, this.handleTabSelected, undefined, null);
}
public render(): JSX.Element {
return <div>{this.renderHeader()}</div>;
return (
<div className="left-pane-contact-section">
{this.renderHeader()}
{this.state.showAddContactView || this.renderContacts()}
</div>
);
}
private renderContacts() {
return (
<div className="left-pane-contact-content">
{this.renderList()}
{this.renderBottomButtons()}
</div>);
}
private renderBottomButtons(): JSX.Element {
const { selectedTab } = this.state;
const edit = window.i18n('edit');
const addContact = window.i18n('addContact');
const createGroup = window.i18n('createGroup');
return (
<div className="left-pane-contact-bottom-buttons">
<SessionButton text={edit} buttonType={SessionButtonType.SquareOutline} buttonColor={SessionButtonColor.White}/>
{selectedTab === 0 ? <SessionButton text={addContact} buttonType={SessionButtonType.SquareOutline} buttonColor={SessionButtonColor.Green}/> :
<SessionButton text={createGroup} buttonType={SessionButtonType.Square} buttonColor={SessionButtonColor.Green}/>}
</div>
)
}
public getCurrentConversations():
| Array<ConversationListItemPropsType>
| undefined {
const { conversations } = this.props;
let conversationList = conversations;
if (conversationList !== undefined) {
conversationList = conversationList.filter(
conversation => !conversation.isSecondary
);
}
return conversationList;
}
private renderList() {
// const conversations = this.getCurrentConversations();
// if (!conversations) {
// throw new Error(
// 'render: must provided conversations if no search results are provided'
// );
// }
// const length = conversations.length;
// const listKey = 0;
// 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.
const list = (
<div className="module-left-pane__list" key={0}>
<AutoSizer>
{({ height, width }) => (
<List
className="module-left-pane__virtual-list"
height={height}
rowCount={length}
rowHeight={64}
rowRenderer={this.renderRow}
width={width}
autoHeight={true}
/>
)}
</AutoSizer>
</div>
);
return [list];
}
public renderRow = ({
// index,
// key,
// style,
}: RowRendererParamsType): JSX.Element|undefined => {
// const { openConversationInternal } = this.props;
// const conversations = this.getCurrentConversations();
// if (!conversations) {
// throw new Error('renderRow: Tried to render without conversations');
// }
// const conversation = conversations[index];
// return (
// <ConversationListItem
// key={key}
// style={style}
// {...conversation}
// onClick={openConversationInternal}
// i18n={window.i18n}
// />
// );
return undefined;
};
public updateSearch(searchTerm: string) {
const { updateSearchTerm, clearSearch } = this.props;

View file

@ -22,7 +22,7 @@ import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionIdEditable } from './SessionIdEditable';
import { UserSearchDropdown } from './UserSearchDropdown';
import { validateNumber } from '../../types/PhoneNumber';
import { LeftPane } from '../LeftPane';
import { RowRendererParamsType, LeftPane } from '../LeftPane';
export interface Props {
searchTerm: string;
@ -38,15 +38,7 @@ export interface Props {
clearSearch: () => void;
}
// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5
type RowRendererParamsType = {
index: number;
isScrolling: boolean;
isVisible: boolean;
key: string;
parent: Object;
style: Object;
};
export class LeftPaneMessageSection extends React.Component<Props, any> {
private readonly updateSearchBound: (searchedString: string) => void;
@ -132,13 +124,7 @@ export class LeftPaneMessageSection extends React.Component<Props, any> {
);
}
// That extra 1 element added to the list is the 'archived conversations' button
const length = conversations.length;
// We ensure that the listKey differs between inbox and archive views, which ensures
// that AutoSizer properly detects the new size of its slot in the flexbox. The
// archive explainer text at the top of the archive view causes problems otherwise.
// It also ensures that we scroll to the top when switching views.
const listKey = 0;
// Note: conversations is not a known prop for List, but it is required to ensure that

View file

@ -108,5 +108,6 @@ export class LeftPaneSectionHeader extends React.Component<Props, State> {
this.setState({
selectedTab: tabType,
});
this.props.onTabSelected(tabType);
};
}