incyclist-services 1.0.55 → 1.0.57
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/api/index.d.ts +1 -0
- package/lib/api/index.js +1 -0
- package/lib/api/repository/json/index.d.ts +9 -7
- package/lib/api/repository/json/index.js +34 -21
- package/lib/api/repository/types.d.ts +12 -4
- package/lib/api/repository/types.js +4 -0
- package/lib/devices/pairing/model.d.ts +4 -2
- package/lib/devices/pairing/service.d.ts +2 -0
- package/lib/devices/pairing/service.js +24 -5
- package/lib/routes/base/api/index.d.ts +2 -1
- package/lib/routes/base/api/index.js +9 -7
- package/lib/routes/base/api/types.d.ts +17 -0
- package/lib/routes/base/types/index.d.ts +1 -1
- package/lib/routes/list/service.d.ts +24 -8
- package/lib/routes/list/service.js +226 -26
- package/lib/routes/list/types.d.ts +20 -0
- package/package.json +2 -2
package/lib/api/index.d.ts
CHANGED
package/lib/api/index.js
CHANGED
|
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./rest/index"), exports);
|
|
18
18
|
__exportStar(require("./rest/types"), exports);
|
|
19
|
+
__exportStar(require("./repository"), exports);
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { EventLogger } from "gd-eventlog";
|
|
2
|
-
import {
|
|
2
|
+
import { IJsonRepositoryBinding, JSONObject, JsonAccess } from "../types";
|
|
3
3
|
export declare class JsonRepository {
|
|
4
4
|
protected static _instances: {
|
|
5
5
|
[x: string]: JsonRepository;
|
|
6
6
|
};
|
|
7
|
-
protected static _defaultBinding:
|
|
7
|
+
protected static _defaultBinding: IJsonRepositoryBinding;
|
|
8
8
|
static create(repoName: string): JsonRepository;
|
|
9
|
-
static setBinding(binding:
|
|
10
|
-
protected binding:
|
|
9
|
+
static setBinding(binding: IJsonRepositoryBinding): void;
|
|
10
|
+
protected binding: IJsonRepositoryBinding;
|
|
11
11
|
protected name: string;
|
|
12
12
|
protected db: string;
|
|
13
13
|
protected logger: EventLogger;
|
|
14
|
-
|
|
14
|
+
protected access: JsonAccess;
|
|
15
|
+
constructor(repoName: string, binding?: IJsonRepositoryBinding);
|
|
16
|
+
getName(): string;
|
|
17
|
+
write(objectName: string, data: JSONObject): Promise<boolean>;
|
|
18
|
+
read(objectName: string): Promise<JSONObject>;
|
|
15
19
|
protected open(): Promise<boolean>;
|
|
16
20
|
protected close(): Promise<boolean>;
|
|
17
|
-
protected write(objectName: string, data: JSONObject): Promise<boolean>;
|
|
18
|
-
protected read(objectName: string): Promise<JSONObject>;
|
|
19
21
|
}
|
|
@@ -26,16 +26,48 @@ class JsonRepository {
|
|
|
26
26
|
this.binding = binding || JsonRepository._defaultBinding;
|
|
27
27
|
this.logger = new gd_eventlog_1.EventLogger(`Repo-${this.name}`);
|
|
28
28
|
}
|
|
29
|
+
getName() {
|
|
30
|
+
return this.name;
|
|
31
|
+
}
|
|
32
|
+
write(objectName, data) {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
yield this.open();
|
|
35
|
+
const success = yield this.access.write(objectName, data);
|
|
36
|
+
if (!success) {
|
|
37
|
+
}
|
|
38
|
+
return success;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
read(objectName) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
yield this.open();
|
|
44
|
+
try {
|
|
45
|
+
const data = yield this.access.read(objectName);
|
|
46
|
+
if (!data) {
|
|
47
|
+
}
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
29
54
|
open() {
|
|
30
55
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
if (this.access)
|
|
57
|
+
return true;
|
|
31
58
|
if (!this.binding)
|
|
32
59
|
throw new Error('no binding specified');
|
|
33
60
|
try {
|
|
34
61
|
const existing = yield this.binding.get(this.name);
|
|
35
62
|
if (existing) {
|
|
63
|
+
this.access = existing;
|
|
36
64
|
return true;
|
|
37
65
|
}
|
|
38
|
-
|
|
66
|
+
const access = yield this.binding.create(this.name);
|
|
67
|
+
if (!access)
|
|
68
|
+
return false;
|
|
69
|
+
this.access = access;
|
|
70
|
+
return true;
|
|
39
71
|
}
|
|
40
72
|
catch (err) {
|
|
41
73
|
return false;
|
|
@@ -47,29 +79,10 @@ class JsonRepository {
|
|
|
47
79
|
if (!this.binding)
|
|
48
80
|
throw new Error('no binding specified');
|
|
49
81
|
this.binding.release(this.name);
|
|
82
|
+
this.access = null;
|
|
50
83
|
return true;
|
|
51
84
|
});
|
|
52
85
|
}
|
|
53
|
-
write(objectName, data) {
|
|
54
|
-
if (!this.binding)
|
|
55
|
-
throw new Error('no binding specified');
|
|
56
|
-
const success = this.binding.write(objectName, data);
|
|
57
|
-
if (!success) {
|
|
58
|
-
}
|
|
59
|
-
return success;
|
|
60
|
-
}
|
|
61
|
-
read(objectName) {
|
|
62
|
-
if (!this.binding)
|
|
63
|
-
throw new Error('no binding specified');
|
|
64
|
-
try {
|
|
65
|
-
const data = this.binding.read(objectName);
|
|
66
|
-
if (!data) {
|
|
67
|
-
}
|
|
68
|
-
return data;
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
86
|
}
|
|
74
87
|
exports.JsonRepository = JsonRepository;
|
|
75
88
|
JsonRepository._instances = {};
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
export type JSONObject = string | number | boolean | {
|
|
2
2
|
[x: string]: JSONObject;
|
|
3
3
|
} | Array<JSONObject>;
|
|
4
|
-
export
|
|
5
|
-
create(name: string): Promise<boolean>;
|
|
6
|
-
get(name: string): Promise<boolean>;
|
|
7
|
-
release(name: string): Promise<boolean>;
|
|
4
|
+
export type JsonAccess = {
|
|
8
5
|
read(resourceName: string): Promise<JSONObject>;
|
|
9
6
|
write(resourceName: string, data: JSONObject): Promise<boolean>;
|
|
7
|
+
delete(resourceName: string): Promise<boolean>;
|
|
8
|
+
};
|
|
9
|
+
export interface IJsonRepositoryBinding {
|
|
10
|
+
create(name: string): Promise<JsonAccess | null>;
|
|
11
|
+
get(name: string): Promise<JsonAccess | null>;
|
|
12
|
+
release(name: string): Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
export declare abstract class AbstractJsonRepositoryBinding implements IJsonRepositoryBinding {
|
|
15
|
+
abstract create(name: string): Promise<JsonAccess | null>;
|
|
16
|
+
abstract get(name: string): Promise<JsonAccess | null>;
|
|
17
|
+
abstract release(name: string): Promise<boolean>;
|
|
10
18
|
}
|
|
@@ -52,10 +52,12 @@ export interface InternalPairingState extends PairingState {
|
|
|
52
52
|
scanTo?: NodeJS.Timeout;
|
|
53
53
|
tsPrevStart?: number;
|
|
54
54
|
check?: {
|
|
55
|
-
|
|
55
|
+
preparing?: number;
|
|
56
|
+
promise?: Promise<boolean>;
|
|
56
57
|
};
|
|
57
58
|
scan?: {
|
|
58
|
-
|
|
59
|
+
preparing?: number;
|
|
60
|
+
promise?: Promise<DeviceSettings[]>;
|
|
59
61
|
adapters?: Array<{
|
|
60
62
|
udid: string;
|
|
61
63
|
adapter: IncyclistDeviceAdapter;
|
|
@@ -12,6 +12,8 @@ export interface Services {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class DevicePairingService extends IncyclistService {
|
|
14
14
|
protected static _instance: DevicePairingService;
|
|
15
|
+
protected static checkCounter: number;
|
|
16
|
+
protected static scanCounter: number;
|
|
15
17
|
protected configuration: DeviceConfigurationService;
|
|
16
18
|
protected access: DeviceAccessService;
|
|
17
19
|
protected rideService: DeviceRideService;
|
|
@@ -198,12 +198,13 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
198
198
|
const c = this.getCapability(capability);
|
|
199
199
|
if (cntSelected === 1 && c.selected === udid) {
|
|
200
200
|
const adapter = this.getDeviceAdapter(udid);
|
|
201
|
-
adapter
|
|
201
|
+
if (adapter)
|
|
202
|
+
adapter.stop();
|
|
202
203
|
}
|
|
203
204
|
if (deleteAll) {
|
|
204
205
|
const adapter = this.getDeviceAdapter(udid);
|
|
205
206
|
const capabilities = adapter.getCapabilities();
|
|
206
|
-
capabilities.forEach((c, idx) => {
|
|
207
|
+
capabilities === null || capabilities === void 0 ? void 0 : capabilities.forEach((c, idx) => {
|
|
207
208
|
const shouldEmit = (idx === capabilities.length - 1);
|
|
208
209
|
this.deleteCapabilityDevice(c, udid, shouldEmit);
|
|
209
210
|
});
|
|
@@ -431,7 +432,6 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
431
432
|
const current = getInterfaceSettings(ifName, prev);
|
|
432
433
|
const changed = (current.state !== ifDetails.state || current.isScanning !== ifDetails.isScanning || current.enabled !== ifDetails.enabled);
|
|
433
434
|
if (!changed) {
|
|
434
|
-
console.log('~~~ DEUBUG: if change, no change', ifName, ifDetails);
|
|
435
435
|
return;
|
|
436
436
|
}
|
|
437
437
|
this.logEvent({ message: 'interface state changed', interface: ifName, state: ifDetails.state });
|
|
@@ -765,6 +765,10 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
765
765
|
}
|
|
766
766
|
startPairing(adapters, props) {
|
|
767
767
|
return __awaiter(this, void 0, void 0, function* () {
|
|
768
|
+
if (this.isPairing())
|
|
769
|
+
return;
|
|
770
|
+
const preparing = DevicePairingService.checkCounter++;
|
|
771
|
+
this.state.check = { preparing };
|
|
768
772
|
this.emit('pairing-start');
|
|
769
773
|
const requiredInterfaces = this.getPairingInterfaces();
|
|
770
774
|
const busyRequired = this.state.interfaces
|
|
@@ -773,8 +777,10 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
773
777
|
const isReady = busyRequired === undefined;
|
|
774
778
|
if (!isReady) {
|
|
775
779
|
setTimeout(() => {
|
|
776
|
-
if (!this.isPairing() && !this.isScanning())
|
|
780
|
+
if ((!this.isPairing() || this.state.check.preparing === preparing) && !this.isScanning()) {
|
|
781
|
+
delete this.state.check;
|
|
777
782
|
this.run();
|
|
783
|
+
}
|
|
778
784
|
}, 1000);
|
|
779
785
|
return;
|
|
780
786
|
}
|
|
@@ -782,6 +788,9 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
782
788
|
this.processConnectedDevices(adapters);
|
|
783
789
|
const selected = this.state.capabilities.map(c => c.selected);
|
|
784
790
|
const target = adapters.filter(ai => !ai.adapter.isStarted() && selected.includes(ai.udid));
|
|
791
|
+
if (this.isPairing() && this.state.check.preparing !== preparing) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
785
794
|
this.initPairingCallbacks();
|
|
786
795
|
const selectedAdapters = target.map(ai => (Object.assign(Object.assign({}, ai), { isStarted: false })));
|
|
787
796
|
const promise = this.rideService.startAdapters(selectedAdapters, 'pair');
|
|
@@ -819,18 +828,26 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
819
828
|
return __awaiter(this, void 0, void 0, function* () {
|
|
820
829
|
const interfaces = this.state.interfaces.filter(i => this.isInterfaceEnabled(i) && i.state === 'connected')
|
|
821
830
|
.map(i => i.name);
|
|
831
|
+
if (this.isScanning())
|
|
832
|
+
return;
|
|
833
|
+
const preparing = DevicePairingService.scanCounter++;
|
|
834
|
+
this.state.scan = { preparing };
|
|
822
835
|
if (interfaces.length === 0) {
|
|
823
836
|
if (this.state.scanTo)
|
|
824
837
|
return;
|
|
825
838
|
this.state.scanTo = setTimeout(() => {
|
|
826
839
|
delete this.state.scanTo;
|
|
827
|
-
if (!this.isPairing() && !this.isScanning())
|
|
840
|
+
if (!this.isPairing() && (!this.isScanning() || this.state.scan.preparing === preparing)) {
|
|
841
|
+
delete this.state.scan;
|
|
828
842
|
this.run();
|
|
843
|
+
}
|
|
829
844
|
}, 1000);
|
|
830
845
|
return;
|
|
831
846
|
}
|
|
832
847
|
this.emit('scanning-start');
|
|
833
848
|
this.state.tsPrevStart = Date.now();
|
|
849
|
+
if (this.isScanning() && this.state.scan.preparing !== preparing)
|
|
850
|
+
return;
|
|
834
851
|
this.logEvent({ message: 'Start Scanning', interfaces: interfaces.join(','), props });
|
|
835
852
|
this.initScanningCallbacks();
|
|
836
853
|
const timeout = props.enforcedScan ? 1000 * 60 * 60 : undefined;
|
|
@@ -1139,5 +1156,7 @@ class DevicePairingService extends service_2.IncyclistService {
|
|
|
1139
1156
|
}
|
|
1140
1157
|
}
|
|
1141
1158
|
exports.DevicePairingService = DevicePairingService;
|
|
1159
|
+
DevicePairingService.checkCounter = 0;
|
|
1160
|
+
DevicePairingService.scanCounter = 0;
|
|
1142
1161
|
const useDevicePairing = () => DevicePairingService.getInstance();
|
|
1143
1162
|
exports.useDevicePairing = useDevicePairing;
|
|
@@ -12,7 +12,8 @@ export default class IncyclistRoutesApi {
|
|
|
12
12
|
protected getApi(): AxiosInstance;
|
|
13
13
|
protected getBaseUrl(): any;
|
|
14
14
|
getRouteDescriptions(query: RouteDescriptionQuery): Promise<Array<RouteApiDescription>>;
|
|
15
|
-
|
|
15
|
+
static verify(route: any): void;
|
|
16
|
+
protected static fixMissingRouteDistances(points: Array<RoutePoint>): void;
|
|
16
17
|
getRouteDetails(routeId: string): Promise<RouteApiDetail>;
|
|
17
18
|
reload(): Promise<any>;
|
|
18
19
|
protected _get(url: string, ...args: any[]): Promise<import("axios").AxiosResponse<any, any>>;
|
|
@@ -25,7 +25,6 @@ class IncyclistRoutesApi {
|
|
|
25
25
|
logError(err, fn, logInfo) {
|
|
26
26
|
const args = logInfo || {};
|
|
27
27
|
this.logger.logEvent(Object.assign({ message: 'Error', error: err.message, fn }, args));
|
|
28
|
-
console.log(err);
|
|
29
28
|
}
|
|
30
29
|
getApi() {
|
|
31
30
|
if (!this.api) {
|
|
@@ -53,7 +52,14 @@ class IncyclistRoutesApi {
|
|
|
53
52
|
}
|
|
54
53
|
});
|
|
55
54
|
}
|
|
56
|
-
|
|
55
|
+
static verify(route) {
|
|
56
|
+
if (route['decoded']) {
|
|
57
|
+
route.points = route['decoded'];
|
|
58
|
+
delete route['decoded'];
|
|
59
|
+
IncyclistRoutesApi.fixMissingRouteDistances(route.points);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
static fixMissingRouteDistances(points) {
|
|
57
63
|
let routeDistance = 0;
|
|
58
64
|
points.forEach((p) => {
|
|
59
65
|
if (!p.routeDistance)
|
|
@@ -65,11 +71,7 @@ class IncyclistRoutesApi {
|
|
|
65
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
72
|
try {
|
|
67
73
|
const res = yield this._get(`/${routeId}`);
|
|
68
|
-
|
|
69
|
-
res.data.points = res.data['decoded'];
|
|
70
|
-
delete res.data['decoded'];
|
|
71
|
-
this.fixMissingRouteDistances(res.data.points);
|
|
72
|
-
}
|
|
74
|
+
IncyclistRoutesApi.verify(res.data);
|
|
73
75
|
return res.data;
|
|
74
76
|
}
|
|
75
77
|
catch (err) {
|
|
@@ -25,6 +25,23 @@ export type RouteApiDescription = {
|
|
|
25
25
|
type?: RouteType;
|
|
26
26
|
localizedTitle?: LocalizedText;
|
|
27
27
|
};
|
|
28
|
+
export type LegacyRouteGpxRepoDescription = {
|
|
29
|
+
id: string;
|
|
30
|
+
hash?: string;
|
|
31
|
+
routeHash?: string;
|
|
32
|
+
title: string;
|
|
33
|
+
private?: boolean;
|
|
34
|
+
distance?: number;
|
|
35
|
+
elevation?: number;
|
|
36
|
+
author?: {
|
|
37
|
+
id: string;
|
|
38
|
+
};
|
|
39
|
+
points?: {
|
|
40
|
+
id: string;
|
|
41
|
+
};
|
|
42
|
+
__v: number;
|
|
43
|
+
category?: RouteCategory;
|
|
44
|
+
};
|
|
28
45
|
export type RouteApiDetail = {
|
|
29
46
|
id: string;
|
|
30
47
|
routeId?: string;
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import { Page,
|
|
1
|
+
import { Page, InternalRouteListState, List, RouteInfo, Route, RouteListEntry, RouteListStartProps, RouteListData, RouteStartSettings, onRouteStatusUpdateCallback, onCarouselStateChangedCallback } 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";
|
|
5
|
+
import { IJsonRepositoryBinding, JsonRepository } from "../../api";
|
|
5
6
|
type filterFn = (route: Route, idx: number, obj: Route[]) => boolean;
|
|
6
7
|
export declare class RouteListService extends IncyclistService {
|
|
7
8
|
protected static _instance: any;
|
|
8
|
-
static getInstance(binding?:
|
|
9
|
+
static getInstance(binding?: IJsonRepositoryBinding): RouteListService;
|
|
9
10
|
protected baseDir: string;
|
|
10
11
|
protected state: InternalRouteListState;
|
|
11
|
-
protected binding: IRouteListBinding;
|
|
12
12
|
protected routes: Array<RouteListEntry>;
|
|
13
|
+
protected videosRepo: JsonRepository;
|
|
14
|
+
protected routesRepo: JsonRepository;
|
|
13
15
|
protected api: IncyclistRoutesApi;
|
|
14
|
-
constructor(binding?:
|
|
15
|
-
setBinding(binding:
|
|
16
|
+
constructor(binding?: IJsonRepositoryBinding);
|
|
17
|
+
setBinding(binding: IJsonRepositoryBinding): void;
|
|
18
|
+
protected getVideosRepo(): JsonRepository;
|
|
19
|
+
protected getRoutesRepo(): JsonRepository;
|
|
16
20
|
preload(carouselSize?: number): Promise<void>;
|
|
17
21
|
protected _preload(carouselSize?: number, detailsOnly?: boolean): Promise<void>;
|
|
22
|
+
protected preloadList(list: List, carouselSize?: number, detailsOnly?: boolean): Promise<void>;
|
|
18
23
|
load(props: {
|
|
19
24
|
list?: List;
|
|
20
25
|
loadFrom?: number;
|
|
@@ -22,9 +27,12 @@ export declare class RouteListService extends IncyclistService {
|
|
|
22
27
|
routeId?: string;
|
|
23
28
|
}): Promise<void>;
|
|
24
29
|
openRouteSelection(pageId: string, props: RouteListStartProps): RouteListData;
|
|
25
|
-
closeRouteSelection(
|
|
30
|
+
closeRouteSelection(pageId: string): void;
|
|
26
31
|
openStartSettings(r: RouteInfo | string): RouteStartSettings;
|
|
27
32
|
cancelStartSettings(r: RouteInfo | string): {};
|
|
33
|
+
setCardUpdateHandler(pageId: string, r: RouteInfo | string, list: List, idx: number, onRouteStateChanged: onRouteStatusUpdateCallback, onCarouselStateChanged: onCarouselStateChangedCallback): void;
|
|
34
|
+
onCarouselInitialized(pageId: string, list: List, startIdx: number, visibleSize: number): void;
|
|
35
|
+
onCarouselUpdated(pageId: string, list: List, startIdx: number, visibleSize: number): void;
|
|
28
36
|
acceptStartSettings(r: RouteInfo | string, startSettings: RouteStartSettings): {};
|
|
29
37
|
getSelectedRoute(): RouteApiDetail;
|
|
30
38
|
getStartSettings(routeId?: string): RouteStartSettings;
|
|
@@ -54,13 +62,18 @@ export declare class RouteListService extends IncyclistService {
|
|
|
54
62
|
protected getRouteDescription(list: List, id: string): RouteInfo;
|
|
55
63
|
protected mergeDescription(local: RouteInfo, fromApi: RouteInfo): void;
|
|
56
64
|
protected mergeWithDetails(route: Route): void;
|
|
57
|
-
protected convertDescription(descr: RouteApiDescription): RouteInfo;
|
|
65
|
+
protected convertDescription(descr: RouteApiDescription, isLocal?: boolean): RouteInfo;
|
|
58
66
|
protected getListFromApiDesciption(description: RouteApiDescription): "selected" | "myRoutes" | "alternatives";
|
|
59
67
|
protected addRouteToList(list: List, route: Route): void;
|
|
60
68
|
protected getRouteList(list: List): Array<Route>;
|
|
69
|
+
protected getRouteLists(): Array<{
|
|
70
|
+
list: List;
|
|
71
|
+
title: string;
|
|
72
|
+
}>;
|
|
61
73
|
protected getRoute(criteria: string | filterFn): Route;
|
|
62
74
|
protected stopAllRides(): void;
|
|
63
|
-
protected
|
|
75
|
+
protected addDescriptionsFromRepo(descriptions: Array<RouteApiDescription>, repo?: JsonRepository): void;
|
|
76
|
+
protected addDescriptionsFromServer(descriptions: Array<RouteApiDescription>): void;
|
|
64
77
|
protected updateRouteTitle(data: RouteInfo, route: {
|
|
65
78
|
descr?: RouteApiDescription;
|
|
66
79
|
}): void;
|
|
@@ -69,9 +82,12 @@ export declare class RouteListService extends IncyclistService {
|
|
|
69
82
|
}): void;
|
|
70
83
|
protected getCountryPrefix(title?: string): string | undefined;
|
|
71
84
|
protected removeCountryPrefix(title?: string): string;
|
|
85
|
+
protected loadRouteDescriptionsFromRepo(): Promise<void>;
|
|
86
|
+
protected loadRouteDescriptionsFromServer(): Promise<void>;
|
|
72
87
|
protected loadRouteDescriptions(): Promise<void>;
|
|
73
88
|
protected loadRouteDetais(route: Route): Promise<void>;
|
|
74
89
|
protected emitRouteUpdated(route: Route): void;
|
|
90
|
+
protected getListState(page: Page, list: List): import("./types").RouteListDateEntry;
|
|
75
91
|
private getRouteFromStartProps;
|
|
76
92
|
}
|
|
77
93
|
export declare const useRouteList: () => RouteListService;
|
|
@@ -18,6 +18,8 @@ const localization_1 = require("../base/utils/localization");
|
|
|
18
18
|
const service_1 = require("../../base/service");
|
|
19
19
|
const route_1 = require("../base/utils/route");
|
|
20
20
|
const settings_1 = require("../../settings");
|
|
21
|
+
const api_2 = require("../../api");
|
|
22
|
+
const clone_1 = __importDefault(require("../../utils/clone"));
|
|
21
23
|
class RouteListService extends service_1.IncyclistService {
|
|
22
24
|
static getInstance(binding) {
|
|
23
25
|
if (!RouteListService._instance)
|
|
@@ -30,20 +32,33 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
30
32
|
initialized: false,
|
|
31
33
|
pages: []
|
|
32
34
|
};
|
|
33
|
-
|
|
35
|
+
if (binding)
|
|
36
|
+
api_2.JsonRepository.setBinding(binding);
|
|
34
37
|
this.api = api_1.default.getInstance();
|
|
35
38
|
this.initRouteLists();
|
|
36
39
|
}
|
|
37
40
|
setBinding(binding) {
|
|
38
41
|
if (!binding)
|
|
39
42
|
return;
|
|
40
|
-
|
|
43
|
+
api_2.JsonRepository.setBinding(binding);
|
|
41
44
|
this.state.initialized = true;
|
|
42
45
|
}
|
|
46
|
+
getVideosRepo() {
|
|
47
|
+
if (this.videosRepo)
|
|
48
|
+
return this.videosRepo;
|
|
49
|
+
this.videosRepo = api_2.JsonRepository.create('videos');
|
|
50
|
+
return this.videosRepo;
|
|
51
|
+
}
|
|
52
|
+
getRoutesRepo() {
|
|
53
|
+
if (this.routesRepo)
|
|
54
|
+
return this.routesRepo;
|
|
55
|
+
this.routesRepo = api_2.JsonRepository.create('routes');
|
|
56
|
+
return this.routesRepo;
|
|
57
|
+
}
|
|
43
58
|
preload(carouselSize = 5) {
|
|
44
59
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
60
|
if (this.state.loading)
|
|
46
|
-
|
|
61
|
+
return;
|
|
47
62
|
const promise = this._preload(carouselSize);
|
|
48
63
|
this.state.loading = { promise };
|
|
49
64
|
yield promise;
|
|
@@ -52,17 +67,35 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
52
67
|
}
|
|
53
68
|
_preload(carouselSize = 5, detailsOnly = false) {
|
|
54
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
this.logEvent({ message: 'preloading routes --' });
|
|
56
70
|
if (!detailsOnly) {
|
|
57
71
|
yield this.loadRouteDescriptions();
|
|
58
72
|
}
|
|
73
|
+
this.emitPageUpdate();
|
|
59
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();
|
|
60
88
|
this.routes.forEach(rle => {
|
|
61
89
|
var _a;
|
|
62
90
|
if (((_a = rle.routes) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
63
91
|
this.sort(rle.routes);
|
|
64
|
-
|
|
65
|
-
|
|
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)) {
|
|
66
99
|
const loader = this.loadRouteDetais(r);
|
|
67
100
|
promises.push(loader);
|
|
68
101
|
}
|
|
@@ -97,20 +130,23 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
97
130
|
}
|
|
98
131
|
openRouteSelection(pageId, props) {
|
|
99
132
|
const { language, visibleCards, visibleLists } = props;
|
|
100
|
-
this.logEvent({ message: '
|
|
133
|
+
this.logEvent({ message: 'openRouteSelection', pageId, language, visibleCards, visibleLists });
|
|
101
134
|
const existing = this.getPage(pageId);
|
|
102
135
|
if (existing) {
|
|
103
136
|
this.closeRouteSelection(pageId);
|
|
104
137
|
}
|
|
105
138
|
this.stopAllRides();
|
|
139
|
+
const page = this.registerPage(pageId, props);
|
|
106
140
|
if (props.visibleCards) {
|
|
107
|
-
this.
|
|
141
|
+
this.preload(props.visibleCards);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.preload(5);
|
|
108
145
|
}
|
|
109
|
-
const page = this.registerPage(pageId, props);
|
|
110
146
|
return page.state;
|
|
111
147
|
}
|
|
112
|
-
closeRouteSelection(
|
|
113
|
-
const idx = this.getPage(
|
|
148
|
+
closeRouteSelection(pageId) {
|
|
149
|
+
const idx = this.getPage(pageId, true);
|
|
114
150
|
if (idx !== -1) {
|
|
115
151
|
this.state.pages.splice(idx, 1);
|
|
116
152
|
}
|
|
@@ -146,6 +182,60 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
146
182
|
return {};
|
|
147
183
|
}
|
|
148
184
|
}
|
|
185
|
+
setCardUpdateHandler(pageId, r, list, idx, onRouteStateChanged, onCarouselStateChanged) {
|
|
186
|
+
const route = this.getRouteFromStartProps(r);
|
|
187
|
+
const page = this.getPage(pageId);
|
|
188
|
+
if (!page)
|
|
189
|
+
return;
|
|
190
|
+
page.onRouteUpdate[route.id] = { idx, onRouteStateChanged };
|
|
191
|
+
page.onCarouselStateChanged[route.id] = { idx, onCarouselStateChanged };
|
|
192
|
+
}
|
|
193
|
+
onCarouselInitialized(pageId, list, startIdx, visibleSize) {
|
|
194
|
+
const page = this.getPage(pageId);
|
|
195
|
+
console.log('~~~ DEBUG:onCarouselInitialied', pageId, list, this.getListState(page, list), startIdx, visibleSize);
|
|
196
|
+
if (!page)
|
|
197
|
+
return;
|
|
198
|
+
const listState = this.getListState(page, list);
|
|
199
|
+
if (listState) {
|
|
200
|
+
listState.startIdx = startIdx;
|
|
201
|
+
listState.endIdx = startIdx + visibleSize - 1;
|
|
202
|
+
}
|
|
203
|
+
const routes = this.getRouteList(list);
|
|
204
|
+
routes.forEach((route) => {
|
|
205
|
+
const { idx, onCarouselStateChanged } = page.onCarouselStateChanged[route.id] || {};
|
|
206
|
+
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
|
+
if (onCarouselStateChanged)
|
|
210
|
+
onCarouselStateChanged({ initialized: true, visible });
|
|
211
|
+
if (visible && (route.data.state === 'prepared' || route.data.state === 'error')) {
|
|
212
|
+
this.loadRouteDetais(route);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
onCarouselUpdated(pageId, list, startIdx, visibleSize) {
|
|
217
|
+
const page = this.getPage(pageId);
|
|
218
|
+
console.log('~~~ DEBUG:onCarouselUpdated', pageId, list, this.getListState(page, list), startIdx, visibleSize);
|
|
219
|
+
if (!page)
|
|
220
|
+
return;
|
|
221
|
+
const listState = this.getListState(page, list);
|
|
222
|
+
if (listState) {
|
|
223
|
+
listState.startIdx = startIdx;
|
|
224
|
+
listState.endIdx = startIdx + visibleSize - 1;
|
|
225
|
+
}
|
|
226
|
+
const routes = this.getRouteList(list);
|
|
227
|
+
routes.forEach((route) => {
|
|
228
|
+
const { idx, onCarouselStateChanged } = page.onCarouselStateChanged[route.id] || {};
|
|
229
|
+
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
|
+
if (onCarouselStateChanged)
|
|
233
|
+
onCarouselStateChanged({ initialized: true, visible });
|
|
234
|
+
if (visible && route.data.state === 'prepared' || route.data.state === 'error') {
|
|
235
|
+
this.loadRouteDetais(route);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
149
239
|
acceptStartSettings(r, startSettings) {
|
|
150
240
|
var _a;
|
|
151
241
|
const route = this.getRouteFromStartProps(r);
|
|
@@ -240,8 +330,8 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
240
330
|
}
|
|
241
331
|
emitPageUpdate() {
|
|
242
332
|
this.state.pages.forEach(p => {
|
|
243
|
-
|
|
244
|
-
p.onStatusUpdate(state);
|
|
333
|
+
p.state = this.getPageState(p.id);
|
|
334
|
+
p.onStatusUpdate(p.state);
|
|
245
335
|
});
|
|
246
336
|
}
|
|
247
337
|
initRouteLists() {
|
|
@@ -269,7 +359,7 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
269
359
|
registerPage(pageId, props) {
|
|
270
360
|
const { onStatusUpdate, language = 'en' } = props;
|
|
271
361
|
const state = this.getPageState(pageId, language);
|
|
272
|
-
const page = { id: pageId, onStatusUpdate, language, state };
|
|
362
|
+
const page = { id: pageId, onStatusUpdate, onRouteUpdate: {}, onCarouselStateChanged: {}, language, state };
|
|
273
363
|
this.state.pages.push(page);
|
|
274
364
|
return page;
|
|
275
365
|
}
|
|
@@ -342,11 +432,12 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
342
432
|
}
|
|
343
433
|
route.data = local;
|
|
344
434
|
}
|
|
345
|
-
convertDescription(descr) {
|
|
435
|
+
convertDescription(descr, isLocal) {
|
|
346
436
|
const { id, title, localizedTitle, country, distance, elevation, category, provider, video, points } = descr;
|
|
347
437
|
const data = { state: 'prepared', id, title, localizedTitle, country, distance, elevation, provider, category };
|
|
348
438
|
data.hasVideo = false;
|
|
349
439
|
data.hasGpx = false;
|
|
440
|
+
data.isLocal = isLocal || false;
|
|
350
441
|
this.updateRouteCountry(data, { descr });
|
|
351
442
|
this.updateRouteTitle(data, { descr });
|
|
352
443
|
if (points)
|
|
@@ -366,10 +457,15 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
366
457
|
var _a;
|
|
367
458
|
let list;
|
|
368
459
|
if (description.type === 'gpx') {
|
|
369
|
-
|
|
460
|
+
if (description.category === 'personal')
|
|
461
|
+
return 'myRoutes';
|
|
462
|
+
list = description.category ? 'alternatives' : 'selected';
|
|
463
|
+
console.log('~~~ DEBUG', description.title, description.private, list);
|
|
370
464
|
return list;
|
|
371
465
|
}
|
|
372
466
|
if (description.type === 'video') {
|
|
467
|
+
if (description.category === undefined || description.category === 'personal')
|
|
468
|
+
return 'myRoutes';
|
|
373
469
|
if ((_a = description.video) === null || _a === void 0 ? void 0 : _a.url) {
|
|
374
470
|
return 'selected';
|
|
375
471
|
}
|
|
@@ -384,6 +480,14 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
384
480
|
var _a;
|
|
385
481
|
return (_a = this.routes.find(rle => rle.list === list)) === null || _a === void 0 ? void 0 : _a.routes;
|
|
386
482
|
}
|
|
483
|
+
getRouteLists() {
|
|
484
|
+
const lists = [
|
|
485
|
+
{ list: 'myRoutes', title: 'My Routes' },
|
|
486
|
+
{ list: 'selected', title: 'Selected For Me' },
|
|
487
|
+
{ list: 'alternatives', title: 'Alternatives' }
|
|
488
|
+
];
|
|
489
|
+
return lists;
|
|
490
|
+
}
|
|
387
491
|
getRoute(criteria) {
|
|
388
492
|
let compareFn = criteria;
|
|
389
493
|
if (typeof criteria === 'string')
|
|
@@ -401,9 +505,38 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
401
505
|
lists[i].routes.forEach(r => r.startState = 'idle');
|
|
402
506
|
}
|
|
403
507
|
}
|
|
404
|
-
|
|
508
|
+
addDescriptionsFromRepo(descriptions, repo) {
|
|
509
|
+
const routes = descriptions;
|
|
510
|
+
if (repo) {
|
|
511
|
+
const type = repo.getName() === 'videos' ? 'video' : 'gpx';
|
|
512
|
+
routes.forEach(r => {
|
|
513
|
+
r.type = type;
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
const converted = routes
|
|
517
|
+
.map(this.convertDescription.bind(this));
|
|
518
|
+
converted.forEach((data, idx) => {
|
|
519
|
+
const list = this.getListFromApiDesciption(descriptions[idx]);
|
|
520
|
+
const existing = this.getRouteDescription(list, data.id);
|
|
521
|
+
if (existing) {
|
|
522
|
+
this.mergeDescription(existing, data);
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
data.state = 'prepared';
|
|
526
|
+
data.isLocal = true;
|
|
527
|
+
const item = { id: data.id, data };
|
|
528
|
+
this.addRouteToList(list, item);
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
addDescriptionsFromServer(descriptions) {
|
|
405
533
|
const converted = descriptions.map(this.convertDescription.bind(this));
|
|
406
534
|
converted.forEach((data, idx) => {
|
|
535
|
+
console.log('~~~ DEBUG:add route from Server', data.title);
|
|
536
|
+
const existing = this.getRoute(data.id);
|
|
537
|
+
if (existing) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
407
540
|
const list = this.getListFromApiDesciption(descriptions[idx]);
|
|
408
541
|
if (!list) {
|
|
409
542
|
this.logEvent({ message: 'Error', error: 'no list found for route', id: data.id, title: data.title });
|
|
@@ -415,8 +548,10 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
415
548
|
}
|
|
416
549
|
else {
|
|
417
550
|
data.state = 'prepared';
|
|
551
|
+
data.isLocal = false;
|
|
418
552
|
const item = { id: data.id, data };
|
|
419
553
|
this.addRouteToList(list, item);
|
|
554
|
+
this.emitPageUpdate();
|
|
420
555
|
}
|
|
421
556
|
});
|
|
422
557
|
}
|
|
@@ -457,39 +592,104 @@ class RouteListService extends service_1.IncyclistService {
|
|
|
457
592
|
return title.substring(3);
|
|
458
593
|
}
|
|
459
594
|
}
|
|
460
|
-
|
|
595
|
+
loadRouteDescriptionsFromRepo() {
|
|
596
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
597
|
+
console.log('~~~ DEBUG:loadRouteDescriptionsFromRepo');
|
|
598
|
+
const enrichRepo = (v, type) => {
|
|
599
|
+
const data = v;
|
|
600
|
+
return Object.assign({ type }, data);
|
|
601
|
+
};
|
|
602
|
+
const videos = ((yield this.getVideosRepo().read('routes')) || []);
|
|
603
|
+
console.log('~~~ DEBUG,videos:', videos);
|
|
604
|
+
this.addDescriptionsFromRepo(videos, this.getVideosRepo());
|
|
605
|
+
const routes = ((yield this.getRoutesRepo().read('routes')) || []);
|
|
606
|
+
console.log('~~~ DEBUG,routes:', routes);
|
|
607
|
+
this.addDescriptionsFromRepo(routes, this.getVideosRepo());
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
loadRouteDescriptionsFromServer() {
|
|
461
611
|
return __awaiter(this, void 0, void 0, function* () {
|
|
462
|
-
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
this.api.getRouteDescriptions({ type: '
|
|
612
|
+
console.log('~~~ DEBUG:loadRouteDescriptionsFromServer');
|
|
613
|
+
const enrichApi = (v, type) => (Object.assign({ type }, v));
|
|
614
|
+
const api = [
|
|
615
|
+
this.api.getRouteDescriptions({ type: 'gpx' }).then(v => v.map(e => enrichApi(e, 'gpx'))),
|
|
616
|
+
this.api.getRouteDescriptions({ type: 'video' }).then(v => v.map(e => enrichApi(e, 'video')))
|
|
466
617
|
];
|
|
467
|
-
const res = yield Promise.allSettled(
|
|
618
|
+
const res = yield Promise.allSettled(api);
|
|
619
|
+
console.log('~~~ DEBUG:loadRouteDescriptionsFromServer done', (new Date()).toISOString(), res);
|
|
620
|
+
this.emitPageUpdate();
|
|
468
621
|
res.forEach(p => {
|
|
469
622
|
if (p.status === 'fulfilled') {
|
|
470
|
-
this.
|
|
623
|
+
this.addDescriptionsFromServer(p.value);
|
|
471
624
|
}
|
|
472
625
|
});
|
|
473
626
|
});
|
|
474
627
|
}
|
|
628
|
+
loadRouteDescriptions() {
|
|
629
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
yield this.loadRouteDescriptionsFromRepo();
|
|
631
|
+
console.log('~~~ DEBUG, routes after Repo', this.routes);
|
|
632
|
+
this.emitPageUpdate();
|
|
633
|
+
this.loadRouteDescriptionsFromServer().then(() => {
|
|
634
|
+
console.log('~~~ DEBUG, routes after API', this.routes);
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
}
|
|
475
638
|
loadRouteDetais(route) {
|
|
476
639
|
return __awaiter(this, void 0, void 0, function* () {
|
|
640
|
+
console.log('~~~ DEBUG:loadDetails()', (0, clone_1.default)(route.data));
|
|
477
641
|
if (route.data.state === 'loaded')
|
|
478
642
|
return;
|
|
479
643
|
try {
|
|
480
644
|
route.data.state = 'loading';
|
|
481
|
-
|
|
645
|
+
this.emitRouteUpdated(route);
|
|
646
|
+
if (route.data.isLocal) {
|
|
647
|
+
route.details = route.data.hasVideo ?
|
|
648
|
+
yield this.videosRepo.read(route.id)
|
|
649
|
+
:
|
|
650
|
+
yield this.routesRepo.read(route.id);
|
|
651
|
+
api_1.default.verify(route.details);
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
route.details = yield this.api.getRouteDetails(route.id);
|
|
655
|
+
}
|
|
656
|
+
if (route.data.title === 'Arnbach')
|
|
657
|
+
console.log('~~~ DEBUG: loaded details', route.details);
|
|
658
|
+
if (route.details.id !== route.data.id) {
|
|
659
|
+
route.data.state = 'error';
|
|
660
|
+
delete route.details;
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
482
663
|
this.mergeWithDetails(route);
|
|
483
|
-
route.data.state = '
|
|
664
|
+
route.data.state = 'loaded';
|
|
484
665
|
this.emitRouteUpdated(route);
|
|
485
666
|
}
|
|
486
667
|
catch (e) {
|
|
668
|
+
console.log('~~~ DEBUG:Error', e);
|
|
487
669
|
route.data.state = 'error';
|
|
670
|
+
this.emitRouteUpdated(route);
|
|
488
671
|
}
|
|
489
672
|
});
|
|
490
673
|
}
|
|
491
674
|
emitRouteUpdated(route) {
|
|
492
675
|
this.emit('route-update', route.id, route.data);
|
|
676
|
+
this.state.pages.forEach(page => {
|
|
677
|
+
try {
|
|
678
|
+
const { onRouteStateChanged } = page.onRouteUpdate[route.id] || {};
|
|
679
|
+
const { language } = page;
|
|
680
|
+
if (onRouteStateChanged) {
|
|
681
|
+
const data = (0, localization_1.getLocalizedData)(route.data, language);
|
|
682
|
+
onRouteStateChanged(data);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
catch (err) {
|
|
686
|
+
console.log('~~~ DEBUG:Error', err);
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
getListState(page, list) {
|
|
691
|
+
console.log('~~~ DEBUG.getListState', list, page === null || page === void 0 ? void 0 : page.state, this.state);
|
|
692
|
+
return page === null || page === void 0 ? void 0 : page.state.lists.find(pl => pl.list === list);
|
|
493
693
|
}
|
|
494
694
|
getRouteFromStartProps(r) {
|
|
495
695
|
try {
|
|
@@ -23,6 +23,7 @@ export type RouteInfo = {
|
|
|
23
23
|
elevation?: number;
|
|
24
24
|
category?: RouteCategory;
|
|
25
25
|
provider?: RouteProvider;
|
|
26
|
+
isLocal?: boolean;
|
|
26
27
|
hasGpx?: boolean;
|
|
27
28
|
hasVideo?: boolean;
|
|
28
29
|
isDemo?: boolean;
|
|
@@ -37,7 +38,14 @@ export type RouteListDateEntry = {
|
|
|
37
38
|
list: List;
|
|
38
39
|
listHeader: string;
|
|
39
40
|
routes: Array<RouteInfo>;
|
|
41
|
+
startIdx?: number;
|
|
42
|
+
endIdx?: number;
|
|
40
43
|
};
|
|
44
|
+
export type onRouteStatusUpdateCallback = (route: RouteInfo) => void;
|
|
45
|
+
export type onCarouselStateChangedCallback = (state: {
|
|
46
|
+
initialized: boolean;
|
|
47
|
+
visible: boolean;
|
|
48
|
+
}) => void;
|
|
41
49
|
export type RouteListData = {
|
|
42
50
|
pageId: string;
|
|
43
51
|
lists: Array<RouteListDateEntry>;
|
|
@@ -59,6 +67,18 @@ export type Page = {
|
|
|
59
67
|
settingsState?: RouteSettingsState;
|
|
60
68
|
language: string;
|
|
61
69
|
onStatusUpdate: RouteListStatusUpdateCallback;
|
|
70
|
+
onRouteUpdate: {
|
|
71
|
+
[index: string]: {
|
|
72
|
+
idx: number;
|
|
73
|
+
onRouteStateChanged: onRouteStatusUpdateCallback;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
onCarouselStateChanged: {
|
|
77
|
+
[index: string]: {
|
|
78
|
+
idx: number;
|
|
79
|
+
onCarouselStateChanged: onCarouselStateChangedCallback;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
62
82
|
};
|
|
63
83
|
export interface LoadingState {
|
|
64
84
|
promise: any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "incyclist-services",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.57",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"gd-eventlog": "^0.1.26"
|
|
6
6
|
},
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"axios": "^1.6.1",
|
|
42
|
-
"incyclist-devices": "^2.1.
|
|
42
|
+
"incyclist-devices": "^2.1.24",
|
|
43
43
|
"uuid": "^9.0.0"
|
|
44
44
|
}
|
|
45
45
|
}
|