Skip to content

Commit 5e56294

Browse files
committed
edit all BusView classes to extend React.PureComponent
1 parent 8d81163 commit 5e56294

File tree

6 files changed

+254
-224
lines changed

6 files changed

+254
-224
lines changed

source/views/transportation/bus/bus-line.js

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -64,61 +64,69 @@ const parseTime = (now: moment) => time => {
6464
)
6565
}
6666

67-
export function BusLine({line, now}: {line: BusLineType, now: moment}) {
68-
// grab the colors (with fallbacks) via _.get
69-
const barColor = get(barColors, line.line, c.black)
70-
const currentStopColor = get(stopColors, line.line, c.gray)
71-
const androidColor = Platform.OS === 'android' ? {color: barColor} : null
72-
73-
const schedule = getScheduleForNow(line.schedules, now)
74-
if (!schedule) {
75-
return (
76-
<View>
77-
<ListSectionHeader title={line.line} titleStyle={androidColor} />
78-
<ListRow title="This line is not running today." />
79-
</View>
67+
export class BusLine extends React.PureComponent {
68+
props: {line: BusLineType, now: moment}
69+
70+
render() {
71+
const {line, now} = this.props
72+
73+
// grab the colors (with fallbacks) via _.get
74+
const barColor = get(barColors, line.line, c.black)
75+
const currentStopColor = get(stopColors, line.line, c.gray)
76+
const androidColor = Platform.OS === 'android' ? {color: barColor} : null
77+
78+
const schedule = getScheduleForNow(line.schedules, now)
79+
if (!schedule) {
80+
return (
81+
<View>
82+
<ListSectionHeader title={line.line} titleStyle={androidColor} />
83+
<ListRow title="This line is not running today." />
84+
</View>
85+
)
86+
}
87+
88+
const scheduledMoments: FancyBusTimeListType[] = schedule.times.map(
89+
timeset => timeset.map(parseTime(now)),
8090
)
81-
}
8291

83-
const scheduledMoments: FancyBusTimeListType[] = schedule.times.map(timeset =>
84-
timeset.map(parseTime(now)),
85-
)
92+
const moments: FancyBusTimeListType = getSetOfStopsForNow(
93+
scheduledMoments,
94+
now,
95+
)
96+
const pairs: [[string, moment]] = zip(schedule.stops, moments)
8697

87-
const moments: FancyBusTimeListType = getSetOfStopsForNow(
88-
scheduledMoments,
89-
now,
90-
)
91-
const pairs: [[string, moment]] = zip(schedule.stops, moments)
98+
const timesIndex = scheduledMoments.indexOf(moments)
99+
const isLastBus = timesIndex === scheduledMoments.length - 1
100+
const subtitle = makeSubtitle({now, moments, isLastBus})
92101

93-
const timesIndex = scheduledMoments.indexOf(moments)
94-
const isLastBus = timesIndex === scheduledMoments.length - 1
95-
const subtitle = makeSubtitle({now, moments, isLastBus})
102+
return (
103+
<View>
104+
<ListSectionHeader
105+
title={line.line}
106+
subtitle={subtitle}
107+
titleStyle={androidColor}
108+
/>
96109

97-
return (
98-
<View>
99-
<ListSectionHeader
100-
title={line.line}
101-
subtitle={subtitle}
102-
titleStyle={androidColor}
103-
/>
104-
105-
{pairs.map(([placeTitle, moment], i, list) =>
106-
<View key={i}>
107-
<BusStopRow
108-
// get the arrival time for this stop from each bus loop after
109-
// the current time (as given by `now`)
110-
times={scheduledMoments.slice(timesIndex).map(set => set[i])}
111-
place={placeTitle}
112-
now={now}
113-
time={moment}
114-
barColor={barColor}
115-
currentStopColor={currentStopColor}
116-
isFirstRow={i === 0}
117-
isLastRow={i === list.length - 1}
118-
/>
119-
{i < list.length - 1 ? <Separator style={styles.separator} /> : null}
120-
</View>,
121-
)}
122-
</View>
123-
)
110+
{pairs.map(([placeTitle, moment], i, list) =>
111+
<View key={i}>
112+
<BusStopRow
113+
// get the arrival time for this stop from each bus loop after
114+
// the current time (as given by `now`)
115+
times={scheduledMoments.slice(timesIndex).map(set => set[i])}
116+
place={placeTitle}
117+
now={now}
118+
time={moment}
119+
barColor={barColor}
120+
currentStopColor={currentStopColor}
121+
isFirstRow={i === 0}
122+
isLastRow={i === list.length - 1}
123+
/>
124+
{i < list.length - 1
125+
? <Separator style={styles.separator} />
126+
: null}
127+
</View>,
128+
)}
129+
</View>
130+
)
131+
}
124132
}

source/views/transportation/bus/bus-stop-row.js

Lines changed: 80 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -26,79 +26,88 @@ const styles = StyleSheet.create({
2626
},
2727
})
2828

29-
export function BusStopRow({
30-
time,
31-
now,
32-
barColor,
33-
currentStopColor,
34-
place,
35-
times,
36-
isFirstRow,
37-
isLastRow,
38-
}: {
39-
time: moment,
40-
now: moment,
41-
barColor: string,
42-
currentStopColor: string,
43-
place: string,
44-
times: FancyBusTimeListType,
45-
isFirstRow: boolean,
46-
isLastRow: boolean,
47-
}) {
48-
const afterStop = time && now.isAfter(time, 'minute')
49-
const atStop = time && now.isSame(time, 'minute')
50-
const beforeStop = !afterStop && !atStop && time !== false
51-
const skippingStop = time === false
29+
export class BusStopRow extends React.PureComponent {
30+
props: {
31+
time: moment,
32+
now: moment,
33+
barColor: string,
34+
currentStopColor: string,
35+
place: string,
36+
times: FancyBusTimeListType,
37+
isFirstRow: boolean,
38+
isLastRow: boolean,
39+
}
5240

53-
return (
54-
<ListRow fullWidth={true} fullHeight={true}>
55-
<Row>
56-
<ProgressChunk
57-
{...{
58-
barColor,
59-
afterStop,
60-
beforeStop,
61-
atStop,
62-
skippingStop,
63-
currentStopColor,
64-
}}
65-
isFirstChunk={isFirstRow}
66-
isLastChunk={isLastRow}
67-
/>
41+
render() {
42+
const {
43+
time,
44+
now,
45+
barColor,
46+
currentStopColor,
47+
place,
48+
times,
49+
isFirstRow,
50+
isLastRow,
51+
} = this.props
6852

69-
<Column flex={1} style={styles.internalPadding}>
70-
<Title
71-
bold={false}
72-
style={[
73-
skippingStop && styles.skippingStopTitle,
74-
afterStop && styles.passedStopTitle,
75-
atStop && styles.atStopTitle,
76-
]}
77-
>
78-
{place}
79-
</Title>
80-
<Detail lines={1}>
81-
<ScheduleTimes {...{times, skippingStop}} />
82-
</Detail>
83-
</Column>
84-
</Row>
85-
</ListRow>
86-
)
53+
const afterStop = time && now.isAfter(time, 'minute')
54+
const atStop = time && now.isSame(time, 'minute')
55+
const beforeStop = !afterStop && !atStop && time !== false
56+
const skippingStop = time === false
57+
58+
return (
59+
<ListRow fullWidth={true} fullHeight={true}>
60+
<Row>
61+
<ProgressChunk
62+
{...{
63+
barColor,
64+
afterStop,
65+
beforeStop,
66+
atStop,
67+
skippingStop,
68+
currentStopColor,
69+
}}
70+
isFirstChunk={isFirstRow}
71+
isLastChunk={isLastRow}
72+
/>
73+
74+
<Column flex={1} style={styles.internalPadding}>
75+
<Title
76+
bold={false}
77+
style={[
78+
skippingStop && styles.skippingStopTitle,
79+
afterStop && styles.passedStopTitle,
80+
atStop && styles.atStopTitle,
81+
]}
82+
>
83+
{place}
84+
</Title>
85+
<Detail lines={1}>
86+
<ScheduleTimes {...{times, skippingStop}} />
87+
</Detail>
88+
</Column>
89+
</Row>
90+
</ListRow>
91+
)
92+
}
8793
}
8894

89-
const ScheduleTimes = ({
90-
times,
91-
skippingStop,
92-
}: {
93-
skippingStop: boolean,
94-
times: FancyBusTimeListType,
95-
}) => {
96-
return (
97-
<Text style={skippingStop && styles.skippingStopDetail}>
98-
{times
99-
// and format the times
100-
.map(time => (time === false ? 'None' : time.format(TIME_FORMAT)))
101-
.join(' • ')}
102-
</Text>
103-
)
95+
class ScheduleTimes extends React.PureComponent {
96+
props: {
97+
skippingStop: boolean,
98+
times: FancyBusTimeListType,
99+
}
100+
101+
render() {
102+
const {times, skippingStop} = this.props
103+
104+
return (
105+
<Text style={skippingStop && styles.skippingStopDetail}>
106+
{times
107+
// and format the times
108+
.map(time => (time === false ? 'None' : time.format(TIME_FORMAT)))
109+
.join(' • ')}
110+
</Text>
111+
)
112+
}
104113
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// @flow
2+
3+
import React from 'react'
4+
import {ScrollView} from 'react-native'
5+
import type {BusLineType} from './types'
6+
import {BusLine} from './bus-line'
7+
import moment from 'moment-timezone'
8+
import {NoticeView} from '../../components/notice'
9+
10+
import {data as defaultBusLines} from '../../../../docs/bus-times.json'
11+
12+
const TIMEZONE = 'America/Winnipeg'
13+
14+
export class BusView extends React.PureComponent {
15+
static defaultProps = {
16+
busLines: defaultBusLines,
17+
}
18+
19+
state = {
20+
intervalId: 0,
21+
now: moment.tz(TIMEZONE),
22+
}
23+
24+
componentWillMount() {
25+
// This updates the screen every second, so that the "next bus" times are
26+
// updated without needing to leave and come back.
27+
this.setState(() => ({intervalId: setInterval(this.updateTime, 5000)}))
28+
}
29+
30+
componentWillUnmount() {
31+
clearTimeout(this.state.intervalId)
32+
}
33+
34+
props: {
35+
busLines: BusLineType[],
36+
line: string,
37+
}
38+
39+
updateTime = () => {
40+
this.setState(() => ({now: moment.tz(TIMEZONE)}))
41+
}
42+
43+
render() {
44+
let {now} = this.state
45+
// now = moment.tz('Fri 8:13pm', 'ddd h:mma', true, TIMEZONE)
46+
const busLines = this.props.busLines
47+
const activeBusLine = busLines.find(({line}) => line === this.props.line)
48+
49+
if (!activeBusLine) {
50+
const {line} = this.props
51+
const lines = busLines.map(({line}) => line).join(', ')
52+
return (
53+
<NoticeView text={`The line "${line}" was not found among ${lines}`} />
54+
)
55+
}
56+
57+
return (
58+
<ScrollView>
59+
<BusLine line={activeBusLine} now={now} />
60+
</ScrollView>
61+
)
62+
}
63+
}

0 commit comments

Comments
 (0)