Skip to content

Commit 4e8f280

Browse files
authored
Merge branch 'master' into building-hours-list-fix
2 parents 8af1e85 + 1818f89 commit 4e8f280

File tree

14 files changed

+259
-93
lines changed

14 files changed

+259
-93
lines changed

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ The Calendar won't work until you give it a Google Calendar API key. You should
2222
1. Create a copy of the `.env.sample.js` file and rename it to `.env.js`
2323
2. Insert your API key in place of the `key goes here` text
2424

25-
## Todo
26-
* Bugs! All bugs should have the [`bug`](https://github.com/StoDevX/AAO-React-Native/issues?q=is%3Aopen+is%3Aissue+label%3Abug) label in the issues
25+
## Contributing
26+
* Bugs! All bugs should have the [`bug/general`](https://github.com/StoDevX/AAO-React-Native/labels/bug%2Fgeneral) or [`bug/layout`](https://github.com/StoDevX/AAO-React-Native/labels/bug%2Flayout) label in the issues
2727
* Enhancements! All ideas for improvement that are not being worked on should be [`closed` and labelled as `discussion`](https://github.com/StoDevX/AAO-React-Native/issues?utf8=%E2%9C%93&q=is%3Aclosed%20is%3Aissue%20label%3Astatus%2Fdiscussion)
28-
* [3D touch actions](https://github.com/jordanbyron/react-native-quick-actions) for icon and within
29-
* [Touch-ID](https://github.com/naoufal/react-native-touch-id) for SIS
3028

31-
## Contributing
32-
Please see [CONTRIBUTING](CONTRIBUTING.md)
29+
For full information, see [CONTRIBUTING](CONTRIBUTING.md)

data/bus-times/express.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ schedules:
2121
stops:
2222
[St. Olaf, Carleton, Food Co-op, Cub/Target, El Tequila, Food Co-op, Carleton, St. Olaf]
2323
times:
24-
- ['1:15pm', '1:22pm', '1:23pm', '1:33pm', '1:37pm', '1:43pm', '1:44pm', '1:52pm']
25-
- ['1:55pm', '2:02pm', '2:03pm', '2:13pm', '2:17pm', '2:23pm', '2:24pm', '2:32pm']
26-
- ['2:35pm', '2:42pm', '2:43pm', '2:53pm', '2:57pm', '3:03pm', '3:04pm', '3:12pm']
2724
- ['3:15pm', '3:22pm', '3:23pm', '3:33pm', '3:37pm', '3:43pm', '3:44pm', '3:52pm']
25+
- ['3:55pm', '4:02pm', '4:03pm', '4:13pm', '4:17pm', '4:23pm', '4:24pm', '4:32pm']
26+
- ['4:35pm', '4:42pm', '4:43pm', '4:53pm', '4:57pm', '4:03pm', '5:04pm', '5:12pm']
27+
- ['5:15pm', '5:22pm', '5:23pm', '5:33pm', '5:37pm', '5:43pm', '5:44pm', '5:52pm']

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"react-native-custom-tabs": "0.1.6",
7272
"react-native-datepicker": "1.6.0",
7373
"react-native-device-info": "0.11.0",
74-
"react-native-google-analytics-bridge": "5.3.0",
74+
"react-native-google-analytics-bridge": "5.3.1",
7575
"react-native-keychain": "2.0.0-rc",
7676
"react-native-linear-gradient": "2.3.0",
7777
"react-native-maps": "0.16.3",
@@ -112,7 +112,7 @@
112112
"eslint-plugin-react-native": "3.1.0",
113113
"flow-bin": "0.45.0",
114114
"jest": "21.0.2",
115-
"js-yaml": "3.9.1",
115+
"js-yaml": "3.10.0",
116116
"junk": "2.1.0",
117117
"marked": "0.3.6",
118118
"minimist": "1.2.0",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @flow
2+
3+
import {tracker} from '../analytics'
4+
import bugsnag from '../bugsnag'
5+
6+
export function reportNetworkProblem(err: Error) {
7+
tracker.trackException(err.message)
8+
bugsnag.notify(err)
9+
console.warn(err)
10+
}

source/views/building-hours/detail/building.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {getShortBuildingStatus} from '../lib'
1616
import {Badge} from './badge'
1717
import {Header} from './header'
1818
import {ScheduleTable} from './schedule-table'
19+
import {ListFooter} from '../../components/list'
1920

2021
const transparentPixel = require('../../../../images/transparent.png')
2122

@@ -72,6 +73,12 @@ export class BuildingDetail extends React.Component<void, Props, void> {
7273
now={now}
7374
onProblemReport={onProblemReport}
7475
/>
76+
77+
<ListFooter
78+
title={
79+
'Building hours subject to change without notice\n\nData collected by the humans of All About Olaf'
80+
}
81+
/>
7582
</View>
7683
</ParallaxView>
7784
)

source/views/building-hours/list.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,18 @@
55
*/
66

77
import React from 'react'
8-
import {StyleSheet, SectionList} from 'react-native'
8+
import {SectionList} from 'react-native'
99
import {BuildingRow} from './row'
1010
import {tracker} from '../../analytics'
1111

1212
import type momentT from 'moment'
1313
import type {TopLevelViewPropsType} from '../types'
1414
import type {BuildingType} from './types'
1515

16-
import * as c from '../components/colors'
17-
import {ListSeparator, ListSectionHeader} from '../components/list'
16+
import {ListSeparator, ListSectionHeader, ListFooter} from '../components/list'
1817

1918
export {BuildingHoursDetailView} from './detail'
2019

21-
const styles = StyleSheet.create({
22-
container: {
23-
backgroundColor: c.white,
24-
},
25-
})
26-
2720
export class BuildingHoursList extends React.PureComponent {
2821
props: TopLevelViewPropsType & {
2922
now: momentT,
@@ -54,12 +47,18 @@ export class BuildingHoursList extends React.PureComponent {
5447
return (
5548
<SectionList
5649
ItemSeparatorComponent={ListSeparator}
50+
ListFooterComponent={
51+
<ListFooter
52+
title={
53+
'Building hours subject to change without notice\n\nData collected by the humans of All About Olaf'
54+
}
55+
/>
56+
}
5757
sections={(this.props.buildings: any)}
5858
extraData={this.props}
5959
keyExtractor={this.keyExtractor}
6060
renderSectionHeader={this.renderSectionHeader}
6161
renderItem={this.renderItem}
62-
contentContainerStyle={styles.container}
6362
refreshing={this.props.loading}
6463
onRefresh={this.props.onRefresh}
6564
/>

source/views/building-hours/row.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import {ListRow, Detail, Title} from '../components/list'
1515
import {getDetailedBuildingStatus, getShortBuildingStatus} from './lib'
1616

1717
const styles = StyleSheet.create({
18+
row: {
19+
backgroundColor: c.white,
20+
},
1821
title: {
1922
justifyContent: 'space-between',
2023
alignItems: 'center',
@@ -133,7 +136,7 @@ export class BuildingRow extends React.Component<void, Props, State> {
133136
const {openStatus, hours, accentBg, accentText} = this.state
134137

135138
return (
136-
<ListRow onPress={this.onPress} arrowPosition="center">
139+
<ListRow onPress={this.onPress} arrowPosition="center" style={styles.row}>
137140
<Row style={styles.title}>
138141
<Title lines={1} style={styles.titleText}>
139142
<Text>{name}</Text>

source/views/components/list/list-footer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const styles = StyleSheet.create({
1616
export class ListFooter extends React.PureComponent {
1717
props: {
1818
title: string,
19-
href: string,
19+
href?: string,
2020
}
2121

2222
render() {

source/views/streaming/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import {StreamListView} from './streams'
1313

1414
export default TabNavigator(
1515
{
16+
StreamingView: {screen: StreamListView},
17+
LiveWebcamsView: {screen: WebcamsView},
1618
KSTORadioView: {screen: KSTOView},
1719
// WeeklyMovieView: {screen: WeeklyMovieView},
18-
LiveWebcamsView: {screen: WebcamsView},
19-
StreamingView: {screen: StreamListView},
2020
},
2121
{
2222
navigationOptions: {

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

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// @flow
22
import React from 'react'
33
import {View, Text, StyleSheet, Platform} from 'react-native'
4-
import type {BusLineType, FancyBusTimeListType} from './types'
4+
import type {BusLineType, FancyBusTimeListType, BusScheduleType} from './types'
55
import {getScheduleForNow, getSetOfStopsForNow} from './lib'
66
import get from 'lodash/get'
77
import zip from 'lodash/zip'
88
import head from 'lodash/head'
9+
import isEqual from 'lodash/isEqual'
910
import last from 'lodash/last'
1011
import moment from 'moment-timezone'
1112
import * as c from '../../components/colors'
@@ -49,7 +50,7 @@ function makeSubtitle({now, moments, isLastBus}) {
4950
return lineDetail
5051
}
5152

52-
const parseTime = (now: moment) => time => {
53+
const parseTime = (now: moment) => (time: string | false) => {
5354
// either pass `false` through or return a parsed time
5455
if (time === false) {
5556
return false
@@ -64,18 +65,101 @@ const parseTime = (now: moment) => time => {
6465
)
6566
}
6667

67-
export class BusLine extends React.PureComponent {
68-
props: {line: BusLineType, now: moment, openMap: () => any}
68+
type Props = {
69+
line: BusLineType,
70+
now: moment,
71+
openMap: () => any,
72+
}
73+
74+
type State = {
75+
schedule: ?BusScheduleType,
76+
scheduledMoments: Array<FancyBusTimeListType>,
77+
currentMoments: FancyBusTimeListType,
78+
stopTitleTimePairs: Array<[string, moment]>,
79+
}
80+
81+
export class BusLine extends React.Component<void, Props, State> {
82+
state = {
83+
schedule: null,
84+
scheduledMoments: [],
85+
currentMoments: [],
86+
stopTitleTimePairs: [],
87+
firstUpdate: true,
88+
}
89+
90+
componentWillMount() {
91+
this.setStateFromProps(this.props)
92+
}
93+
94+
componentWillReceiveProps(nextProps: Props) {
95+
this.setStateFromProps(nextProps)
96+
}
97+
98+
shouldComponentUpdate(nextProps: Props, nextState: State) {
99+
// We won't check the time in shouldComponentUpdate, because we really
100+
// only care if the bus information has changed, and this is called after
101+
// setStateFromProps runs.
102+
103+
return (
104+
this.props.line !== nextProps.line ||
105+
this.props.openMap !== nextProps.openMap ||
106+
!isEqual(this.state.currentMoments, nextState.currentMoments)
107+
)
108+
}
109+
110+
setStateFromProps = (nextProps: Props) => {
111+
if (
112+
this.props.now.isSame(nextProps.now, 'minute') &&
113+
!this.state.firstUpdate
114+
) {
115+
return
116+
}
117+
118+
const {line, now} = nextProps
119+
120+
const schedule = getScheduleForNow(line.schedules, now)
121+
if (!schedule) {
122+
return
123+
}
124+
125+
const parseTimes = timeset => timeset.map(parseTime(now))
126+
const scheduledMoments: Array<FancyBusTimeListType> = schedule.times.map(
127+
parseTimes,
128+
)
129+
130+
const currentMoments: FancyBusTimeListType = getSetOfStopsForNow(
131+
scheduledMoments,
132+
now,
133+
)
134+
135+
const stopTitleTimePairs: Array<[string, moment]> = zip(
136+
schedule.stops,
137+
currentMoments,
138+
)
139+
140+
this.setState(() => ({
141+
schedule,
142+
scheduledMoments,
143+
currentMoments,
144+
stopTitleTimePairs,
145+
firstUpdate: false,
146+
}))
147+
}
69148

70149
render() {
71150
const {line, now} = this.props
151+
const {
152+
schedule,
153+
scheduledMoments,
154+
currentMoments,
155+
stopTitleTimePairs,
156+
} = this.state
72157

73158
// grab the colors (with fallbacks) via _.get
74159
const barColor = get(barColors, line.line, c.black)
75160
const currentStopColor = get(stopColors, line.line, c.gray)
76161
const androidColor = Platform.OS === 'android' ? {color: barColor} : null
77162

78-
const schedule = getScheduleForNow(line.schedules, now)
79163
if (!schedule) {
80164
return (
81165
<View>
@@ -87,19 +171,9 @@ export class BusLine extends React.PureComponent {
87171
)
88172
}
89173

90-
const scheduledMoments: FancyBusTimeListType[] = schedule.times.map(
91-
timeset => timeset.map(parseTime(now)),
92-
)
93-
94-
const moments: FancyBusTimeListType = getSetOfStopsForNow(
95-
scheduledMoments,
96-
now,
97-
)
98-
const pairs: [[string, moment]] = zip(schedule.stops, moments)
99-
100-
const timesIndex = scheduledMoments.indexOf(moments)
174+
const timesIndex = scheduledMoments.indexOf(currentMoments)
101175
const isLastBus = timesIndex === scheduledMoments.length - 1
102-
const subtitle = makeSubtitle({now, moments, isLastBus})
176+
const subtitle = makeSubtitle({now, moments: currentMoments, isLastBus})
103177

104178
return (
105179
<View>
@@ -109,7 +183,7 @@ export class BusLine extends React.PureComponent {
109183
titleStyle={androidColor}
110184
/>
111185

112-
{pairs.map(([placeTitle, moment], i, list) =>
186+
{stopTitleTimePairs.map(([placeTitle, moment], i, list) =>
113187
<View key={i}>
114188
<BusStopRow
115189
// get the arrival time for this stop from each bus loop after

0 commit comments

Comments
 (0)