@@ -9,13 +9,18 @@ import {SectionList, StyleSheet} from 'react-native'
99import { ListSeparator , ListSectionHeader } from '../components/list'
1010import { ListEmpty , ListFooter } from '../components/list'
1111import { ContactRow } from './contact-row'
12- import { data } from './data'
12+ import delay from 'delay'
13+ import { reportNetworkProblem } from '../../lib/report-network-problem'
14+ import * as defaultData from '../../../docs/contact-info.json'
1315import groupBy from 'lodash/groupBy'
1416import toPairs from 'lodash/toPairs'
1517import * as c from '../components/colors'
1618import type { ContactType } from './types'
19+ import type { TopLevelViewPropsType } from '../types'
1720
1821const AAO_URL = 'https://github.com/StoDevX/AAO-React-Native/issues/new'
22+ const GITHUB_URL =
23+ 'https://stodevx.github.io/AAO-React-Native/contact-info.json'
1924
2025const groupContacts = ( contacts : ContactType [ ] ) => {
2126 const grouped = groupBy ( contacts , c => c . category )
@@ -28,12 +33,60 @@ const styles = StyleSheet.create({
2833 } ,
2934} )
3035
31- export default class ContactsListView extends React . PureComponent {
36+ type Props = TopLevelViewPropsType
37+
38+ type State = {
39+ contacts : Array < ContactType > ,
40+ loading : boolean ,
41+ refreshing : boolean ,
42+ }
43+
44+ export class ContactsListView extends React . PureComponent < void , Props , State > {
3245 static navigationOptions = {
3346 title : 'Important Contacts' ,
3447 headerBackTitle : 'Contacts' ,
3548 }
3649
50+ state = {
51+ contacts : defaultData . data ,
52+ loading : true ,
53+ refreshing : false ,
54+ }
55+
56+ componentWillMount ( ) {
57+ this . fetchData ( )
58+ }
59+
60+ refresh = async ( ) => {
61+ const start = Date . now ( )
62+ this . setState ( ( ) => ( { refreshing : true } ) )
63+
64+ await this . fetchData ( )
65+
66+ // wait 0.5 seconds – if we let it go at normal speed, it feels broken.
67+ const elapsed = Date . now ( ) - start
68+ if ( elapsed < 500 ) {
69+ await delay ( 500 - elapsed )
70+ }
71+
72+ this . setState ( ( ) => ( { refreshing : false } ) )
73+ }
74+
75+ fetchData = async ( ) => {
76+ this . setState ( ( ) => ( { loading : true } ) )
77+
78+ let { data : contacts } = await fetchJson ( GITHUB_URL ) . catch ( err => {
79+ reportNetworkProblem ( err )
80+ return defaultData
81+ } )
82+
83+ if ( process . env . NODE_ENV === 'development' ) {
84+ contacts = defaultData . data
85+ }
86+
87+ this . setState ( ( ) => ( { contacts, loading : false } ) )
88+ }
89+
3790 onPressContact = ( contact : ContactType ) = > {
3891 this . props . navigation . navigate ( 'ContactsDetailView' , {
3992 contact,
@@ -46,12 +99,10 @@ export default class ContactsListView extends React.PureComponent {
4699 renderItem = ( { item} : { item : ContactType } ) =>
47100 < ContactRow contact = { item } onPress = { this . onPressContact } />
48101
49- keyExtractor = ( item : ContactType ) => {
50- return item . title
51- }
102+ keyExtractor = ( item : ContactType ) => item . title
52103
53104 render ( ) {
54- const groupedData = groupContacts ( data )
105+ const groupedData = groupContacts ( this . state . contacts )
55106 return (
56107 < SectionList
57108 ItemSeparatorComponent = { ListSeparator }
@@ -68,6 +119,8 @@ export default class ContactsListView extends React.PureComponent {
68119 keyExtractor = { this . keyExtractor }
69120 renderSectionHeader = { this . renderSectionHeader }
70121 renderItem = { this . renderItem }
122+ refreshing = { this . state . refreshing }
123+ onRefresh = { this . refresh }
71124 />
72125 )
73126 }
0 commit comments