Skip to content

Commit 7aa486d

Browse files
authored
Merge pull request #1720 from StoDevX/add-back-refresh-to-lists
Add back refresh to lists
2 parents fa0bdaf + ee9a4e2 commit 7aa486d

File tree

9 files changed

+139
-85
lines changed

9 files changed

+139
-85
lines changed

source/views/calendar/calendar-google.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,22 @@ export class GoogleCalendarView extends React.Component {
2222

2323
state: {
2424
events: EventType[],
25-
loaded: boolean,
25+
loading: boolean,
2626
refreshing: boolean,
2727
error: ?Error,
2828
now: moment,
2929
} = {
3030
events: [],
31-
loaded: false,
31+
loading: true,
3232
refreshing: false,
3333
error: null,
3434
now: moment.tz(TIMEZONE),
3535
}
3636

3737
componentWillMount() {
38-
this.getEvents()
38+
this.getEvents().then(() => {
39+
this.setState(() => ({loading: false}))
40+
})
3941
}
4042

4143
buildCalendarUrl(calendarId: string) {
@@ -87,11 +89,7 @@ export class GoogleCalendarView extends React.Component {
8789
console.warn(err)
8890
}
8991

90-
this.setState({
91-
now,
92-
loaded: true,
93-
events: this.convertEvents(data, now),
94-
})
92+
this.setState({now, events: this.convertEvents(data, now)})
9593
}
9694

9795
refresh = async () => {
@@ -110,7 +108,7 @@ export class GoogleCalendarView extends React.Component {
110108
}
111109

112110
render() {
113-
if (!this.state.loaded) {
111+
if (this.state.loading) {
114112
return <LoadingView />
115113
}
116114

source/views/contacts/contact-list.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {SectionList, StyleSheet} from 'react-native'
99
import {ListSeparator, ListSectionHeader} from '../components/list'
1010
import {ListEmpty} from '../components/list'
1111
import {ContactRow} from './contact-row'
12+
import delay from 'delay'
1213
import {reportNetworkProblem} from '../../lib/report-network-problem'
1314
import * as defaultData from '../../../docs/contact-info.json'
1415
import groupBy from 'lodash/groupBy'
@@ -36,6 +37,7 @@ type Props = TopLevelViewPropsType
3637
type State = {
3738
contacts: Array<ContactType>,
3839
loading: boolean,
40+
refreshing: boolean,
3941
}
4042

4143
export class ContactsListView extends React.PureComponent<void, Props, State> {
@@ -47,15 +49,31 @@ export class ContactsListView extends React.PureComponent<void, Props, State> {
4749
state = {
4850
contacts: defaultData.data,
4951
loading: true,
52+
refreshing: false,
5053
}
5154

5255
componentWillMount() {
53-
this.fetchData()
56+
this.fetchData().then(() => {
57+
this.setState(() => ({loading: false}))
58+
})
5459
}
5560

56-
fetchData = async () => {
57-
this.setState(() => ({loading: true}))
61+
refresh = async () => {
62+
const start = Date.now()
63+
this.setState(() => ({refreshing: true}))
64+
65+
await this.fetchData()
66+
67+
// wait 0.5 seconds – if we let it go at normal speed, it feels broken.
68+
const elapsed = Date.now() - start
69+
if (elapsed < 500) {
70+
await delay(500 - elapsed)
71+
}
72+
73+
this.setState(() => ({refreshing: false}))
74+
}
5875

76+
fetchData = async () => {
5977
let {data: contacts} = await fetchJson(GITHUB_URL).catch(err => {
6078
reportNetworkProblem(err)
6179
return defaultData
@@ -65,7 +83,7 @@ export class ContactsListView extends React.PureComponent<void, Props, State> {
6583
contacts = defaultData.data
6684
}
6785

68-
this.setState(() => ({contacts, loading: false}))
86+
this.setState(() => ({contacts}))
6987
}
7088

7189
onPressContact = (contact: ContactType) => {
@@ -96,6 +114,8 @@ export class ContactsListView extends React.PureComponent<void, Props, State> {
96114
keyExtractor={this.keyExtractor}
97115
renderSectionHeader={this.renderSectionHeader}
98116
renderItem={this.renderItem}
117+
refreshing={this.state.refreshing}
118+
onRefresh={this.refresh}
99119
/>
100120
)
101121
}

source/views/dictionary/list.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22

33
import React from 'react'
4-
import {StyleSheet, Platform} from 'react-native'
4+
import {StyleSheet, RefreshControl, Platform} from 'react-native'
55
import {SearchableAlphabetListView} from '../components/searchable-alphabet-listview'
66
import {Column} from '../components/layout'
77
import {
@@ -49,7 +49,7 @@ type Props = TopLevelViewPropsType
4949
type State = {
5050
results: {[key: string]: Array<WordType>},
5151
allTerms: Array<WordType>,
52-
loading: boolean,
52+
refreshing: boolean,
5353
}
5454

5555
export class DictionaryView extends React.PureComponent<void, Props, State> {
@@ -61,16 +61,16 @@ export class DictionaryView extends React.PureComponent<void, Props, State> {
6161
state = {
6262
results: defaultData.data,
6363
allTerms: defaultData.data,
64-
loading: true,
64+
refreshing: false,
6565
}
6666

6767
componentWillMount() {
68-
this.refresh()
68+
this.fetchData()
6969
}
7070

7171
refresh = async () => {
7272
const start = Date.now()
73-
this.setState(() => ({loading: true}))
73+
this.setState(() => ({refreshing: true}))
7474

7575
await this.fetchData()
7676

@@ -80,7 +80,7 @@ export class DictionaryView extends React.PureComponent<void, Props, State> {
8080
await delay(500 - elapsed)
8181
}
8282

83-
this.setState(() => ({loading: false}))
83+
this.setState(() => ({refreshing: false}))
8484
}
8585

8686
fetchData = async () => {
@@ -139,6 +139,13 @@ export class DictionaryView extends React.PureComponent<void, Props, State> {
139139
}
140140

141141
render() {
142+
const refreshControl = (
143+
<RefreshControl
144+
refreshing={this.state.refreshing}
145+
onRefresh={this.refresh}
146+
/>
147+
)
148+
142149
return (
143150
<SearchableAlphabetListView
144151
cell={this.renderRow}
@@ -148,6 +155,7 @@ export class DictionaryView extends React.PureComponent<void, Props, State> {
148155
}
149156
data={groupBy(this.state.results, item => head(item.word))}
150157
onSearch={this.performSearch}
158+
refreshControl={refreshControl}
151159
renderSeparator={this.renderSeparator}
152160
sectionHeader={this.renderSectionHeader}
153161
sectionHeaderHeight={SECTION_HEADER_HEIGHT}

source/views/faqs/index.js

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// @flow
22
import React from 'react'
3+
import {RefreshControl} from 'react-native'
34
import {ScrollView} from 'glamorous-native'
45
import {Markdown} from '../components/markdown'
6+
import {reportNetworkProblem} from '../../lib/report-network-problem'
57
import LoadingView from '../components/loading'
6-
import {text} from '../../../docs/faqs.json'
7-
import {tracker} from '../../analytics'
8-
import bugsnag from '../../bugsnag'
8+
import * as defaultData from '../../../docs/faqs.json'
9+
import delay from 'delay'
910

1011
const faqsUrl = 'https://stodevx.github.io/AAO-React-Native/faqs.json'
1112

@@ -15,39 +16,59 @@ export class FaqView extends React.PureComponent {
1516
}
1617

1718
state = {
18-
text: text,
19+
text: defaultData.text,
20+
loading: true,
21+
refreshing: false,
1922
}
2023

2124
componentWillMount() {
22-
this.fetchData()
25+
this.fetchData().then(() => {
26+
this.setState(() => ({loading: false}))
27+
})
2328
}
2429

2530
fetchData = async () => {
26-
let fetched = text
27-
try {
28-
let blob: {text: string} = await fetchJson(faqsUrl)
29-
fetched = blob.text
30-
} catch (err) {
31-
tracker.trackException(err.message)
32-
bugsnag.notify(err)
33-
console.warn(err.message)
34-
}
31+
let {text} = await fetchJson(faqsUrl).catch(err => {
32+
reportNetworkProblem(err)
33+
return {text: 'There was a problem loading the FAQs'}
34+
})
3535

3636
if (process.env.NODE_ENV === 'development') {
37-
fetched = text
37+
text = defaultData.text
3838
}
3939

40-
this.setState({text: fetched})
40+
this.setState(() => ({text}))
41+
}
42+
43+
refresh = async () => {
44+
const start = Date.now()
45+
this.setState(() => ({refreshing: true}))
46+
47+
await this.fetchData()
48+
49+
// wait 0.5 seconds – if we let it go at normal speed, it feels broken.
50+
const elapsed = Date.now() - start
51+
if (elapsed < 500) {
52+
await delay(500 - elapsed)
53+
}
54+
this.setState(() => ({refreshing: false}))
4155
}
4256

4357
render() {
44-
if (!this.state.text) {
58+
if (this.state.loading) {
4559
return <LoadingView />
4660
}
4761

62+
const refreshControl = (
63+
<RefreshControl
64+
refreshing={this.state.refreshing}
65+
onRefresh={this.refresh}
66+
/>
67+
)
68+
4869
return (
49-
<ScrollView paddingHorizontal={15}>
50-
<Markdown source={text} />
70+
<ScrollView refreshControl={refreshControl} paddingHorizontal={15}>
71+
<Markdown source={this.state.text} />
5172
</ScrollView>
5273
)
5374
}

source/views/sis/student-work/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,20 @@ export default class StudentWorkView extends React.PureComponent {
4343

4444
state: {
4545
jobs: Array<{title: string, data: Array<JobType>}>,
46-
loaded: boolean,
46+
loading: boolean,
4747
refreshing: boolean,
4848
error: boolean,
4949
} = {
5050
jobs: [],
51-
loaded: false,
51+
loading: true,
5252
refreshing: false,
5353
error: false,
5454
}
5555

5656
componentWillMount() {
57-
this.fetchData()
57+
this.fetchData().then(() => {
58+
this.setState(() => ({loading: false}))
59+
})
5860
}
5961

6062
fetchData = async () => {
@@ -87,8 +89,6 @@ export default class StudentWorkView extends React.PureComponent {
8789
this.setState(() => ({error: true}))
8890
console.error(err)
8991
}
90-
91-
this.setState(() => ({loaded: true}))
9292
}
9393

9494
refresh = async () => {
@@ -124,7 +124,7 @@ export default class StudentWorkView extends React.PureComponent {
124124
return <Text selectable={true}>{this.state.error}</Text>
125125
}
126126

127-
if (!this.state.loaded) {
127+
if (this.state.loading) {
128128
return <LoadingView />
129129
}
130130

source/views/streaming/streams/list.js

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,21 @@ export class StreamListView extends React.PureComponent {
3737
}
3838

3939
state: {
40-
error: ?Error,
41-
loaded: boolean,
42-
noStreams: boolean,
40+
error: ?string,
41+
loading: boolean,
4342
refreshing: boolean,
4443
streams: Array<{title: string, data: Array<StreamType>}>,
4544
} = {
4645
error: null,
47-
loaded: false,
48-
noStreams: false,
46+
loading: true,
4947
refreshing: false,
5048
streams: [],
5149
}
5250

5351
componentWillMount() {
54-
this.getStreams()
52+
this.getStreams().then(() => {
53+
this.setState(() => ({loading: false}))
54+
})
5555
}
5656

5757
refresh = async () => {
@@ -90,10 +90,6 @@ export class StreamListView extends React.PureComponent {
9090
const data = await fetchJson(streamsAPI)
9191
const streams = data.results
9292

93-
if (streams.length > 1) {
94-
this.setState(() => ({noStreams: true}))
95-
}
96-
9793
// force title-case on the stream types, to prevent not-actually-duplicate headings
9894
const processed = streams
9995
.filter(stream => stream.category !== 'athletics')
@@ -115,11 +111,7 @@ export class StreamListView extends React.PureComponent {
115111
const grouped = groupBy(processed, j => j.$groupBy)
116112
const mapped = toPairs(grouped).map(([title, data]) => ({title, data}))
117113

118-
this.setState(() => ({
119-
error: null,
120-
loaded: true,
121-
streams: mapped,
122-
}))
114+
this.setState(() => ({error: null, streams: mapped}))
123115
} catch (error) {
124116
this.setState(() => ({error: error.message}))
125117
console.warn(error)
@@ -135,12 +127,12 @@ export class StreamListView extends React.PureComponent {
135127
renderItem = ({item}: {item: StreamType}) => <StreamRow stream={item} />
136128

137129
render() {
138-
if (!this.state.loaded) {
130+
if (this.state.loading) {
139131
return <LoadingView />
140132
}
141133

142134
if (this.state.error) {
143-
return <NoticeView text={'Error: ' + this.state.error.message} />
135+
return <NoticeView text={'Error: ' + this.state.error} />
144136
}
145137

146138
return (

0 commit comments

Comments
 (0)