Skip to content

Commit eecbb20

Browse files
committed
group events by day
1 parent f5fae39 commit eecbb20

File tree

2 files changed

+81
-34
lines changed

2 files changed

+81
-34
lines changed

views/calendar/calendar.js

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import {
1111
Platform,
1212
ListView,
1313
RefreshControl,
14+
View,
1415
} from 'react-native'
1516

17+
import groupBy from 'lodash/groupBy'
18+
import moment from 'moment-timezone'
1619
import delay from 'delay'
1720
import LoadingView from '../components/loading'
1821
import qs from 'querystring'
1922
import EventView from './event'
23+
import * as c from '../components/colors'
2024
import { GOOGLE_CALENDAR_API_KEY } from '../../lib/config'
2125

2226
type GoogleCalendarTimeType = {
@@ -36,7 +40,8 @@ export default class CalendarView extends React.Component {
3640

3741
state = {
3842
events: new ListView.DataSource({
39-
rowHasChanged: this._rowHasChanged,
43+
rowHasChanged: this.rowHasChanged,
44+
sectionHeaderHasChanged: this.sectionHeaderHasChanged,
4045
}),
4146
loaded: false,
4247
refreshing: true,
@@ -47,8 +52,12 @@ export default class CalendarView extends React.Component {
4752
this.refresh()
4853
}
4954

50-
_rowHasChanged(r1: GoogleCalendarEventType, r2: GoogleCalendarEventType) {
51-
return r1.summary != r2.summary
55+
rowHasChanged(r1: GoogleCalendarEventType, r2: GoogleCalendarEventType) {
56+
return r1.summary !== r2.summary
57+
}
58+
59+
sectionHeaderHasChanged(h1: number, h2: number) {
60+
return h1 !== h2
5261
}
5362

5463
buildCalendarUrl(calendarId: string) {
@@ -79,7 +88,12 @@ export default class CalendarView extends React.Component {
7988
}
8089

8190
if (data) {
82-
this.setState({events: this.state.events.cloneWithRows(data)})
91+
data.forEach(event => {
92+
event.startTime = moment(event.start.dateTime)
93+
event.endTime = moment(event.end.dateTime)
94+
})
95+
let grouped = groupBy(data, event => event.startTime.format('ddd MMM Do'))
96+
this.setState({events: this.state.events.cloneWithRowsAndSections(grouped)})
8397
}
8498
if (error) {
8599
this.setState({error: error.message})
@@ -102,6 +116,32 @@ export default class CalendarView extends React.Component {
102116
this.setState({refreshing: false})
103117
}
104118

119+
renderRow = (data: Object) => {
120+
return (
121+
<EventView
122+
style={styles.row}
123+
eventTitle={data.summary}
124+
startTime={data.startTime}
125+
endTime={data.endTime}
126+
location={data.location}
127+
/>
128+
)
129+
}
130+
131+
renderSectionHeader = (sectionData: Object, sectionIdentifier: any) => {
132+
return (
133+
<View style={styles.rowSectionHeader}>
134+
<Text style={styles.rowSectionHeaderText} numberOfLines={1}>
135+
{sectionIdentifier}
136+
</Text>
137+
</View>
138+
)
139+
}
140+
141+
renderSeparator = (sectionID: any, rowID: any) => {
142+
return <View key={`${sectionID}-${rowID}`} style={styles.separator} />
143+
}
144+
105145
render() {
106146
if (!this.state.loaded) {
107147
return <LoadingView />
@@ -117,15 +157,9 @@ export default class CalendarView extends React.Component {
117157
contentInset={{bottom: Platform.OS === 'ios' ? 49 : 0}}
118158
dataSource={this.state.events}
119159
pageSize={5}
120-
renderRow={data =>
121-
<EventView
122-
style={styles.row}
123-
eventTitle={data.summary}
124-
startTime={data.start.dateTime}
125-
endTime={data.end.dateTime}
126-
location={data.location}
127-
/>
128-
}
160+
renderRow={this.renderRow}
161+
renderSectionHeader={this.renderSectionHeader}
162+
renderSeparator={this.renderSeparator}
129163
refreshControl={
130164
<RefreshControl
131165
refreshing={this.state.refreshing}
@@ -144,9 +178,24 @@ let styles = StyleSheet.create({
144178
},
145179
row: {
146180
minHeight: 88,
147-
marginLeft: 10,
148-
paddingRight: 10,
149-
borderBottomWidth: 1,
181+
// marginLeft: 10,
182+
// paddingRight: 10,
183+
},
184+
separator: {
185+
borderBottomWidth: StyleSheet.hairlineWidth,
150186
borderBottomColor: '#ebebeb',
151187
},
188+
rowSectionHeader: {
189+
backgroundColor: c.iosListSectionHeader,
190+
paddingTop: 5,
191+
paddingBottom: 5,
192+
paddingLeft: 10,
193+
borderTopWidth: 1,
194+
borderBottomWidth: 1,
195+
borderColor: '#ebebeb',
196+
},
197+
rowSectionHeaderText: {
198+
color: 'black',
199+
fontWeight: 'bold',
200+
},
152201
})

views/calendar/event.js

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,50 @@ import {
55
Text,
66
} from 'react-native'
77

8-
import moment from 'moment-timezone'
98
import * as c from '../components/colors'
109
import {getText, parseHtml} from '../../lib/html'
1110

1211
let styles = StyleSheet.create({
12+
container: {
13+
paddingTop: 10,
14+
paddingBottom: 6,
15+
paddingLeft: 10,
16+
},
1317
itemTitle: {
1418
color: c.black,
15-
paddingLeft: 10,
16-
paddingRight: 10,
17-
paddingTop: 10,
1819
paddingBottom: 3,
1920
fontSize: 16,
20-
textAlign: 'left',
21+
fontWeight: '500',
2122
},
2223
itemPreview: {
2324
color: c.iosText,
24-
paddingLeft: 10,
25-
paddingRight: 10,
26-
paddingBottom: 6,
2725
fontSize: 13,
28-
textAlign: 'left',
2926
},
3027
})
3128

3229
// PROPS: eventTitle, location, startTime, endTime
33-
export default function EventView(props: {eventTitle: string, location: string, startTime?: string, endTime?: string, style?: any}) {
30+
export default function EventView(props: {eventTitle: string, location: string, startTime?: Object, endTime?: Object, style?: any}) {
3431
let title = getText(parseHtml(props.eventTitle))
3532

36-
let stString = moment(props.startTime).format('M/D h:mma')
37-
let etString = moment(props.endTime).format('M/D h:mma')
38-
3933
let showTimes = props.startTime && props.endTime
4034
let showLocation = Boolean(props.location)
4135

4236
return (
43-
<View style={props.style}>
37+
<View style={[styles.container, props.style]}>
4438
<Text style={styles.itemTitle}>{title}</Text>
45-
{ showTimes ? <Text style={styles.itemPreview}>{stString} - {etString}</Text> : null }
46-
{ showLocation ? <Text style={styles.itemPreview}>{props.location}</Text> : null }
39+
{ showTimes ? <Text style={styles.itemPreview}>
40+
{props.startTime.format('M/D h:mma')}{props.endTime.format('M/D h:mma')}
41+
</Text> : null }
42+
{ showLocation ? <Text style={styles.itemPreview}>
43+
{props.location}
44+
</Text> : null }
4745
</View>
4846
)
4947
}
5048
EventView.propTypes = {
51-
endTime: React.PropTypes.string,
49+
endTime: React.PropTypes.object,
5250
eventTitle: React.PropTypes.string.isRequired,
5351
location: React.PropTypes.string,
54-
startTime: React.PropTypes.string,
52+
startTime: React.PropTypes.object,
5553
style: React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.object]),
5654
}

0 commit comments

Comments
 (0)