1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | import React from 'react'
|
7 | import { View, StyleSheet } from 'react-native'
|
8 | import WheelPicker from './WheelPicker'
|
9 | import {
|
10 | hourTo24Format,
|
11 | hourTo12Format,
|
12 | pickerDateArray,
|
13 | getHoursArray,
|
14 | increaseDateByDays,
|
15 | getFiveMinutesArray,
|
16 | getAmArray,
|
17 | } from './Utils'
|
18 |
|
19 | const millisecondsPerDay = 1000 * 60 * 60 * 24
|
20 | const HOUR = 60
|
21 |
|
22 | type Props = {
|
23 | initDate: string,
|
24 | hours: Array<number>,
|
25 | minutes: Array<string>,
|
26 | onDateSelected: Date => void,
|
27 | startDate: string,
|
28 | daysCount: number,
|
29 | days: Array<number>,
|
30 | hideDate?: boolean,
|
31 | hideHours?: boolean,
|
32 | hideMinutes?: boolean,
|
33 | hideAM?: boolean,
|
34 | }
|
35 |
|
36 | type State = {
|
37 | selectedDate: Date,
|
38 | daysAfterSelectedDate: number,
|
39 | initDayInex: number,
|
40 | initHourInex: number,
|
41 | initMinuteInex: number,
|
42 | initAmInex: number,
|
43 | }
|
44 |
|
45 | export default class DatePicker extends React.Component<Props, State> {
|
46 | constructor(props: Props) {
|
47 | super(props)
|
48 | const { startDate, minutes } = props
|
49 | const selectedDate = this.props.initDate
|
50 | ? new Date(this.props.initDate)
|
51 | : new Date()
|
52 | const time12format = hourTo12Format(selectedDate.getHours())
|
53 | const time24format = selectedDate.getHours()
|
54 | const millisBetween = selectedDate.getTime() - new Date().getTime()
|
55 | let millisBetweenStartDate
|
56 | let daysStartDate = 0
|
57 | if (startDate) {
|
58 | millisBetweenStartDate =
|
59 | new Date(startDate).getTime() - new Date().getTime()
|
60 | daysStartDate = millisBetweenStartDate / millisecondsPerDay
|
61 | }
|
62 | const days = millisBetween / millisecondsPerDay
|
63 | const daysAfterSelectedDate = Math.round(daysStartDate)
|
64 | const initDayInex = startDate
|
65 | ? Math.round(days) - Math.round(daysStartDate)
|
66 | : Math.round(days)
|
67 | const initHourInex = this.props.format24
|
68 | ? time24format
|
69 | : Number(time12format[0]) - 1
|
70 | const minutesCount = minutes ? minutes.length : 12
|
71 | const initMinuteInex = Math.round(
|
72 | selectedDate.getMinutes() / (HOUR / minutesCount)
|
73 | )
|
74 |
|
75 | const initAmInex = time12format[1] === 'AM' ? 0 : 1
|
76 |
|
77 | this.state = {
|
78 | daysAfterSelectedDate,
|
79 | initDayInex,
|
80 | selectedDate,
|
81 | initHourInex,
|
82 | initMinuteInex,
|
83 | initAmInex,
|
84 | }
|
85 | }
|
86 |
|
87 | render() {
|
88 | const {
|
89 | startDate,
|
90 | days,
|
91 | daysCount,
|
92 | hours,
|
93 | minutes,
|
94 | format24,
|
95 | backgroundColor,
|
96 | hideDate,
|
97 | hideHours,
|
98 | hideMinutes,
|
99 | hideAM,
|
100 | } = this.props
|
101 | const { initHourInex, initDayInex, initMinuteInex } = this.state
|
102 | return (
|
103 | <View style={[styles.container, { backgroundColor }]}>
|
104 | {!hideDate && <WheelPicker
|
105 | style={styles.dateWheelPicker}
|
106 | {...this.props}
|
107 | data={days || pickerDateArray(startDate, daysCount)}
|
108 | onItemSelected={this.onDaySelected}
|
109 | initPosition={initDayInex}
|
110 | />}
|
111 | {!hideHours && <WheelPicker
|
112 | style={styles.wheelPicker}
|
113 | {...this.props}
|
114 | isCyclic
|
115 | data={hours || getHoursArray(format24)}
|
116 | onItemSelected={this.onHourSelected}
|
117 | initPosition={initHourInex}
|
118 | />}
|
119 | {!hideMinutes && <WheelPicker
|
120 | style={styles.wheelPicker}
|
121 | {...this.props}
|
122 | isCyclic
|
123 | data={minutes || getFiveMinutesArray()}
|
124 | onItemSelected={this.onMinuteSelected}
|
125 | initPosition={initMinuteInex}
|
126 | />}
|
127 | {!this.props.format24 && !hideAM && this.renderAm()}
|
128 | </View>
|
129 | )
|
130 | }
|
131 |
|
132 | renderAm() {
|
133 | const { initAmInex } = this.state
|
134 | return (
|
135 | <WheelPicker
|
136 | style={styles.wheelPicker}
|
137 | {...this.props}
|
138 | data={getAmArray()}
|
139 | onItemSelected={this.onAmSelected}
|
140 | initPosition={initAmInex}
|
141 | />
|
142 | )
|
143 | }
|
144 |
|
145 | onDaySelected = (position: number) => {
|
146 | let selectedDate = this.state.selectedDate
|
147 | const daysAfterSelectedDate = this.state.daysAfterSelectedDate
|
148 | const hours = selectedDate.getHours()
|
149 | const minutes = selectedDate.getMinutes()
|
150 |
|
151 | const {
|
152 | startDate,
|
153 | days,
|
154 | daysCount
|
155 | } = this.props
|
156 | const data = days || pickerDateArray(startDate, daysCount)
|
157 | if (data[position] === 'Today') {
|
158 | selectedDate = new Date()
|
159 | } else {
|
160 | selectedDate = increaseDateByDays(
|
161 | new Date(),
|
162 | this.props.startDate
|
163 | ? daysAfterSelectedDate + position
|
164 | : position
|
165 | )
|
166 | }
|
167 | selectedDate.setHours(hours)
|
168 | selectedDate.setMinutes(minutes)
|
169 | this.onDateSelected(selectedDate)
|
170 | }
|
171 |
|
172 | onHourSelected = (position: number) => {
|
173 | const selectedDate = this.state.selectedDate
|
174 | const { hours, format24 } = this.props
|
175 | const data = hours || getHoursArray(format24)
|
176 | if (this.props.format24) {
|
177 | selectedDate.setHours(Number(data[position]))
|
178 | } else {
|
179 | const time12format = hourTo12Format(selectedDate.getHours())
|
180 | const newTime12Format = `${data[position]} ${time12format[1]}`
|
181 | const selectedHour24format = hourTo24Format(newTime12Format)
|
182 | selectedDate.setHours(selectedHour24format)
|
183 | }
|
184 | this.onDateSelected(selectedDate)
|
185 | }
|
186 |
|
187 | onMinuteSelected = (position: number) => {
|
188 | const selectedDate = this.state.selectedDate
|
189 | const { minutes } = this.props
|
190 | const data = minutes || getFiveMinutesArray()
|
191 | selectedDate.setMinutes(Number(data[position]))
|
192 | this.onDateSelected(selectedDate)
|
193 | }
|
194 |
|
195 | onAmSelected = (position: number) => {
|
196 | const selectedDate = this.state.selectedDate
|
197 | const time12format = hourTo12Format(selectedDate.getHours())
|
198 | const newTime12Format = `${time12format[0]} ${getAmArray()[position]}`
|
199 | const selectedHour24format = hourTo24Format(newTime12Format)
|
200 | selectedDate.setHours(selectedHour24format)
|
201 | this.onDateSelected(selectedDate)
|
202 | }
|
203 |
|
204 | onDateSelected(selectedDate: Date) {
|
205 | this.setState({ selectedDate })
|
206 | if (this.props.onDateSelected) {
|
207 | this.props.onDateSelected(selectedDate)
|
208 | }
|
209 | }
|
210 | }
|
211 |
|
212 | let styles = StyleSheet.create({
|
213 | container: {
|
214 | alignItems: 'center',
|
215 | flexDirection: 'row',
|
216 | },
|
217 | wheelPicker: {
|
218 | height: 150,
|
219 | width: null,
|
220 | flex: 1,
|
221 | },
|
222 | dateWheelPicker: {
|
223 | height: 150,
|
224 | width: null,
|
225 | flex: 3,
|
226 | },
|
227 | })
|