incyclist-services 1.0.57 → 1.0.58
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/lib/devices/pairing/service.js +7 -1
- package/lib/devices/ride/service.d.ts +4 -0
- package/lib/devices/ride/service.js +65 -4
- package/lib/routes/base/types/index.d.ts +1 -1
- package/lib/routes/list/FreeRideCard.d.ts +8 -0
- package/lib/routes/list/FreeRideCard.js +11 -0
- package/lib/routes/list/service.d.ts +14 -5
- package/lib/routes/list/service.js +191 -96
- package/lib/routes/list/types.d.ts +27 -7
- package/lib/utils/geo.js +4 -2
- package/package.json +1 -1
|
@@ -733,7 +733,7 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
733
733
|
run(props = {}) {
|
|
734
734
|
return __awaiter(this, void 0, void 0, function* () {
|
|
735
735
|
this.emit('run');
|
|
736
|
-
if (this.isPairing() || this.isScanning()
|
|
736
|
+
if ((this.isPairing() || this.isScanning()) && !this.state.waiting) {
|
|
737
737
|
yield this._stop();
|
|
738
738
|
}
|
|
739
739
|
if (this.state.stopRequested || this.state.stopped) {
|
|
@@ -848,6 +848,10 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
848
848
|
this.state.tsPrevStart = Date.now();
|
|
849
849
|
if (this.isScanning() && this.state.scan.preparing !== preparing)
|
|
850
850
|
return;
|
|
851
|
+
this.logEvent({ message: 'Stopping Adapters', interfaces: interfaces.join(','), props });
|
|
852
|
+
const stopPromises = [];
|
|
853
|
+
interfaces.forEach(i => stopPromises.push(this.stopAdaptersOnInterface(i)));
|
|
854
|
+
yield Promise.allSettled(stopPromises);
|
|
851
855
|
this.logEvent({ message: 'Start Scanning', interfaces: interfaces.join(','), props });
|
|
852
856
|
this.initScanningCallbacks();
|
|
853
857
|
const timeout = props.enforcedScan ? 1000 * 60 * 60 : undefined;
|
|
@@ -1017,6 +1021,8 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
1017
1021
|
stopAdaptersWithCapability(capability, udid) {
|
|
1018
1022
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1019
1023
|
const c = this.getCapability(capability);
|
|
1024
|
+
if (!c)
|
|
1025
|
+
return;
|
|
1020
1026
|
const { adapters = [], capabilities } = this.state;
|
|
1021
1027
|
const maxRetries = 3;
|
|
1022
1028
|
let target = udid ?
|
|
@@ -32,6 +32,10 @@ export declare class DeviceRideService extends EventEmitter {
|
|
|
32
32
|
startCheck(filter: RideServiceCheckFilter): Promise<void>;
|
|
33
33
|
getAdapters(filter: RideServiceCheckFilter): AdapterRideInfo[];
|
|
34
34
|
setSerialPortInUse(adapter: IncyclistDeviceAdapter): void;
|
|
35
|
+
protected checkAntSameDeviceID(adapters: AdapterRideInfo[]): Array<{
|
|
36
|
+
udid: string;
|
|
37
|
+
info: AdapterInfo;
|
|
38
|
+
}>;
|
|
35
39
|
startAdapters(adapters: AdapterRideInfo[], startType: 'start' | 'check' | 'pair', props?: RideServiceDeviceProperties): Promise<boolean>;
|
|
36
40
|
start(props: RideServiceDeviceProperties): Promise<boolean>;
|
|
37
41
|
startRetry(props: RideServiceDeviceProperties): Promise<boolean>;
|
|
@@ -336,11 +336,39 @@ class DeviceRideService extends events_1.default {
|
|
|
336
336
|
serial.setInUse(device.getPort());
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
+
checkAntSameDeviceID(adapters) {
|
|
340
|
+
const antDevices = adapters.map((ai, idx) => (Object.assign(Object.assign({}, ai), { idx })))
|
|
341
|
+
.filter(ai => ai.adapter.getInterface() === 'ant')
|
|
342
|
+
.map(ai => ({ idx: ai.idx, deviceID: ai.adapter.getID(), capabilities: ai.capabilities, udid: ai.udid }));
|
|
343
|
+
const antDeviceIds = antDevices.map(di => di.deviceID);
|
|
344
|
+
const duplicateIds = antDeviceIds.filter((item, index) => antDeviceIds.indexOf(item) !== index);
|
|
345
|
+
const score = (capabilities) => {
|
|
346
|
+
let value = 0;
|
|
347
|
+
if (capabilities.includes(incyclist_devices_1.IncyclistCapability.Control))
|
|
348
|
+
value += 100;
|
|
349
|
+
if (capabilities.includes(incyclist_devices_1.IncyclistCapability.Power))
|
|
350
|
+
value += 50;
|
|
351
|
+
value += capabilities.length;
|
|
352
|
+
return value;
|
|
353
|
+
};
|
|
354
|
+
const duplicateDevices = antDevices.filter(di => duplicateIds.includes(di.deviceID)).sort((a, b) => score(b.capabilities) - score(a.capabilities));
|
|
355
|
+
const leading = duplicateDevices[0];
|
|
356
|
+
const duplicateAdapters = [];
|
|
357
|
+
duplicateDevices.forEach((di, i) => {
|
|
358
|
+
if (i == 0)
|
|
359
|
+
return;
|
|
360
|
+
duplicateAdapters.push({ udid: leading.udid, info: adapters[di.idx] });
|
|
361
|
+
});
|
|
362
|
+
return duplicateAdapters;
|
|
363
|
+
}
|
|
339
364
|
startAdapters(adapters, startType, props) {
|
|
340
365
|
return __awaiter(this, void 0, void 0, function* () {
|
|
341
366
|
const { forceErgMode, startPos, realityFactor, rideMode, route } = props || {};
|
|
367
|
+
const duplicates = this.checkAntSameDeviceID(adapters);
|
|
342
368
|
this.startPromises = adapters === null || adapters === void 0 ? void 0 : adapters.map((ai) => __awaiter(this, void 0, void 0, function* () {
|
|
343
369
|
var _a;
|
|
370
|
+
if (duplicates.find(dai => dai.info.udid === ai.udid))
|
|
371
|
+
return;
|
|
344
372
|
const startProps = (0, clone_1.default)(props || {});
|
|
345
373
|
if (startType === 'check' || startType === 'pair') {
|
|
346
374
|
startProps.timeout = 10000;
|
|
@@ -389,6 +417,9 @@ class DeviceRideService extends events_1.default {
|
|
|
389
417
|
.then((success) => __awaiter(this, void 0, void 0, function* () {
|
|
390
418
|
if (success) {
|
|
391
419
|
this.emit(`${startType}-success`, this.getAdapterStateInfo(ai));
|
|
420
|
+
if (duplicates.find(dai => dai.udid === ai.udid)) {
|
|
421
|
+
duplicates.forEach(dai => { this.emit(`${startType}-success`, this.getAdapterStateInfo(dai.info)); });
|
|
422
|
+
}
|
|
392
423
|
this.logEvent(Object.assign({ message: `${startType} ${sType} request finished` }, logProps));
|
|
393
424
|
if (startType === 'check')
|
|
394
425
|
yield ai.adapter.pause().catch(console.log);
|
|
@@ -400,6 +431,9 @@ class DeviceRideService extends events_1.default {
|
|
|
400
431
|
}
|
|
401
432
|
else {
|
|
402
433
|
this.emit(`${startType}-error`, this.getAdapterStateInfo(ai));
|
|
434
|
+
if (duplicates.find(dai => dai.udid === ai.udid)) {
|
|
435
|
+
duplicates.forEach(dai => { this.emit(`${startType}-error`, this.getAdapterStateInfo(dai.info)); });
|
|
436
|
+
}
|
|
403
437
|
this.logEvent(Object.assign({ message: `${startType} ${sType} request failed` }, logProps));
|
|
404
438
|
if (startType === 'check' || startType === 'pair')
|
|
405
439
|
yield ai.adapter.stop().catch(console.log);
|
|
@@ -411,6 +445,9 @@ class DeviceRideService extends events_1.default {
|
|
|
411
445
|
ai.isStarted = false;
|
|
412
446
|
this.logEvent(Object.assign(Object.assign({ message: `${startType} ${sType} request failed` }, logProps), { reason: err.message }));
|
|
413
447
|
this.emit(`${startType}-error`, this.getAdapterStateInfo(ai), err);
|
|
448
|
+
if (duplicates.find(dai => dai.udid === ai.udid)) {
|
|
449
|
+
duplicates.forEach(dai => { this.emit(`${startType}-error`, this.getAdapterStateInfo(dai.info)); });
|
|
450
|
+
}
|
|
414
451
|
if (startType === 'check' || startType === 'pair') {
|
|
415
452
|
yield ai.adapter.stop().catch(console.log);
|
|
416
453
|
}
|
|
@@ -529,10 +566,29 @@ class DeviceRideService extends events_1.default {
|
|
|
529
566
|
this.verifySelected(selectedDevices, incyclist_devices_1.IncyclistCapability.Speed);
|
|
530
567
|
this.verifySelected(selectedDevices, incyclist_devices_1.IncyclistCapability.Cadence);
|
|
531
568
|
this.verifySelected(selectedDevices, incyclist_devices_1.IncyclistCapability.Power);
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
569
|
+
const duplicates = this.checkAntSameDeviceID(adapters);
|
|
570
|
+
const toBeReplaced = duplicates.filter(dai => dai.udid === adapterInfo.udid).map(dai => dai.info.udid);
|
|
571
|
+
let enabledCapabilities = [];
|
|
572
|
+
if (this.simulatorEnforced) {
|
|
573
|
+
enabledCapabilities = [incyclist_devices_1.IncyclistCapability.Control, incyclist_devices_1.IncyclistCapability.Power, incyclist_devices_1.IncyclistCapability.Speed, incyclist_devices_1.IncyclistCapability.HeartRate, incyclist_devices_1.IncyclistCapability.Cadence];
|
|
574
|
+
}
|
|
575
|
+
else if (duplicates.length > 0 && duplicates.find(d => d.udid === adapterInfo.udid)) {
|
|
576
|
+
const selected = (0, clone_1.default)(selectedDevices);
|
|
577
|
+
selected.forEach(cd => {
|
|
578
|
+
if (toBeReplaced.includes(cd.selected))
|
|
579
|
+
cd.selected = adapterInfo.udid;
|
|
580
|
+
});
|
|
581
|
+
selected.forEach;
|
|
582
|
+
selected.forEach(sd => {
|
|
583
|
+
const duplicate = duplicates.find(dai => dai.info.udid === sd.selected);
|
|
584
|
+
if (duplicate)
|
|
585
|
+
sd.selected = duplicate.udid;
|
|
586
|
+
});
|
|
587
|
+
enabledCapabilities = selected.map(c => c.capability);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
enabledCapabilities = selectedDevices.filter(sd => sd.selected === adapterInfo.udid).map(c => c.capability);
|
|
591
|
+
}
|
|
536
592
|
this.logEvent({ message: 'Data Update', device: adapterInfo.adapter.getName(), data, enabledCapabilities });
|
|
537
593
|
enabledCapabilities.forEach(capability => {
|
|
538
594
|
switch (capability) {
|
|
@@ -559,6 +615,11 @@ class DeviceRideService extends events_1.default {
|
|
|
559
615
|
}
|
|
560
616
|
});
|
|
561
617
|
this.emit('data', this.data, adapterInfo.udid);
|
|
618
|
+
if (toBeReplaced) {
|
|
619
|
+
toBeReplaced.forEach(udid => {
|
|
620
|
+
this.emit('data', this.data, udid);
|
|
621
|
+
});
|
|
622
|
+
}
|
|
562
623
|
}
|
|
563
624
|
sendUpdate(request) {
|
|
564
625
|
const adapters = this.getAdapterList();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FreeRideCard = void 0;
|
|
4
|
+
class FreeRideCard {
|
|
5
|
+
constructor(state, title) {
|
|
6
|
+
this.type = 'free-ride';
|
|
7
|
+
this.state = state;
|
|
8
|
+
this.title = title || 'Free Ride';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.FreeRideCard = FreeRideCard;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Page, InternalRouteListState, List, RouteInfo, Route, RouteListEntry, RouteListStartProps, RouteListData, RouteStartSettings, onRouteStatusUpdateCallback, onCarouselStateChangedCallback } from "./types";
|
|
1
|
+
import { Page, InternalRouteListState, List, RouteInfo, Route, RouteListEntry, RouteListStartProps, RouteListData, RouteStartSettings, onRouteStatusUpdateCallback, onCarouselStateChangedCallback, RoutesDB } from "./types";
|
|
2
2
|
import IncyclistRoutesApi from "../base/api";
|
|
3
3
|
import { RouteApiDescription, RouteApiDetail } from "../base/api/types";
|
|
4
4
|
import { IncyclistService } from "../../base/service";
|
|
@@ -9,17 +9,16 @@ export declare class RouteListService extends IncyclistService {
|
|
|
9
9
|
static getInstance(binding?: IJsonRepositoryBinding): RouteListService;
|
|
10
10
|
protected baseDir: string;
|
|
11
11
|
protected state: InternalRouteListState;
|
|
12
|
-
protected
|
|
12
|
+
protected lists: Array<RouteListEntry>;
|
|
13
13
|
protected videosRepo: JsonRepository;
|
|
14
14
|
protected routesRepo: JsonRepository;
|
|
15
15
|
protected api: IncyclistRoutesApi;
|
|
16
|
+
protected routeDescriptions: RoutesDB;
|
|
16
17
|
constructor(binding?: IJsonRepositoryBinding);
|
|
17
18
|
setBinding(binding: IJsonRepositoryBinding): void;
|
|
18
19
|
protected getVideosRepo(): JsonRepository;
|
|
19
20
|
protected getRoutesRepo(): JsonRepository;
|
|
20
21
|
preload(carouselSize?: number): Promise<void>;
|
|
21
|
-
protected _preload(carouselSize?: number, detailsOnly?: boolean): Promise<void>;
|
|
22
|
-
protected preloadList(list: List, carouselSize?: number, detailsOnly?: boolean): Promise<void>;
|
|
23
22
|
load(props: {
|
|
24
23
|
list?: List;
|
|
25
24
|
loadFrom?: number;
|
|
@@ -28,6 +27,7 @@ export declare class RouteListService extends IncyclistService {
|
|
|
28
27
|
}): Promise<void>;
|
|
29
28
|
openRouteSelection(pageId: string, props: RouteListStartProps): RouteListData;
|
|
30
29
|
closeRouteSelection(pageId: string): void;
|
|
30
|
+
onResize(pageId: string): void;
|
|
31
31
|
openStartSettings(r: RouteInfo | string): RouteStartSettings;
|
|
32
32
|
cancelStartSettings(r: RouteInfo | string): {};
|
|
33
33
|
setCardUpdateHandler(pageId: string, r: RouteInfo | string, list: List, idx: number, onRouteStateChanged: onRouteStatusUpdateCallback, onCarouselStateChanged: onCarouselStateChangedCallback): void;
|
|
@@ -40,6 +40,8 @@ export declare class RouteListService extends IncyclistService {
|
|
|
40
40
|
stopRide(r?: RouteInfo | string): {};
|
|
41
41
|
startDownload(routeId: any, onStatusUpdate: any): void;
|
|
42
42
|
cancelDownload(routeId: any): void;
|
|
43
|
+
protected _preload(carouselSize?: number, detailsOnly?: boolean): Promise<void>;
|
|
44
|
+
protected preloadList(list: List, carouselSize?: number): Promise<void>;
|
|
43
45
|
protected loadStartSettingsFromUserSettings(route: Route): {
|
|
44
46
|
startPos: number;
|
|
45
47
|
realityFactor: number;
|
|
@@ -71,7 +73,9 @@ export declare class RouteListService extends IncyclistService {
|
|
|
71
73
|
title: string;
|
|
72
74
|
}>;
|
|
73
75
|
protected getRoute(criteria: string | filterFn): Route;
|
|
76
|
+
protected getAllRoutes(): Array<Route>;
|
|
74
77
|
protected stopAllRides(): void;
|
|
78
|
+
protected addDescriptionsFromDB(descriptions: RoutesDB): void;
|
|
75
79
|
protected addDescriptionsFromRepo(descriptions: Array<RouteApiDescription>, repo?: JsonRepository): void;
|
|
76
80
|
protected addDescriptionsFromServer(descriptions: Array<RouteApiDescription>): void;
|
|
77
81
|
protected updateRouteTitle(data: RouteInfo, route: {
|
|
@@ -83,12 +87,17 @@ export declare class RouteListService extends IncyclistService {
|
|
|
83
87
|
protected getCountryPrefix(title?: string): string | undefined;
|
|
84
88
|
protected removeCountryPrefix(title?: string): string;
|
|
85
89
|
protected loadRouteDescriptionsFromRepo(): Promise<void>;
|
|
90
|
+
protected saveRouteDescriptions(): Promise<void>;
|
|
86
91
|
protected loadRouteDescriptionsFromServer(): Promise<void>;
|
|
87
92
|
protected loadRouteDescriptions(): Promise<void>;
|
|
88
|
-
protected loadRouteDetais(route: Route): Promise<
|
|
93
|
+
protected loadRouteDetais(route: Route): Promise<RouteInfo>;
|
|
94
|
+
saveRouteDetails(route: any): Promise<void>;
|
|
89
95
|
protected emitRouteUpdated(route: Route): void;
|
|
90
96
|
protected getListState(page: Page, list: List): import("./types").RouteListDateEntry;
|
|
91
97
|
private getRouteFromStartProps;
|
|
98
|
+
private isDescriptionsLoaded;
|
|
99
|
+
private decodePoints;
|
|
100
|
+
private encodePoints;
|
|
92
101
|
}
|
|
93
102
|
export declare const useRouteList: () => RouteListService;
|
|
94
103
|
export {};
|
|
@@ -20,6 +20,7 @@ const route_1 = require("../base/utils/route");
|
|
|
20
20
|
const settings_1 = require("../../settings");
|
|
21
21
|
const api_2 = require("../../api");
|
|
22
22
|
const clone_1 = __importDefault(require("../../utils/clone"));
|
|
23
|
+
const FreeRideCard_1 = require("./FreeRideCard");
|
|
23
24
|
class RouteListService extends service_1.IncyclistService {
|
|
24
25
|
static getInstance(binding) {
|
|
25
26
|
if (!RouteListService._instance)
|
|
@@ -30,12 +31,14 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
30
31
|
super('RouteList');
|
|
31
32
|
this.state = {
|
|
32
33
|
initialized: false,
|
|
33
|
-
pages: []
|
|
34
|
+
pages: [],
|
|
35
|
+
preloadDone: false
|
|
34
36
|
};
|
|
35
37
|
if (binding)
|
|
36
38
|
api_2.JsonRepository.setBinding(binding);
|
|
37
39
|
this.api = api_1.default.getInstance();
|
|
38
40
|
this.initRouteLists();
|
|
41
|
+
this.routeDescriptions = {};
|
|
39
42
|
}
|
|
40
43
|
setBinding(binding) {
|
|
41
44
|
if (!binding)
|
|
@@ -57,56 +60,15 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
57
60
|
}
|
|
58
61
|
preload(carouselSize = 5) {
|
|
59
62
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
-
if (this.state.loading)
|
|
63
|
+
if (this.state.loading || this.state.preloadDone)
|
|
61
64
|
return;
|
|
62
65
|
const promise = this._preload(carouselSize);
|
|
63
66
|
this.state.loading = { promise };
|
|
64
67
|
yield promise;
|
|
68
|
+
this.state.preloadDone = true;
|
|
65
69
|
this.state.loading = null;
|
|
66
70
|
});
|
|
67
71
|
}
|
|
68
|
-
_preload(carouselSize = 5, detailsOnly = false) {
|
|
69
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
-
if (!detailsOnly) {
|
|
71
|
-
yield this.loadRouteDescriptions();
|
|
72
|
-
}
|
|
73
|
-
this.emitPageUpdate();
|
|
74
|
-
const promises = [];
|
|
75
|
-
const promisesApi = [];
|
|
76
|
-
const lists = this.getRouteLists().map(li => li.list);
|
|
77
|
-
lists.forEach((list) => {
|
|
78
|
-
this.preloadList(list, carouselSize, detailsOnly);
|
|
79
|
-
});
|
|
80
|
-
this.logEvent({ message: 'preloading routes finished' });
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
preloadList(list, carouselSize = 5, detailsOnly = false) {
|
|
84
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
const promises = [];
|
|
86
|
-
const promisesApi = [];
|
|
87
|
-
this.emitPageUpdate();
|
|
88
|
-
this.routes.forEach(rle => {
|
|
89
|
-
var _a;
|
|
90
|
-
if (((_a = rle.routes) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
91
|
-
this.sort(rle.routes);
|
|
92
|
-
let cntApi = 0;
|
|
93
|
-
rle.routes.forEach((r) => {
|
|
94
|
-
if (!r.data.isLocal) {
|
|
95
|
-
cntApi++;
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
if (cntApi <= Math.min(carouselSize, rle.routes.length)) {
|
|
99
|
-
const loader = this.loadRouteDetais(r);
|
|
100
|
-
promises.push(loader);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
yield Promise.allSettled(promises);
|
|
106
|
-
this.emitPageUpdate();
|
|
107
|
-
this.logEvent({ message: 'preloading routes finished' });
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
72
|
load(props) {
|
|
111
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
74
|
const { routeId, list, loadFrom, loadTo } = props;
|
|
@@ -119,7 +81,7 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
119
81
|
if (list)
|
|
120
82
|
lists.push(list);
|
|
121
83
|
else
|
|
122
|
-
lists = this.
|
|
84
|
+
lists = this.lists.map(rle => rle.list);
|
|
123
85
|
lists.forEach(l => {
|
|
124
86
|
const routes = this.getRouteList(l);
|
|
125
87
|
for (let i = loadFrom; i < loadTo; i++) {
|
|
@@ -137,12 +99,10 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
137
99
|
}
|
|
138
100
|
this.stopAllRides();
|
|
139
101
|
const page = this.registerPage(pageId, props);
|
|
140
|
-
if (
|
|
141
|
-
this.preload(props.visibleCards);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.preload(5);
|
|
145
|
-
}
|
|
102
|
+
if (!this.state.preloadDone)
|
|
103
|
+
this.preload(props.visibleCards || 5);
|
|
104
|
+
else
|
|
105
|
+
this.onResize(pageId);
|
|
146
106
|
return page.state;
|
|
147
107
|
}
|
|
148
108
|
closeRouteSelection(pageId) {
|
|
@@ -151,6 +111,20 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
151
111
|
this.state.pages.splice(idx, 1);
|
|
152
112
|
}
|
|
153
113
|
}
|
|
114
|
+
onResize(pageId) {
|
|
115
|
+
const page = this.getPage(pageId);
|
|
116
|
+
const routeIds = Object.keys(page.onCarouselStateChanged);
|
|
117
|
+
routeIds.forEach(id => {
|
|
118
|
+
var _a;
|
|
119
|
+
const route = this.getRoute(id);
|
|
120
|
+
const stateChange = (_a = page.onCarouselStateChanged[id]) === null || _a === void 0 ? void 0 : _a.onCarouselStateChanged;
|
|
121
|
+
if (stateChange)
|
|
122
|
+
stateChange({ initialized: true, visible: false });
|
|
123
|
+
const update = page.onRouteUpdate[id].onRouteStateChanged;
|
|
124
|
+
if (update)
|
|
125
|
+
update(route.data);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
154
128
|
openStartSettings(r) {
|
|
155
129
|
var _a;
|
|
156
130
|
const route = this.getRouteFromStartProps(r);
|
|
@@ -184,6 +158,8 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
184
158
|
}
|
|
185
159
|
setCardUpdateHandler(pageId, r, list, idx, onRouteStateChanged, onCarouselStateChanged) {
|
|
186
160
|
const route = this.getRouteFromStartProps(r);
|
|
161
|
+
if (!route)
|
|
162
|
+
return;
|
|
187
163
|
const page = this.getPage(pageId);
|
|
188
164
|
if (!page)
|
|
189
165
|
return;
|
|
@@ -192,7 +168,6 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
192
168
|
}
|
|
193
169
|
onCarouselInitialized(pageId, list, startIdx, visibleSize) {
|
|
194
170
|
const page = this.getPage(pageId);
|
|
195
|
-
console.log('~~~ DEBUG:onCarouselInitialied', pageId, list, this.getListState(page, list), startIdx, visibleSize);
|
|
196
171
|
if (!page)
|
|
197
172
|
return;
|
|
198
173
|
const listState = this.getListState(page, list);
|
|
@@ -204,8 +179,6 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
204
179
|
routes.forEach((route) => {
|
|
205
180
|
const { idx, onCarouselStateChanged } = page.onCarouselStateChanged[route.id] || {};
|
|
206
181
|
const visible = listState !== undefined ? idx >= listState.startIdx && idx <= listState.endIdx : undefined;
|
|
207
|
-
if (route.data.title === 'Malaga City Tour')
|
|
208
|
-
console.log('~~~ DEBUG:Initialized -checked detail', visible, idx, listState.startIdx, listState.endIdx, route.data);
|
|
209
182
|
if (onCarouselStateChanged)
|
|
210
183
|
onCarouselStateChanged({ initialized: true, visible });
|
|
211
184
|
if (visible && (route.data.state === 'prepared' || route.data.state === 'error')) {
|
|
@@ -215,7 +188,6 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
215
188
|
}
|
|
216
189
|
onCarouselUpdated(pageId, list, startIdx, visibleSize) {
|
|
217
190
|
const page = this.getPage(pageId);
|
|
218
|
-
console.log('~~~ DEBUG:onCarouselUpdated', pageId, list, this.getListState(page, list), startIdx, visibleSize);
|
|
219
191
|
if (!page)
|
|
220
192
|
return;
|
|
221
193
|
const listState = this.getListState(page, list);
|
|
@@ -227,8 +199,6 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
227
199
|
routes.forEach((route) => {
|
|
228
200
|
const { idx, onCarouselStateChanged } = page.onCarouselStateChanged[route.id] || {};
|
|
229
201
|
const visible = listState !== undefined ? idx >= listState.startIdx && idx <= listState.endIdx : undefined;
|
|
230
|
-
if (route.data.title === 'Malaga City Tour')
|
|
231
|
-
console.log('~~~ DEBUG:Initialized -checked detail', visible, idx, listState.startIdx, listState.endIdx, route.data);
|
|
232
202
|
if (onCarouselStateChanged)
|
|
233
203
|
onCarouselStateChanged({ initialized: true, visible });
|
|
234
204
|
if (visible && route.data.state === 'prepared' || route.data.state === 'error') {
|
|
@@ -282,6 +252,44 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
282
252
|
}
|
|
283
253
|
cancelDownload(routeId) {
|
|
284
254
|
}
|
|
255
|
+
_preload(carouselSize = 5, detailsOnly = false) {
|
|
256
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
257
|
+
if (!detailsOnly) {
|
|
258
|
+
yield this.loadRouteDescriptions();
|
|
259
|
+
}
|
|
260
|
+
this.emitPageUpdate();
|
|
261
|
+
const lists = this.getRouteLists().map(li => li.list);
|
|
262
|
+
lists.forEach((list) => {
|
|
263
|
+
this.preloadList(list, carouselSize);
|
|
264
|
+
});
|
|
265
|
+
this.logEvent({ message: 'preloading routes finished' });
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
preloadList(list, carouselSize = 5) {
|
|
269
|
+
var _a;
|
|
270
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
271
|
+
this.emitPageUpdate();
|
|
272
|
+
const promises = [];
|
|
273
|
+
const rle = this.lists.find(l => l.list === list);
|
|
274
|
+
if (((_a = rle.routes) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
275
|
+
this.sort(rle.routes);
|
|
276
|
+
let cntApi = 0;
|
|
277
|
+
rle.routes.forEach((r) => {
|
|
278
|
+
if (!r.data.isLocal) {
|
|
279
|
+
cntApi++;
|
|
280
|
+
}
|
|
281
|
+
if (r.data.isLocal || cntApi <= Math.min(carouselSize, rle.routes.length)) {
|
|
282
|
+
promises.push(this.loadRouteDetais(r));
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
console.log('~~~ DEBUG: during preload', promises.length);
|
|
287
|
+
Promise.allSettled(promises).then((res) => {
|
|
288
|
+
console.log('~~~ DEBUG: after preload', (0, clone_1.default)(this.state), (0, clone_1.default)(this.routeDescriptions), res);
|
|
289
|
+
this.saveRouteDescriptions();
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
}
|
|
285
293
|
loadStartSettingsFromUserSettings(route) {
|
|
286
294
|
let startPos = 0, realityFactor = 100, segment;
|
|
287
295
|
const { data } = route;
|
|
@@ -301,6 +309,10 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
301
309
|
if (prevRoutePosition !== null) {
|
|
302
310
|
startPos = prevRoutePosition;
|
|
303
311
|
}
|
|
312
|
+
if (data.videoFormat === 'avi') {
|
|
313
|
+
startPos = 0;
|
|
314
|
+
segment = undefined;
|
|
315
|
+
}
|
|
304
316
|
return { startPos, realityFactor, segment };
|
|
305
317
|
}
|
|
306
318
|
writeStartSettingsToUserSettings(route, startSettings) {
|
|
@@ -335,10 +347,10 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
335
347
|
});
|
|
336
348
|
}
|
|
337
349
|
initRouteLists() {
|
|
338
|
-
this.
|
|
339
|
-
this.
|
|
340
|
-
this.
|
|
341
|
-
this.
|
|
350
|
+
this.lists = [];
|
|
351
|
+
this.lists.push({ list: "myRoutes", routes: [] });
|
|
352
|
+
this.lists.push({ list: "selected", routes: [] });
|
|
353
|
+
this.lists.push({ list: "alternatives", routes: [] });
|
|
342
354
|
}
|
|
343
355
|
getPageState(pageId, lang) {
|
|
344
356
|
var _a;
|
|
@@ -347,6 +359,11 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
347
359
|
const language = lang || ((_a = this.getPage(pageId)) === null || _a === void 0 ? void 0 : _a.language) || 'en';
|
|
348
360
|
const add = (list, listHeader) => {
|
|
349
361
|
const data = this.getRouteList(list);
|
|
362
|
+
if (list === 'myRoutes' && !data.find(r => r.data.type === 'free-ride')) {
|
|
363
|
+
const card = new FreeRideCard_1.FreeRideCard('loaded');
|
|
364
|
+
const route = { data: card, id: 'free-ride', };
|
|
365
|
+
data.unshift(route);
|
|
366
|
+
}
|
|
350
367
|
if ((data === null || data === void 0 ? void 0 : data.length) > 0) {
|
|
351
368
|
lists.push(this.getRouteListDataEntry(list, data, language, listHeader));
|
|
352
369
|
}
|
|
@@ -354,6 +371,7 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
354
371
|
add('myRoutes', 'My Routes');
|
|
355
372
|
add('selected', 'Selected For Me');
|
|
356
373
|
add('alternatives', 'Alternatives');
|
|
374
|
+
console.log('~~~ DEBUG:getPageState', state);
|
|
357
375
|
return state;
|
|
358
376
|
}
|
|
359
377
|
registerPage(pageId, props) {
|
|
@@ -407,7 +425,9 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
407
425
|
local.distance = local.distance || details.distance;
|
|
408
426
|
local.elevation = local.elevation || details.elevation;
|
|
409
427
|
local.localizedTitle = local.localizedTitle || details.localizedTitle;
|
|
410
|
-
local.points
|
|
428
|
+
if (!local.points) {
|
|
429
|
+
local.points = details.points;
|
|
430
|
+
}
|
|
411
431
|
if (!local.hasGpx && details.points) {
|
|
412
432
|
local.hasGpx = true;
|
|
413
433
|
}
|
|
@@ -434,7 +454,7 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
434
454
|
}
|
|
435
455
|
convertDescription(descr, isLocal) {
|
|
436
456
|
const { id, title, localizedTitle, country, distance, elevation, category, provider, video, points } = descr;
|
|
437
|
-
const data = { state: 'prepared', id, title, localizedTitle, country, distance, elevation, provider, category };
|
|
457
|
+
const data = { type: 'route', state: 'prepared', id, title, localizedTitle, country, distance, elevation, provider, category };
|
|
438
458
|
data.hasVideo = false;
|
|
439
459
|
data.hasGpx = false;
|
|
440
460
|
data.isLocal = isLocal || false;
|
|
@@ -460,7 +480,6 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
460
480
|
if (description.category === 'personal')
|
|
461
481
|
return 'myRoutes';
|
|
462
482
|
list = description.category ? 'alternatives' : 'selected';
|
|
463
|
-
console.log('~~~ DEBUG', description.title, description.private, list);
|
|
464
483
|
return list;
|
|
465
484
|
}
|
|
466
485
|
if (description.type === 'video') {
|
|
@@ -478,7 +497,7 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
478
497
|
}
|
|
479
498
|
getRouteList(list) {
|
|
480
499
|
var _a;
|
|
481
|
-
return (_a = this.
|
|
500
|
+
return (_a = this.lists.find(rle => rle.list === list)) === null || _a === void 0 ? void 0 : _a.routes;
|
|
482
501
|
}
|
|
483
502
|
getRouteLists() {
|
|
484
503
|
const lists = [
|
|
@@ -492,19 +511,36 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
492
511
|
let compareFn = criteria;
|
|
493
512
|
if (typeof criteria === 'string')
|
|
494
513
|
compareFn = v => v.id === criteria;
|
|
495
|
-
const lists = this.
|
|
514
|
+
const lists = this.lists;
|
|
496
515
|
let route = null;
|
|
497
516
|
for (let i = 0; i < lists.length && !route; i++) {
|
|
498
517
|
route = lists[i].routes.find(compareFn);
|
|
499
518
|
}
|
|
500
519
|
return route;
|
|
501
520
|
}
|
|
521
|
+
getAllRoutes() {
|
|
522
|
+
const lists = this.lists;
|
|
523
|
+
const routes = [];
|
|
524
|
+
for (let i = 0; i < lists.length; i++) {
|
|
525
|
+
routes.push(...lists[i].routes);
|
|
526
|
+
}
|
|
527
|
+
return routes;
|
|
528
|
+
}
|
|
502
529
|
stopAllRides() {
|
|
503
|
-
const lists = this.
|
|
530
|
+
const lists = this.lists;
|
|
504
531
|
for (let i = 0; i < lists.length; i++) {
|
|
505
532
|
lists[i].routes.forEach(r => r.startState = 'idle');
|
|
506
533
|
}
|
|
507
534
|
}
|
|
535
|
+
addDescriptionsFromDB(descriptions) {
|
|
536
|
+
const ids = Object.keys(descriptions);
|
|
537
|
+
const routes = ids.map(id => descriptions[id]);
|
|
538
|
+
this.routeDescriptions = descriptions;
|
|
539
|
+
routes.forEach((data) => {
|
|
540
|
+
data.state = "prepared";
|
|
541
|
+
this.addRouteToList(data.list, { data, id: data.id });
|
|
542
|
+
});
|
|
543
|
+
}
|
|
508
544
|
addDescriptionsFromRepo(descriptions, repo) {
|
|
509
545
|
const routes = descriptions;
|
|
510
546
|
if (repo) {
|
|
@@ -526,13 +562,13 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
526
562
|
data.isLocal = true;
|
|
527
563
|
const item = { id: data.id, data };
|
|
528
564
|
this.addRouteToList(list, item);
|
|
565
|
+
this.routeDescriptions[data.id] = Object.assign(Object.assign({}, data), { list });
|
|
529
566
|
}
|
|
530
567
|
});
|
|
531
568
|
}
|
|
532
569
|
addDescriptionsFromServer(descriptions) {
|
|
533
570
|
const converted = descriptions.map(this.convertDescription.bind(this));
|
|
534
571
|
converted.forEach((data, idx) => {
|
|
535
|
-
console.log('~~~ DEBUG:add route from Server', data.title);
|
|
536
572
|
const existing = this.getRoute(data.id);
|
|
537
573
|
if (existing) {
|
|
538
574
|
return;
|
|
@@ -551,6 +587,7 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
551
587
|
data.isLocal = false;
|
|
552
588
|
const item = { id: data.id, data };
|
|
553
589
|
this.addRouteToList(list, item);
|
|
590
|
+
this.routeDescriptions[data.id] = Object.assign(Object.assign({}, data), { list });
|
|
554
591
|
this.emitPageUpdate();
|
|
555
592
|
}
|
|
556
593
|
});
|
|
@@ -594,30 +631,53 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
594
631
|
}
|
|
595
632
|
loadRouteDescriptionsFromRepo() {
|
|
596
633
|
return __awaiter(this, void 0, void 0, function* () {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
634
|
+
if (Object.keys(this.routeDescriptions).length > 0) {
|
|
635
|
+
this.emitPageUpdate();
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
const all = yield this.getRoutesRepo().read('settings');
|
|
639
|
+
if (!all) {
|
|
640
|
+
const videos = ((yield this.getVideosRepo().read('routes')) || []);
|
|
641
|
+
this.addDescriptionsFromRepo(videos, this.getVideosRepo());
|
|
642
|
+
const routes = ((yield this.getRoutesRepo().read('routes')) || []);
|
|
643
|
+
this.addDescriptionsFromRepo(routes, this.getRoutesRepo());
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
const ids = Object.keys(all);
|
|
647
|
+
ids.forEach(id => {
|
|
648
|
+
const r = all[id];
|
|
649
|
+
if (typeof r.points === 'string') {
|
|
650
|
+
this.decodePoints(r);
|
|
651
|
+
}
|
|
652
|
+
if (!Array.isArray(r.points))
|
|
653
|
+
delete r.points;
|
|
654
|
+
});
|
|
655
|
+
console.log('~~~ DEBUG:', all);
|
|
656
|
+
this.addDescriptionsFromDB(all);
|
|
657
|
+
}
|
|
658
|
+
this.saveRouteDescriptions();
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
saveRouteDescriptions() {
|
|
662
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
663
|
+
const ids = Object.keys(this.routeDescriptions);
|
|
664
|
+
const data = ids.map(id => {
|
|
665
|
+
const r = this.routeDescriptions[id];
|
|
666
|
+
if (r.points)
|
|
667
|
+
this.encodePoints(r);
|
|
668
|
+
return Object.assign({}, r);
|
|
669
|
+
});
|
|
670
|
+
yield this.getRoutesRepo().write('settings', data);
|
|
608
671
|
});
|
|
609
672
|
}
|
|
610
673
|
loadRouteDescriptionsFromServer() {
|
|
611
674
|
return __awaiter(this, void 0, void 0, function* () {
|
|
612
|
-
console.log('~~~ DEBUG:loadRouteDescriptionsFromServer');
|
|
613
675
|
const enrichApi = (v, type) => (Object.assign({ type }, v));
|
|
614
676
|
const api = [
|
|
615
677
|
this.api.getRouteDescriptions({ type: 'gpx' }).then(v => v.map(e => enrichApi(e, 'gpx'))),
|
|
616
678
|
this.api.getRouteDescriptions({ type: 'video' }).then(v => v.map(e => enrichApi(e, 'video')))
|
|
617
679
|
];
|
|
618
680
|
const res = yield Promise.allSettled(api);
|
|
619
|
-
console.log('~~~ DEBUG:loadRouteDescriptionsFromServer done', (new Date()).toISOString(), res);
|
|
620
|
-
this.emitPageUpdate();
|
|
621
681
|
res.forEach(p => {
|
|
622
682
|
if (p.status === 'fulfilled') {
|
|
623
683
|
this.addDescriptionsFromServer(p.value);
|
|
@@ -627,34 +687,45 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
627
687
|
}
|
|
628
688
|
loadRouteDescriptions() {
|
|
629
689
|
return __awaiter(this, void 0, void 0, function* () {
|
|
690
|
+
console.log('~~~ DEBUG:loadRouteDescriptions', Object.keys(this.routeDescriptions));
|
|
630
691
|
yield this.loadRouteDescriptionsFromRepo();
|
|
631
|
-
console.log('~~~ DEBUG, routes after Repo', this.routes);
|
|
632
692
|
this.emitPageUpdate();
|
|
633
|
-
this.
|
|
634
|
-
|
|
635
|
-
|
|
693
|
+
if (this.isDescriptionsLoaded()) {
|
|
694
|
+
yield this.loadRouteDescriptionsFromServer();
|
|
695
|
+
this.emitPageUpdate();
|
|
696
|
+
this.saveRouteDescriptions();
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
this.loadRouteDescriptionsFromServer().then(() => {
|
|
700
|
+
this.emitPageUpdate();
|
|
701
|
+
});
|
|
702
|
+
}
|
|
636
703
|
});
|
|
637
704
|
}
|
|
638
705
|
loadRouteDetais(route) {
|
|
639
706
|
return __awaiter(this, void 0, void 0, function* () {
|
|
640
|
-
|
|
641
|
-
if (route.data.state === 'loaded')
|
|
707
|
+
if (route.data.state === 'loaded' || route.data.state === 'loading')
|
|
642
708
|
return;
|
|
643
709
|
try {
|
|
644
710
|
route.data.state = 'loading';
|
|
645
711
|
this.emitRouteUpdated(route);
|
|
646
|
-
|
|
712
|
+
try {
|
|
647
713
|
route.details = route.data.hasVideo ?
|
|
648
|
-
yield this.
|
|
714
|
+
yield this.getVideosRepo().read(route.id)
|
|
649
715
|
:
|
|
650
|
-
yield this.
|
|
716
|
+
yield this.getRoutesRepo().read(route.id);
|
|
651
717
|
api_1.default.verify(route.details);
|
|
652
718
|
}
|
|
653
|
-
|
|
719
|
+
catch (err) {
|
|
720
|
+
console.log('~~~ DEBUG:error', route.data.title, route.data.isLocal, err);
|
|
721
|
+
if (route.data.isLocal)
|
|
722
|
+
throw err;
|
|
723
|
+
}
|
|
724
|
+
if (!route.details) {
|
|
654
725
|
route.details = yield this.api.getRouteDetails(route.id);
|
|
726
|
+
api_1.default.verify(route.details);
|
|
727
|
+
this.saveRouteDetails(route);
|
|
655
728
|
}
|
|
656
|
-
if (route.data.title === 'Arnbach')
|
|
657
|
-
console.log('~~~ DEBUG: loaded details', route.details);
|
|
658
729
|
if (route.details.id !== route.data.id) {
|
|
659
730
|
route.data.state = 'error';
|
|
660
731
|
delete route.details;
|
|
@@ -663,14 +734,30 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
663
734
|
this.mergeWithDetails(route);
|
|
664
735
|
route.data.state = 'loaded';
|
|
665
736
|
this.emitRouteUpdated(route);
|
|
737
|
+
const { list } = this.routeDescriptions[route.id];
|
|
738
|
+
this.routeDescriptions[route.id] = Object.assign(Object.assign({}, route.data), { list });
|
|
739
|
+
return route.data;
|
|
666
740
|
}
|
|
667
741
|
catch (e) {
|
|
668
|
-
console.log('~~~ DEBUG:Error', e);
|
|
669
742
|
route.data.state = 'error';
|
|
670
743
|
this.emitRouteUpdated(route);
|
|
671
744
|
}
|
|
672
745
|
});
|
|
673
746
|
}
|
|
747
|
+
saveRouteDetails(route) {
|
|
748
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
749
|
+
try {
|
|
750
|
+
route.details = route.data.hasVideo ?
|
|
751
|
+
yield this.videosRepo.write(route.id, route.details)
|
|
752
|
+
:
|
|
753
|
+
yield this.routesRepo.write(route.id, route.details);
|
|
754
|
+
}
|
|
755
|
+
catch (err) {
|
|
756
|
+
if (route.data.isLocal)
|
|
757
|
+
throw err;
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
}
|
|
674
761
|
emitRouteUpdated(route) {
|
|
675
762
|
this.emit('route-update', route.id, route.data);
|
|
676
763
|
this.state.pages.forEach(page => {
|
|
@@ -688,7 +775,6 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
688
775
|
});
|
|
689
776
|
}
|
|
690
777
|
getListState(page, list) {
|
|
691
|
-
console.log('~~~ DEBUG.getListState', list, page === null || page === void 0 ? void 0 : page.state, this.state);
|
|
692
778
|
return page === null || page === void 0 ? void 0 : page.state.lists.find(pl => pl.list === list);
|
|
693
779
|
}
|
|
694
780
|
getRouteFromStartProps(r) {
|
|
@@ -707,6 +793,15 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
707
793
|
return;
|
|
708
794
|
}
|
|
709
795
|
}
|
|
796
|
+
isDescriptionsLoaded() {
|
|
797
|
+
return Object.keys(this.routeDescriptions).length === 0;
|
|
798
|
+
}
|
|
799
|
+
decodePoints(r) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
encodePoints(r) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
710
805
|
}
|
|
711
806
|
exports.RouteListService = RouteListService;
|
|
712
807
|
const useRouteList = () => RouteListService.getInstance();
|
|
@@ -12,10 +12,14 @@ export type RouteListStartProps = {
|
|
|
12
12
|
export type LocalizedText = {
|
|
13
13
|
[index: string]: string;
|
|
14
14
|
};
|
|
15
|
-
export type
|
|
15
|
+
export type CardType = 'route' | 'free-ride' | 'import';
|
|
16
|
+
export interface CardInfo {
|
|
17
|
+
type: CardType;
|
|
16
18
|
state: RouteState;
|
|
17
|
-
id?: string;
|
|
18
19
|
title?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RouteInfo extends CardInfo {
|
|
22
|
+
id?: string;
|
|
19
23
|
localizedTitle?: LocalizedText;
|
|
20
24
|
country?: string;
|
|
21
25
|
isLoop?: boolean;
|
|
@@ -31,8 +35,21 @@ export type RouteInfo = {
|
|
|
31
35
|
videoFormat?: string;
|
|
32
36
|
videoUrl?: string;
|
|
33
37
|
previewUrl?: string;
|
|
34
|
-
points?: Array<RoutePoint
|
|
38
|
+
points?: Array<RoutePoint> | string;
|
|
35
39
|
segments?: Array<RouteSegment>;
|
|
40
|
+
}
|
|
41
|
+
export interface RouteDBEntry extends RouteInfo {
|
|
42
|
+
list: List;
|
|
43
|
+
settings?: {
|
|
44
|
+
position?: number;
|
|
45
|
+
segment?: string;
|
|
46
|
+
realityFactor?: number;
|
|
47
|
+
};
|
|
48
|
+
cntStarts?: number;
|
|
49
|
+
lastStart?: number;
|
|
50
|
+
}
|
|
51
|
+
export type RoutesDB = {
|
|
52
|
+
[index: string]: RouteDBEntry;
|
|
36
53
|
};
|
|
37
54
|
export type RouteListDateEntry = {
|
|
38
55
|
list: List;
|
|
@@ -87,17 +104,20 @@ export interface InternalRouteListState {
|
|
|
87
104
|
initialized: boolean;
|
|
88
105
|
pages: Array<Page>;
|
|
89
106
|
loading?: LoadingState;
|
|
107
|
+
preloadDone: boolean;
|
|
90
108
|
}
|
|
91
109
|
export type RouteStartState = 'idle' | 'preparing' | 'selected' | 'started';
|
|
92
|
-
export type
|
|
110
|
+
export type Card<T> = {
|
|
93
111
|
id: string;
|
|
94
|
-
data:
|
|
112
|
+
data: T;
|
|
95
113
|
details?: RouteApiDetail;
|
|
96
114
|
startSettings?: RouteStartSettings;
|
|
97
115
|
startState?: RouteStartState;
|
|
98
116
|
};
|
|
99
|
-
export type
|
|
117
|
+
export type CardListEntry<T> = {
|
|
100
118
|
list: List;
|
|
101
|
-
routes: Array<
|
|
119
|
+
routes: Array<Card<T>>;
|
|
102
120
|
};
|
|
121
|
+
export type Route = Card<RouteInfo>;
|
|
122
|
+
export type RouteListEntry = CardListEntry<RouteInfo>;
|
|
103
123
|
export type List = 'myRoutes' | 'alternatives' | 'selected';
|
package/lib/utils/geo.js
CHANGED
|
@@ -47,9 +47,11 @@ const getPointAfter = (p1, p2, offset) => {
|
|
|
47
47
|
};
|
|
48
48
|
exports.getPointAfter = getPointAfter;
|
|
49
49
|
const getLatLng = (position) => {
|
|
50
|
-
if (Array.isArray(position))
|
|
50
|
+
if (Array.isArray(position)) {
|
|
51
51
|
return { lat: position[0], lng: position[1] };
|
|
52
|
-
|
|
52
|
+
}
|
|
53
|
+
if (position.lat !== undefined && position.lng !== undefined) {
|
|
53
54
|
return position;
|
|
55
|
+
}
|
|
54
56
|
};
|
|
55
57
|
exports.getLatLng = getLatLng;
|