@qikdev/sdk 1.0.10 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +1294 -1229
- package/package.json +1 -1
- package/src/api/qik.access.js +177 -201
- package/src/api/qik.api.js +55 -28
- package/src/api/qik.auth.js +181 -113
- package/src/api/qik.cache.js +29 -7
- package/src/api/qik.content.js +275 -147
- package/src/api/qik.core.js +19 -28
- package/src/api/qik.files.js +48 -38
- package/src/api/qik.filter.js +148 -207
- package/src/api/qik.geo.js +59 -42
- package/src/api/qik.socket.js +228 -62
- package/src/api/qik.storage.js +17 -8
- package/src/api/qik.system.js +6 -5
- package/src/api/qik.utils.js +244 -199
- package/src/version.js +1 -1
package/src/api/qik.filter.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
3
|
-
*
|
|
2
|
+
* @classdesc Helpers for filter configurations — the { operator, filters } objects used as the `filter` of
|
|
3
|
+
* sdk.content.list. A filter group is { operator: 'and' | 'or' | 'nor', filters: [...] }, where each entry is
|
|
4
|
+
* either a nested group or a condition { key, comparator, value, value2, values }. These helpers work out which
|
|
5
|
+
* conditions are "active" (complete enough to apply), e.g. to show a count of applied filters or to know when
|
|
6
|
+
* a filter has changed. They run locally.
|
|
7
|
+
* @alias filter
|
|
4
8
|
* @class
|
|
9
|
+
* @example
|
|
10
|
+
* const count = sdk.filter.activeFilters(filter).filter((entry) => !entry.operator).length;
|
|
5
11
|
*/
|
|
6
12
|
|
|
7
13
|
|
|
@@ -40,7 +46,20 @@ function compactFunction(val) {
|
|
|
40
46
|
|
|
41
47
|
///////////////////////
|
|
42
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @description Normalises a filter key: drops anything after a '|' and a leading '.'.
|
|
51
|
+
* @alias filter.cleanKey
|
|
52
|
+
* @param {String} key The key.
|
|
53
|
+
* @returns {String} The cleaned key ('' when the key is missing).
|
|
54
|
+
* @example
|
|
55
|
+
* sdk.filter.cleanKey('.data.colour|label'); // 'data.colour'
|
|
56
|
+
*/
|
|
43
57
|
service.cleanKey = function(key) {
|
|
58
|
+
// A missing key is empty, not the text 'undefined' or 'null'
|
|
59
|
+
if (key === undefined || key === null) {
|
|
60
|
+
return '';
|
|
61
|
+
}
|
|
62
|
+
|
|
44
63
|
key = String(key).split('|')[0];
|
|
45
64
|
|
|
46
65
|
if (key[0] == '.') {
|
|
@@ -53,16 +72,18 @@ service.cleanKey = function(key) {
|
|
|
53
72
|
///////////////////////
|
|
54
73
|
|
|
55
74
|
/**
|
|
56
|
-
* @description
|
|
75
|
+
* @description Checks whether a filter condition or group is complete enough to apply. A condition needs a key and
|
|
76
|
+
* either a value, a value2 or a non-empty values array — except comparators that need no value ('empty',
|
|
77
|
+
* 'notempty', 'datetoday', 'datenottoday', 'datebeforetoday', 'dateaftertoday', 'dateweektoday', 'datemonthtoday',
|
|
78
|
+
* 'datebeforenow', 'dateafternow', 'datethisweek', 'datethismonth'). A group is valid when at least one of its entries is.
|
|
79
|
+
* The comparator name itself isn't checked.
|
|
57
80
|
* @alias filter.isValidFilter
|
|
58
|
-
* @param
|
|
81
|
+
* @param {Object} filter A condition { key, comparator, value, value2, values } or a group { operator, filters }.
|
|
82
|
+
* @returns {Boolean} True when it can be applied (a truthy number for a condition that only has `values`).
|
|
59
83
|
* @example
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* //
|
|
63
|
-
*
|
|
64
|
-
* const validFilter = sdk.filter.isValidFilter({key:'favoriteColor', comparator:'in', values:['Red', 'Green', 'Blue']})
|
|
65
|
-
* // returns true
|
|
84
|
+
* sdk.filter.isValidFilter({ key: 'data.colour', comparator: 'in', values: [] }); // falsy: nothing to compare with
|
|
85
|
+
* sdk.filter.isValidFilter({ key: 'data.colour', comparator: 'in', values: ['Red', 'Green'] }); // truthy
|
|
86
|
+
* sdk.filter.isValidFilter({ key: 'data.notes', comparator: 'empty' }); // true
|
|
66
87
|
*/
|
|
67
88
|
service.isValidFilter = function(filter) {
|
|
68
89
|
if (!filter) {
|
|
@@ -185,51 +206,30 @@ service.isValidFilter = function(filter) {
|
|
|
185
206
|
////////////////////////////////////////////////
|
|
186
207
|
|
|
187
208
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
209
|
+
* @description Collects every valid (active) entry in a filter configuration, walking nested groups. Valid groups are
|
|
210
|
+
* included as well as valid conditions, so filter out entries with an `operator` to get just the conditions.
|
|
190
211
|
* @alias filter.activeFilters
|
|
191
|
-
* @param
|
|
212
|
+
* @param {Object} filterConfiguration A filter group { operator, filters }.
|
|
213
|
+
* @returns {Array<Object>} The valid groups and conditions, outermost first.
|
|
192
214
|
* @example
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* "key": "invalid no comparator",
|
|
207
|
-
* "value": "e"
|
|
208
|
-
* }
|
|
209
|
-
* {
|
|
210
|
-
* "key": "formData.person.lastName",
|
|
211
|
-
* "comparator": "endswith",
|
|
212
|
-
* "value": "e"
|
|
213
|
-
* }
|
|
214
|
-
* ]
|
|
215
|
-
* }
|
|
216
|
-
* ]
|
|
217
|
-
* }
|
|
215
|
+
* const filterConfiguration = {
|
|
216
|
+
* operator: 'and',
|
|
217
|
+
* filters: [
|
|
218
|
+
* {
|
|
219
|
+
* operator: 'or',
|
|
220
|
+
* filters: [
|
|
221
|
+
* { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
222
|
+
* { key: 'formData.person.lastName', comparator: 'endswith' }, // no value, so not active
|
|
223
|
+
* { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' },
|
|
224
|
+
* ],
|
|
225
|
+
* },
|
|
226
|
+
* ],
|
|
227
|
+
* };
|
|
218
228
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
* "key": "formData.person.firstName",
|
|
224
|
-
* "comparator": "startswith",
|
|
225
|
-
* "value": "c"
|
|
226
|
-
* },
|
|
227
|
-
* {
|
|
228
|
-
* "key": "formData.person.lastName",
|
|
229
|
-
* "comparator": "endswith",
|
|
230
|
-
* "value": "e"
|
|
231
|
-
* }]
|
|
232
|
-
*
|
|
229
|
+
* sdk.filter.activeFilters(filterConfiguration);
|
|
230
|
+
* // [outer group, inner group,
|
|
231
|
+
* // { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
232
|
+
* // { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' }]
|
|
233
233
|
*/
|
|
234
234
|
service.activeFilters = function(filterConfiguration) {
|
|
235
235
|
var memo = [];
|
|
@@ -263,40 +263,30 @@ service.activeFilters = function(filterConfiguration) {
|
|
|
263
263
|
|
|
264
264
|
|
|
265
265
|
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
266
|
+
* @description Lists the distinct field keys used by active conditions. Anything after a '|' in a key and a leading '.'
|
|
267
|
+
* are removed, and so are '[]' array markers unless options.trimArrayDelimeters is false.
|
|
268
268
|
* @alias filter.activeFilterKeys
|
|
269
|
-
* @param
|
|
269
|
+
* @param {Object} filterConfiguration A filter group { operator, filters }.
|
|
270
|
+
* @param {Object} [options] Options.
|
|
271
|
+
* @param {Boolean} [options.trimArrayDelimeters] Set to false to keep '[]' in keys such as 'items[].title'.
|
|
272
|
+
* @returns {Array<String>} The keys.
|
|
270
273
|
* @example
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* "key": "invalid no comparator",
|
|
285
|
-
* "value": "e"
|
|
286
|
-
* }
|
|
287
|
-
* {
|
|
288
|
-
* "key": "formData.person.lastName",
|
|
289
|
-
* "comparator": "endswith",
|
|
290
|
-
* "value": "e"
|
|
291
|
-
* }
|
|
292
|
-
* ]
|
|
293
|
-
* }
|
|
294
|
-
* ]
|
|
295
|
-
* }
|
|
274
|
+
* const filterConfiguration = {
|
|
275
|
+
* operator: 'and',
|
|
276
|
+
* filters: [
|
|
277
|
+
* {
|
|
278
|
+
* operator: 'or',
|
|
279
|
+
* filters: [
|
|
280
|
+
* { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
281
|
+
* { key: 'formData.person.lastName', comparator: 'endswith' }, // no value, so not active
|
|
282
|
+
* { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' },
|
|
283
|
+
* ],
|
|
284
|
+
* },
|
|
285
|
+
* ],
|
|
286
|
+
* };
|
|
296
287
|
*
|
|
297
|
-
*
|
|
298
|
-
* //
|
|
299
|
-
*
|
|
288
|
+
* sdk.filter.activeFilterKeys(filterConfiguration);
|
|
289
|
+
* // ['formData.person.firstName', 'formData.person.lastName']
|
|
300
290
|
*/
|
|
301
291
|
service.activeFilterKeys = function(filterConfiguration, options) {
|
|
302
292
|
options = options || {}
|
|
@@ -323,40 +313,27 @@ service.activeFilterKeys = function(filterConfiguration, options) {
|
|
|
323
313
|
|
|
324
314
|
|
|
325
315
|
/**
|
|
326
|
-
*
|
|
327
|
-
* @description Returns an array of all comparators that are being actively filtered
|
|
316
|
+
* @description Lists the distinct comparators used by active conditions.
|
|
328
317
|
* @alias filter.activeFilterComparators
|
|
329
|
-
* @param
|
|
318
|
+
* @param {Object} filterConfiguration A filter group { operator, filters }.
|
|
319
|
+
* @returns {Array<String>} The comparator names.
|
|
330
320
|
* @example
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
* "key": "invalid no comparator",
|
|
345
|
-
* "value": "e"
|
|
346
|
-
* }
|
|
347
|
-
* {
|
|
348
|
-
* "key": "formData.person.lastName",
|
|
349
|
-
* "comparator": "endswith",
|
|
350
|
-
* "value": "e"
|
|
351
|
-
* }
|
|
352
|
-
* ]
|
|
353
|
-
* }
|
|
354
|
-
* ]
|
|
355
|
-
* }
|
|
321
|
+
* const filterConfiguration = {
|
|
322
|
+
* operator: 'and',
|
|
323
|
+
* filters: [
|
|
324
|
+
* {
|
|
325
|
+
* operator: 'or',
|
|
326
|
+
* filters: [
|
|
327
|
+
* { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
328
|
+
* { key: 'formData.person.lastName', comparator: 'endswith' }, // no value, so not active
|
|
329
|
+
* { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' },
|
|
330
|
+
* ],
|
|
331
|
+
* },
|
|
332
|
+
* ],
|
|
333
|
+
* };
|
|
356
334
|
*
|
|
357
|
-
*
|
|
358
|
-
* //
|
|
359
|
-
*
|
|
335
|
+
* sdk.filter.activeFilterComparators(filterConfiguration);
|
|
336
|
+
* // ['startswith', 'endswith']
|
|
360
337
|
*/
|
|
361
338
|
service.activeFilterComparators = function(filterConfiguration) {
|
|
362
339
|
var comparators = service.activeFilters(filterConfiguration)
|
|
@@ -373,40 +350,27 @@ service.activeFilterComparators = function(filterConfiguration) {
|
|
|
373
350
|
}
|
|
374
351
|
|
|
375
352
|
/**
|
|
376
|
-
*
|
|
377
|
-
* @description Returns an array of all comparators that are being actively filtered
|
|
353
|
+
* @description Lists the distinct operators ('and', 'or', 'nor') of the groups that contain at least one active condition.
|
|
378
354
|
* @alias filter.activeFilterOperators
|
|
379
|
-
* @param
|
|
355
|
+
* @param {Object} filterConfiguration A filter group { operator, filters }.
|
|
356
|
+
* @returns {Array<String>} The operators.
|
|
380
357
|
* @example
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
* "key": "invalid no comparator",
|
|
395
|
-
* "value": "e"
|
|
396
|
-
* }
|
|
397
|
-
* {
|
|
398
|
-
* "key": "formData.person.lastName",
|
|
399
|
-
* "comparator": "endswith",
|
|
400
|
-
* "value": "e"
|
|
401
|
-
* }
|
|
402
|
-
* ]
|
|
403
|
-
* }
|
|
404
|
-
* ]
|
|
405
|
-
* }
|
|
358
|
+
* const filterConfiguration = {
|
|
359
|
+
* operator: 'and',
|
|
360
|
+
* filters: [
|
|
361
|
+
* {
|
|
362
|
+
* operator: 'or',
|
|
363
|
+
* filters: [
|
|
364
|
+
* { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
365
|
+
* { key: 'formData.person.lastName', comparator: 'endswith' }, // no value, so not active
|
|
366
|
+
* { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' },
|
|
367
|
+
* ],
|
|
368
|
+
* },
|
|
369
|
+
* ],
|
|
370
|
+
* };
|
|
406
371
|
*
|
|
407
|
-
*
|
|
408
|
-
* //
|
|
409
|
-
*
|
|
372
|
+
* sdk.filter.activeFilterOperators(filterConfiguration);
|
|
373
|
+
* // ['and', 'or']
|
|
410
374
|
*/
|
|
411
375
|
service.activeFilterOperators = function(filterConfiguration) {
|
|
412
376
|
var operators = service.activeFilters(filterConfiguration)
|
|
@@ -423,40 +387,29 @@ service.activeFilterOperators = function(filterConfiguration) {
|
|
|
423
387
|
|
|
424
388
|
|
|
425
389
|
/**
|
|
426
|
-
*
|
|
427
|
-
*
|
|
390
|
+
* @description Lists the values used by active conditions (value, value2 and every entry of values). Object values are
|
|
391
|
+
* reduced to their _id, id, title or name. Empty values are dropped; duplicates are kept.
|
|
428
392
|
* @alias filter.activeFilterValues
|
|
429
|
-
* @param
|
|
393
|
+
* @param {Object} filterConfiguration A filter group { operator, filters }.
|
|
394
|
+
* @param {Object} [options] Not used; accepted for compatibility.
|
|
395
|
+
* @returns {Array<*>} The values.
|
|
430
396
|
* @example
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
* "key": "invalid no comparator",
|
|
445
|
-
* "value": "e"
|
|
446
|
-
* }
|
|
447
|
-
* {
|
|
448
|
-
* "key": "formData.person.lastName",
|
|
449
|
-
* "comparator": "endswith",
|
|
450
|
-
* "value": "a"
|
|
451
|
-
* }
|
|
452
|
-
* ]
|
|
453
|
-
* }
|
|
454
|
-
* ]
|
|
455
|
-
* }
|
|
397
|
+
* const filterConfiguration = {
|
|
398
|
+
* operator: 'and',
|
|
399
|
+
* filters: [
|
|
400
|
+
* {
|
|
401
|
+
* operator: 'or',
|
|
402
|
+
* filters: [
|
|
403
|
+
* { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
404
|
+
* { key: 'formData.person.lastName', comparator: 'endswith' }, // no value, so not active
|
|
405
|
+
* { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' },
|
|
406
|
+
* ],
|
|
407
|
+
* },
|
|
408
|
+
* ],
|
|
409
|
+
* };
|
|
456
410
|
*
|
|
457
|
-
*
|
|
458
|
-
* //
|
|
459
|
-
*
|
|
411
|
+
* sdk.filter.activeFilterValues(filterConfiguration);
|
|
412
|
+
* // ['c', 'e']
|
|
460
413
|
*/
|
|
461
414
|
service.activeFilterValues = function(filterConfiguration, options) {
|
|
462
415
|
|
|
@@ -490,40 +443,28 @@ service.activeFilterValues = function(filterConfiguration, options) {
|
|
|
490
443
|
|
|
491
444
|
|
|
492
445
|
/**
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
* Often used to check if a user has changed the filter in any way, the string only takes into consideration active valid filters
|
|
446
|
+
* @description Turns the active parts of a filter configuration into a string, so you can tell whether the filter
|
|
447
|
+
* that would actually be applied has changed (incomplete conditions don't affect it).
|
|
496
448
|
* @alias filter.filterChangeString
|
|
497
|
-
* @param
|
|
449
|
+
* @param {Object} config A filter group { operator, filters }.
|
|
450
|
+
* @returns {String} A JSON string of the active entries.
|
|
498
451
|
* @example
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
* "key": "invalid no comparator",
|
|
513
|
-
* "value": "e"
|
|
514
|
-
* }
|
|
515
|
-
* {
|
|
516
|
-
* "key": "formData.person.lastName",
|
|
517
|
-
* "comparator": "endswith",
|
|
518
|
-
* "value": "a"
|
|
519
|
-
* }
|
|
520
|
-
* ]
|
|
521
|
-
* }
|
|
522
|
-
* ]
|
|
523
|
-
* }
|
|
452
|
+
* const filterConfiguration = {
|
|
453
|
+
* operator: 'and',
|
|
454
|
+
* filters: [
|
|
455
|
+
* {
|
|
456
|
+
* operator: 'or',
|
|
457
|
+
* filters: [
|
|
458
|
+
* { key: 'formData.person.firstName', comparator: 'startswith', value: 'c' },
|
|
459
|
+
* { key: 'formData.person.lastName', comparator: 'endswith' }, // no value, so not active
|
|
460
|
+
* { key: 'formData.person.lastName', comparator: 'endswith', value: 'e' },
|
|
461
|
+
* ],
|
|
462
|
+
* },
|
|
463
|
+
* ],
|
|
464
|
+
* };
|
|
524
465
|
*
|
|
525
|
-
* //
|
|
526
|
-
* const changeString = sdk.filter.filterChangeString(filterConfiguration);
|
|
466
|
+
* // Re-run the list only when the effective filter changes
|
|
467
|
+
* const changeString = sdk.filter.filterChangeString(filterConfiguration);
|
|
527
468
|
*/
|
|
528
469
|
service.filterChangeString = function(config) {
|
|
529
470
|
|
package/src/api/qik.geo.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
///////////////////////////////////////////////////
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Location helpers: the device's position (browser geolocation, which asks the user's permission), the
|
|
5
|
+
* distance between two points, and the organisation's default timezone and country, plus lists of
|
|
6
|
+
* countries and timezones.
|
|
6
7
|
* @alias geo
|
|
7
8
|
* @constructor
|
|
8
9
|
* @hideconstructor
|
|
@@ -31,18 +32,18 @@ export default function(qik) {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
*
|
|
35
|
-
* Get the distance between two geo location points
|
|
35
|
+
* Calculates the straight-line (great-circle) distance between two points, in metres.
|
|
36
36
|
* @alias geo.distance
|
|
37
|
-
* @param
|
|
38
|
-
* @param
|
|
39
|
-
* @param
|
|
40
|
-
* @param
|
|
41
|
-
* @param
|
|
42
|
-
* @param
|
|
37
|
+
* @param {Object} positionOne The first point.
|
|
38
|
+
* @param {Number} positionOne.lat Latitude in degrees.
|
|
39
|
+
* @param {Number} positionOne.lon Longitude in degrees.
|
|
40
|
+
* @param {Object} positionTwo The second point.
|
|
41
|
+
* @param {Number} positionTwo.lat Latitude in degrees.
|
|
42
|
+
* @param {Number} positionTwo.lon Longitude in degrees.
|
|
43
|
+
* @returns {Number} The distance in metres.
|
|
43
44
|
* @example
|
|
44
|
-
* const
|
|
45
|
-
* //
|
|
45
|
+
* const metres = sdk.geo.distance({ lat: -37.8136, lon: 144.9631 }, { lat: -33.8688, lon: 151.2093 });
|
|
46
|
+
* // about 713000
|
|
46
47
|
*/
|
|
47
48
|
service.distance = function({ lat: lat1, lon: lon1 }, { lat: lat2, lon: lon2 }) {
|
|
48
49
|
function deg2rad(deg) {
|
|
@@ -62,13 +63,12 @@ export default function(qik) {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
/**
|
|
65
|
-
*
|
|
66
|
-
* Start watching the user's geolocation
|
|
66
|
+
* Asks the browser for the device's current position once (the user may be prompted for permission).
|
|
67
67
|
* @alias geo.getPosition
|
|
68
|
-
* @
|
|
68
|
+
* @returns {Promise<Object>} A GeolocationPosition: { coords: { latitude, longitude, accuracy, altitude, ... }, timestamp }. Rejects with { message: 'Geolocation is not enabled' } outside a browser or without geolocation, or with the browser's error if the user refuses.
|
|
69
69
|
* @example
|
|
70
|
-
* const
|
|
71
|
-
*
|
|
70
|
+
* const { coords } = await sdk.geo.getPosition();
|
|
71
|
+
* console.log(coords.latitude, coords.longitude);
|
|
72
72
|
*/
|
|
73
73
|
service.getPosition = async function() {
|
|
74
74
|
|
|
@@ -83,13 +83,14 @@ export default function(qik) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
*
|
|
87
|
-
* Start watching the user's geolocation
|
|
86
|
+
* Starts watching the device's position; the callback runs every time it changes.
|
|
88
87
|
* @alias geo.watchPosition
|
|
89
|
-
* @param
|
|
88
|
+
* @param {Function} positionDataReceived Called with a GeolocationPosition ({ coords, timestamp }) on every update.
|
|
89
|
+
* @returns {Promise<Object>} { id }: the watch id, needed to stop watching. Rejects with { message: 'Geolocation is not enabled' } when geolocation isn't available.
|
|
90
90
|
* @example
|
|
91
|
-
* const
|
|
92
|
-
*
|
|
91
|
+
* const { id } = await sdk.geo.watchPosition((position) => {
|
|
92
|
+
* console.log(position.coords.latitude, position.coords.longitude);
|
|
93
|
+
* });
|
|
93
94
|
*/
|
|
94
95
|
service.watchPosition = async function(positionDataReceived) {
|
|
95
96
|
|
|
@@ -107,13 +108,14 @@ export default function(qik) {
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
/**
|
|
110
|
-
*
|
|
111
|
-
* Start watching the user's geolocation
|
|
111
|
+
* Stops a watch started with watchPosition.
|
|
112
112
|
* @alias geo.stopWatchPosition
|
|
113
|
-
* @param
|
|
113
|
+
* @param {Number} watchID The id returned by watchPosition (its `id`).
|
|
114
|
+
* @returns {Promise<Boolean>} true. Rejects with { message: 'Geolocation is not enabled' } when geolocation isn't available.
|
|
114
115
|
* @example
|
|
115
|
-
* const
|
|
116
|
-
* //
|
|
116
|
+
* const { id } = await sdk.geo.watchPosition(onPosition);
|
|
117
|
+
* // later
|
|
118
|
+
* await sdk.geo.stopWatchPosition(id);
|
|
117
119
|
*/
|
|
118
120
|
service.stopWatchPosition = async function(watchID) {
|
|
119
121
|
if (!isEnabled()) {
|
|
@@ -121,7 +123,7 @@ export default function(qik) {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
console.log('qik:geo: watch stopped');
|
|
124
|
-
navigator.geolocation.clearWatch(
|
|
126
|
+
navigator.geolocation.clearWatch(watchID);
|
|
125
127
|
return true;
|
|
126
128
|
}
|
|
127
129
|
|
|
@@ -129,18 +131,17 @@ export default function(qik) {
|
|
|
129
131
|
///////////////////////////////////////////////////
|
|
130
132
|
|
|
131
133
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* will attempt to retrieve an accurate timezone either from the user's organisation or available services within the browser
|
|
134
|
+
* Returns the timezone to use by default: the signed-in user's organisation timezone, otherwise the
|
|
135
|
+
* browser's (also used when signed out).
|
|
135
136
|
* @alias geo.getDefaultTimezone
|
|
137
|
+
* @returns {String|undefined} An IANA timezone name such as 'Australia/Melbourne', or undefined outside a browser with no organisation timezone.
|
|
136
138
|
* @example
|
|
137
|
-
* const
|
|
138
|
-
* // Would return something similar to:
|
|
139
|
-
* // Australia/Melbourne
|
|
139
|
+
* const timezone = sdk.geo.getDefaultTimezone(); // 'Australia/Melbourne'
|
|
140
140
|
*/
|
|
141
141
|
service.getDefaultTimezone = function() {
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
// getCurrentUser() is null when signed out
|
|
144
|
+
const currentUser = qik.auth.getCurrentUser()?.session;
|
|
144
145
|
|
|
145
146
|
if(currentUser) {
|
|
146
147
|
const defaultUserTimezone = currentUser?.organisation?.timezone;
|
|
@@ -161,6 +162,12 @@ export default function(qik) {
|
|
|
161
162
|
|
|
162
163
|
///////////////////////////////////////////////////
|
|
163
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Country names keyed by two-letter ISO code, e.g. countryLookup.AU === 'Australia'.
|
|
167
|
+
* @alias geo.countryLookup
|
|
168
|
+
* @example
|
|
169
|
+
* const name = sdk.geo.countryLookup['NZ']; // 'New Zealand'
|
|
170
|
+
*/
|
|
164
171
|
service.countryLookup = {
|
|
165
172
|
"AC": "Ascension Island",
|
|
166
173
|
"AD": "Andorra",
|
|
@@ -424,8 +431,20 @@ export default function(qik) {
|
|
|
424
431
|
"ZW": "Zimbabwe"
|
|
425
432
|
}
|
|
426
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Every country name from countryLookup, as an array.
|
|
436
|
+
* @alias geo.countryNames
|
|
437
|
+
* @example
|
|
438
|
+
* const names = sdk.geo.countryNames; // ['Ascension Island', 'Andorra', ...]
|
|
439
|
+
*/
|
|
427
440
|
service.countryNames = Object.values(service.countryLookup);
|
|
428
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Every IANA timezone name, e.g. for a timezone picker.
|
|
444
|
+
* @alias geo.timezones
|
|
445
|
+
* @example
|
|
446
|
+
* const options = sdk.geo.timezones.map((zone) => ({ title: zone, value: zone }));
|
|
447
|
+
*/
|
|
429
448
|
service.timezones = [
|
|
430
449
|
"Africa/Abidjan",
|
|
431
450
|
"Africa/Accra",
|
|
@@ -864,17 +883,15 @@ export default function(qik) {
|
|
|
864
883
|
]
|
|
865
884
|
|
|
866
885
|
/**
|
|
867
|
-
*
|
|
868
|
-
* Retrieves the default country for the current user/application
|
|
869
|
-
* will attempt to retrieve the country from the user or application's organisation or from services available within the browser
|
|
886
|
+
* Returns the signed-in user's organisation country.
|
|
870
887
|
* @alias geo.getDefaultCountry
|
|
888
|
+
* @returns {Object|undefined} { code, name }, e.g. { code: 'AU', name: 'Australia' }, or undefined when signed out or the organisation has no country set.
|
|
871
889
|
* @example
|
|
872
|
-
* const
|
|
873
|
-
* // Would return something similar to:
|
|
874
|
-
* // { code:'AU', name:'Australia' }
|
|
890
|
+
* const country = sdk.geo.getDefaultCountry(); // { code: 'AU', name: 'Australia' }
|
|
875
891
|
*/
|
|
876
892
|
service.getDefaultCountry = function() {
|
|
877
|
-
|
|
893
|
+
// getCurrentUser() is null when signed out
|
|
894
|
+
const currentUser = qik.auth.getCurrentUser()?.session;
|
|
878
895
|
|
|
879
896
|
if(currentUser) {
|
|
880
897
|
const code = currentUser?.organisation?.countryCode;
|