1 | import { bindActionCreators } from 'redux';
|
2 | import { Platform } from 'react-native';
|
3 | import { connect } from 'react-redux';
|
4 | import * as UIActions from './actions/uiActions';
|
5 | import * as AppActions from './actions/appActions';
|
6 | import * as ILA from './actions/identityLoginActions';
|
7 | import AR from './array';
|
8 |
|
9 | export function RedConnect(component) {
|
10 | return connect(mapStateToProps, mapDispatchToProps)(component);
|
11 | }
|
12 | import {
|
13 | Linking
|
14 | } from 'react-native';
|
15 |
|
16 | var ReactNative = require('react-native');
|
17 | var {
|
18 | AsyncStorage
|
19 | } = ReactNative;
|
20 |
|
21 | export const BATCH = 'BATCH';
|
22 | export function batch(batch) {
|
23 | return {
|
24 | type: BATCH,
|
25 | batch
|
26 | }
|
27 | }
|
28 |
|
29 | export function capitalizeFirstLetter(string) {
|
30 | if (string)
|
31 | return string.charAt(0).toUpperCase() + string.slice(1);
|
32 | return string;
|
33 | }
|
34 | export function lowercaseFirstLetter(string) {
|
35 | if (string)
|
36 | return string.charAt(0).toLowerCase() + string.slice(1);
|
37 | return string;
|
38 | }
|
39 |
|
40 | export function GUID() {
|
41 | var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
42 | var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
43 | return v.toString(16);
|
44 | });
|
45 | return guid;
|
46 | }
|
47 |
|
48 | let actions = {};
|
49 | export function addActions(_actions) {
|
50 | actions = Object.assign(actions, _actions);
|
51 | }
|
52 | export function mapDispatchToProps(dispatch) {
|
53 | var actionBlob = Object.assign({},
|
54 | ILA,
|
55 | AppActions,
|
56 | UIActions,
|
57 | actions
|
58 | );
|
59 |
|
60 | var result = bindActionCreators(actionBlob, dispatch);
|
61 | result.dispatch = dispatch;
|
62 | return result;
|
63 | }
|
64 |
|
65 | export function mapStateToProps(state) {
|
66 | return {
|
67 | state: state
|
68 | };
|
69 | };
|
70 |
|
71 | export function redAsyncStorage(store) {
|
72 | return ((store) => next => action => {
|
73 | var result = next(action);
|
74 | if (action.store)
|
75 | debouncedStoreAsync(store, action);
|
76 | return result;
|
77 | })(store);
|
78 | }
|
79 |
|
80 |
|
81 | function storeAsync(store, action) {
|
82 | var res = action;
|
83 | if (res.store) {
|
84 | try {
|
85 | var storeTarget = res.store;
|
86 | var storpart = store.getState()[storeTarget];
|
87 | if (res.storePart) {
|
88 | storpart = storpart[res.storePart];
|
89 | storpart = Object.assign({}, { ___isStorePart: res.storePart, store: res.store, [res.storePart]: storpart });
|
90 | storeTarget = res.storePart;
|
91 | }
|
92 | if (storpart) {
|
93 | var storestring = JSON.stringify(storpart);
|
94 | return AsyncStorage.setItem(storeTarget, storestring);
|
95 | }
|
96 | }
|
97 | catch (e) {
|
98 | UIA.log(e);
|
99 | }
|
100 | }
|
101 | }
|
102 |
|
103 | var debouncedStoreAsync = debounce(storeAsync, 1000, {})
|
104 |
|
105 | var nativeMax = Math.max;
|
106 |
|
107 | function isObject(value) {
|
108 |
|
109 |
|
110 | var type = typeof value;
|
111 | return !!value && (type == 'object' || type == 'function');
|
112 | }
|
113 |
|
114 | function debounce(func, wait, options) {
|
115 | var args,
|
116 | maxTimeoutId,
|
117 | result,
|
118 | stamp,
|
119 | thisArg,
|
120 | now = Date.now,
|
121 | timeoutId,
|
122 | trailingCall,
|
123 | lastCalled = 0,
|
124 | maxWait = false,
|
125 | trailing = true;
|
126 |
|
127 | if (typeof func != 'function') {
|
128 | throw new TypeError(FUNC_ERROR_TEXT);
|
129 | }
|
130 | wait = wait < 0 ? 0 : (+wait || 0);
|
131 | if (options === true) {
|
132 | var leading = true;
|
133 | trailing = false;
|
134 | } else if (isObject(options)) {
|
135 | leading = !!options.leading;
|
136 | maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
|
137 | trailing = 'trailing' in options ? !!options.trailing : trailing;
|
138 | }
|
139 |
|
140 | function cancel() {
|
141 | if (timeoutId) {
|
142 | clearTimeout(timeoutId);
|
143 | }
|
144 | if (maxTimeoutId) {
|
145 | clearTimeout(maxTimeoutId);
|
146 | }
|
147 | lastCalled = 0;
|
148 | maxTimeoutId = timeoutId = trailingCall = undefined;
|
149 | }
|
150 |
|
151 | function complete(isCalled, id) {
|
152 | if (id) {
|
153 | clearTimeout(id);
|
154 | }
|
155 | maxTimeoutId = timeoutId = trailingCall = undefined;
|
156 | if (isCalled) {
|
157 | lastCalled = now();
|
158 | result = func.apply(thisArg, args);
|
159 | if (!timeoutId && !maxTimeoutId) {
|
160 | args = thisArg = undefined;
|
161 | }
|
162 | }
|
163 | }
|
164 |
|
165 | function delayed() {
|
166 | var remaining = wait - (now() - stamp);
|
167 | if (remaining <= 0 || remaining > wait) {
|
168 | complete(trailingCall, maxTimeoutId);
|
169 | } else {
|
170 | timeoutId = setTimeout(delayed, remaining);
|
171 | }
|
172 | }
|
173 |
|
174 | function maxDelayed() {
|
175 | complete(trailing, timeoutId);
|
176 | }
|
177 |
|
178 | function debounced() {
|
179 | args = arguments;
|
180 | stamp = now();
|
181 | thisArg = this;
|
182 | trailingCall = trailing && (timeoutId || !leading);
|
183 |
|
184 | if (maxWait === false) {
|
185 | var leadingCall = leading && !timeoutId;
|
186 | } else {
|
187 | if (!maxTimeoutId && !leading) {
|
188 | lastCalled = stamp;
|
189 | }
|
190 | var remaining = maxWait - (stamp - lastCalled),
|
191 | isCalled = remaining <= 0 || remaining > maxWait;
|
192 |
|
193 | if (isCalled) {
|
194 | if (maxTimeoutId) {
|
195 | maxTimeoutId = clearTimeout(maxTimeoutId);
|
196 | }
|
197 | lastCalled = stamp;
|
198 | result = func.apply(thisArg, args);
|
199 | }
|
200 | else if (!maxTimeoutId) {
|
201 | maxTimeoutId = setTimeout(maxDelayed, remaining);
|
202 | }
|
203 | }
|
204 | if (isCalled && timeoutId) {
|
205 | timeoutId = clearTimeout(timeoutId);
|
206 | }
|
207 | else if (!timeoutId && wait !== maxWait) {
|
208 | timeoutId = setTimeout(delayed, wait);
|
209 | }
|
210 | if (leadingCall) {
|
211 | isCalled = true;
|
212 | result = func.apply(thisArg, args);
|
213 | }
|
214 | if (isCalled && !timeoutId && !maxTimeoutId) {
|
215 | args = thisArg = undefined;
|
216 | }
|
217 | return result;
|
218 | }
|
219 | debounced.cancel = cancel;
|
220 | return debounced;
|
221 | }
|
222 |
|
223 |
|
224 | if (Number.prototype.toRadians === undefined) {
|
225 | Number.prototype.toRadians = function () { return this * Math.PI / 180; };
|
226 | }
|
227 |
|
228 |
|
229 | if (Number.prototype.toDegrees === undefined) {
|
230 | Number.prototype.toDegrees = function () { return this * 180 / Math.PI; };
|
231 | }
|
232 |
|
233 | export function convertMetersToMiles(dist) {
|
234 | var result = dist;
|
235 | result = (Math.round(100 * result * 0.000621371) / 100);
|
236 | return result;
|
237 | }
|
238 |
|
239 | export function getDistance(coords1, coords2) {
|
240 | if (!coords1 || !coords2) {
|
241 | return null;
|
242 | }
|
243 | var lat1 = coords1.latitude || coords1.lat;
|
244 | var lat2 = coords2.latitude || coords2.lat;
|
245 | var lon1 = coords1.longitude || coords1.lng;
|
246 | var lon2 = coords2.longitude || coords2.lng;
|
247 | if (lat1 !== undefined && lat2 !== undefined && lon1 !== undefined && lon2 !== undefined) {
|
248 | var R = 6371e3;
|
249 | var φ1 = lat1.toRadians();
|
250 | var φ2 = lat2.toRadians();
|
251 | var Δφ = (lat2 - lat1).toRadians();
|
252 | var Δλ = (lon2 - lon1).toRadians();
|
253 |
|
254 | var a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
|
255 | Math.cos(φ1) * Math.cos(φ2) *
|
256 | Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
|
257 | var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
258 |
|
259 | var d = R * c;
|
260 | return d;
|
261 | }
|
262 | }
|
263 |
|
264 | export function estimatedTravelTime(directions) {
|
265 | if (directions && directions.routes && directions.routes[0]) {
|
266 | var legs = directions.routes[0].legs;
|
267 | var result = 0;
|
268 | legs.map(leg => {
|
269 | if (leg && leg.steps) {
|
270 | result += leg.duration.value;
|
271 | }
|
272 | });
|
273 | return Math.round(result / 60);
|
274 | }
|
275 |
|
276 | return null;
|
277 | }
|
278 |
|
279 | export function estimatedTravelTimeHM(directions) {
|
280 | var eta = estimatedTravelTime(directions);
|
281 | if (eta !== null) {
|
282 | var hours = Math.floor(eta / 60);
|
283 | var minutes = eta - (hours * 60);
|
284 | return { hours, minutes }
|
285 | }
|
286 | return null;
|
287 | }
|
288 |
|
289 | export function email(to, cc, bcc, subject, body) {
|
290 | let url = 'mailto:';
|
291 | let argLength = arguments.length;
|
292 |
|
293 | switch (argLength) {
|
294 | case 0:
|
295 | LaunchURL(url);
|
296 | return;
|
297 | case 5:
|
298 | break;
|
299 | default:
|
300 | console.log('you must supply either 0 or 5 arguments. You supplied ' + argLength);
|
301 | return;
|
302 | }
|
303 |
|
304 |
|
305 |
|
306 | let valueAdded = false;
|
307 |
|
308 | if (isCorrectType('Array', arguments[0])) {
|
309 | let validAddresses = getValidArgumentsFromArray(arguments[0], 'String');
|
310 |
|
311 | if (validAddresses.length > 0) {
|
312 | url += encodeURIComponent(validAddresses.join(','));
|
313 | }
|
314 | }
|
315 |
|
316 | url += '?';
|
317 |
|
318 | if (isCorrectType('Array', arguments[1])) {
|
319 | let validAddresses = getValidArgumentsFromArray(arguments[1], 'String');
|
320 |
|
321 | if (validAddresses.length > 0) {
|
322 | valueAdded = true;
|
323 | url += 'cc=' + encodeURIComponent(validAddresses.join(','));
|
324 | }
|
325 | }
|
326 |
|
327 | if (isCorrectType('Array', arguments[2])) {
|
328 | if (valueAdded) {
|
329 | url += '&';
|
330 | }
|
331 |
|
332 | let validAddresses = getValidArgumentsFromArray(arguments[2], 'String');
|
333 |
|
334 | if (validAddresses.length > 0) {
|
335 | valueAdded = true;
|
336 | url += 'bcc=' + encodeURIComponent(validAddresses.join(','));
|
337 | }
|
338 | }
|
339 |
|
340 | if (isCorrectType('String', arguments[3])) {
|
341 | if (valueAdded) {
|
342 | url += '&';
|
343 | }
|
344 |
|
345 | valueAdded = true;
|
346 | url += 'subject=' + encodeURIComponent(arguments[3]);
|
347 | }
|
348 |
|
349 | if (isCorrectType('String', arguments[4])) {
|
350 | if (valueAdded) {
|
351 | url += '&';
|
352 | }
|
353 |
|
354 | url += 'body=' + encodeURIComponent(arguments[4]);
|
355 | }
|
356 |
|
357 | LaunchURL(url);
|
358 | }
|
359 |
|
360 | export function phonecall(phoneNumber, prompt) {
|
361 | if (arguments.length !== 2) {
|
362 | console.log('you must supply exactly 2 arguments');
|
363 | return;
|
364 | }
|
365 |
|
366 | if (!isCorrectType('String', phoneNumber)) {
|
367 | console.log('the phone number must be provided as a String value');
|
368 | return;
|
369 | }
|
370 |
|
371 | if (!isCorrectType('Boolean', prompt)) {
|
372 | console.log('the prompt parameter must be a Boolean');
|
373 | return;
|
374 | }
|
375 |
|
376 | let url;
|
377 |
|
378 | if (Platform.OS !== 'android') {
|
379 | url = prompt ? 'telprompt:' : 'tel:';
|
380 | }
|
381 | else {
|
382 | url = 'tel:';
|
383 | }
|
384 |
|
385 | url += phoneNumber;
|
386 |
|
387 | LaunchURL(url);
|
388 | }
|
389 |
|
390 | export function text(phoneNumber = null, body = null) {
|
391 | if (arguments.length > 2) {
|
392 | console.log('you supplied too many arguments. You can either supply 0 or 1 or 2');
|
393 | return;
|
394 | }
|
395 |
|
396 | let url = 'sms:';
|
397 |
|
398 | if (phoneNumber) {
|
399 | if (isCorrectType('String', phoneNumber)) {
|
400 | url += phoneNumber;
|
401 | } else {
|
402 | console.log('the phone number should be provided as a string. It was provided as '
|
403 | + Object.prototype.toString.call(phoneNumber).slice(8, -1)
|
404 | + ',ignoring the value provided');
|
405 | }
|
406 | }
|
407 |
|
408 | if (body) {
|
409 | if (isCorrectType('String', body)) {
|
410 |
|
411 |
|
412 | if (Platform.OS === 'android') body = encodeURIComponent(body);
|
413 | url += Platform.OS === 'ios' ? `&body=${encodeURIComponent(body)}` : `?body=${encodeURIComponent(body)}`;
|
414 | } else {
|
415 | console.log('the body should be provided as a string. It was provided as '
|
416 | + Object.prototype.toString.call(body).slice(8, -1)
|
417 | + ',ignoring the value provided');
|
418 | }
|
419 | }
|
420 |
|
421 | LaunchURL(url);
|
422 | }
|
423 |
|
424 | function getValidArgumentsFromArray(array, type) {
|
425 | var validValues = [];
|
426 | array.forEach(function (value) {
|
427 | if (isCorrectType(type, value)) {
|
428 | validValues.push(value);
|
429 | }
|
430 | });
|
431 |
|
432 | return validValues;
|
433 | };
|
434 |
|
435 | function isCorrectType(expected, actual) {
|
436 | return Object.prototype.toString.call(actual).slice(8, -1) === expected;
|
437 | };
|
438 |
|
439 | export function LaunchURL(url) {
|
440 | Linking.canOpenURL(url).then(supported => {
|
441 | if (!supported) {
|
442 | console.log('Can\'t handle url: ' + url);
|
443 | } else {
|
444 | Linking.openURL(url)
|
445 | .catch(err => {
|
446 | if (url.includes('telprompt')) {
|
447 |
|
448 |
|
449 |
|
450 | } else {
|
451 | console.warn('openURL error', err)
|
452 | }
|
453 | });
|
454 | }
|
455 | }).catch(err => console.warn('An unexpected error happened', err));
|
456 | };
|