import * as React from 'react' ; import { SectionList , StyleSheet } from 'react-native' ; import { ListSeparator , ListSectionHeader , ListEmpty } from '@frogpond/lists' ; import { ContactRow } from './row' ; import groupBy from 'lodash/groupBy' ; import toPairs from 'lodash/toPairs' ; import * as c from '@frogpond/colors' ; import type { ContactType } from './types' ; import type { TopLevelViewPropsType } from '../types' ; import { fetch } from '@frogpond/fetch' ; import { API } from '@frogpond/api' ; const fetchContacts = ( forReload ? ) : Promise < Array < ContactType > > => fetch ( API ( '/contacts' ) , { delay : forReload ? 500 : 0 , } ) . json < { data : Array < ContactType > ; } > ( ) . then ( ( body ) => body . data ) ; const groupContacts = ( contacts ) => { let grouped = groupBy ( contacts , ( c ) => c . category ) ; return toPairs ( grouped ) . map ( ( [ key , value ] ) => ( { title : key , data : value } ) ) ; } ; const styles = StyleSheet . create ( { listContainer : { backgroundColor : c . white , } , contentContainer : { flexGrow : 1 , } , } ) ; type Props = TopLevelViewPropsType ; type State = { contacts : Array < ContactType > ; loading : boolean ; } ; export class ContactsListView extends React . PureComponent < Props , State > { static navigationOptions = { title : 'Important Contacts' , headerBackTitle : 'Contacts' , } ; state = { contacts : [ ] , loading : false , } ; componentDidMount ( ) { this . fetchData ( ) ; } refresh = async ( ) : Promise < void > => { this . setState ( ( ) => ( { loading : true } ) ) ; let contacts = await fetchContacts ( true ) ; this . setState ( ( ) => ( { loading : false , contacts : contacts } ) ) ; } ; fetchData = async ( ) => { let contacts = await fetchContacts ( ) ; this . setState ( ( ) => ( { contacts : contacts } ) ) ; } ; onPressContact = ( contact ) => { this . props . navigation . navigate ( 'ContactsDetailView' , { contact , } ) ; } ; renderSectionHeader = ( { section : { title } } ) => ( < ListSectionHeader title = { title } / > ) ; renderItem = ( { item } ) => ( < ContactRow contact = { item } onPress = { this . onPressContact } / > ) ; keyExtractor = ( item ) => item . title ; render ( ) { let groupedData = groupContacts ( this . state . contacts ) ; return ( < SectionList ItemSeparatorComponent = { ListSeparator } ListEmptyComponent = { < ListEmpty mode = "bug" / > } contentContainerStyle = { styles . contentContainer } keyExtractor = { this . keyExtractor } onRefresh = { this . refresh } refreshing = { this . state . loading } renderItem = { this . renderItem } renderSectionHeader = { this . renderSectionHeader } sections = { groupedData } style = { styles . listContainer } / > ) ; } }