incyclist-services 1.7.47 → 1.7.48
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/cjs/api/repository/json/index.js +33 -6
- package/lib/cjs/apps/service.js +1 -0
- package/lib/cjs/maps/MapArea/options.js +29 -22
- package/lib/cjs/maps/MapArea/service.js +28 -12
- package/lib/cjs/maps/MapArea/utils.js +8 -6
- package/lib/cjs/ride/page/service.js +26 -13
- package/lib/cjs/ride/route/GpxDisplayService.js +3 -2
- package/lib/cjs/ride/route/RouteDisplayService.js +23 -16
- package/lib/cjs/routes/list/cards/RouteCard.js +6 -7
- package/lib/cjs/services/overpass/overpass.js +7 -1
- package/lib/esm/api/repository/json/index.js +33 -6
- package/lib/esm/apps/service.js +1 -0
- package/lib/esm/maps/MapArea/options.js +29 -22
- package/lib/esm/maps/MapArea/service.js +29 -13
- package/lib/esm/maps/MapArea/utils.js +8 -6
- package/lib/esm/ride/page/service.js +26 -13
- package/lib/esm/ride/route/GpxDisplayService.js +3 -2
- package/lib/esm/ride/route/RouteDisplayService.js +24 -17
- package/lib/esm/routes/list/cards/RouteCard.js +6 -7
- package/lib/esm/services/overpass/overpass.js +7 -1
- package/lib/types/activities/ride/types.d.ts +16 -0
- package/lib/types/api/repository/json/index.d.ts +5 -4
- package/lib/types/i18n/units/converter.d.ts +2 -2
- package/lib/types/maps/MapArea/options.d.ts +2 -2
- package/lib/types/maps/MapArea/service.d.ts +10 -9
- package/lib/types/maps/MapArea/types.d.ts +2 -2
- package/lib/types/ride/base/types.d.ts +2 -2
- package/lib/types/ride/page/service.d.ts +6 -8
- package/lib/types/ride/route/GpxDisplayService.d.ts +8 -3
- package/lib/types/ride/route/RouteDisplayService.d.ts +19 -15
- package/lib/types/services/overpass/overpass.d.ts +7 -3
- package/package.json +7 -5
|
@@ -28,24 +28,45 @@ class JsonRepository {
|
|
|
28
28
|
}
|
|
29
29
|
async write(objectName, data) {
|
|
30
30
|
await this.open();
|
|
31
|
-
|
|
31
|
+
if (!this.access)
|
|
32
|
+
return false;
|
|
33
|
+
const success = await this.access.write(this.toFileName(objectName), data);
|
|
34
|
+
if (objectName.includes(':')) {
|
|
35
|
+
await this.access.delete(objectName).catch(() => { });
|
|
36
|
+
}
|
|
32
37
|
return success;
|
|
33
38
|
}
|
|
34
39
|
async read(objectName) {
|
|
35
40
|
await this.open();
|
|
36
|
-
|
|
41
|
+
if (!this.access)
|
|
42
|
+
return;
|
|
43
|
+
const fileName = this.toFileName(objectName);
|
|
44
|
+
let data;
|
|
45
|
+
try {
|
|
46
|
+
data = await this.access.read(fileName);
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
37
49
|
try {
|
|
50
|
+
if (!data && objectName.includes(':')) {
|
|
51
|
+
data = await this.access.read(objectName);
|
|
52
|
+
}
|
|
38
53
|
const str = JSON.stringify(data);
|
|
39
54
|
if (str === '{}' || str.length < 2)
|
|
40
|
-
return
|
|
55
|
+
return;
|
|
41
56
|
}
|
|
42
57
|
catch {
|
|
43
|
-
return
|
|
58
|
+
return;
|
|
44
59
|
}
|
|
45
60
|
return data;
|
|
46
61
|
}
|
|
47
62
|
async delete(objectName) {
|
|
48
|
-
|
|
63
|
+
await this.open();
|
|
64
|
+
if (!this.access)
|
|
65
|
+
return false;
|
|
66
|
+
const result = await this.access.delete(this.toFileName(objectName));
|
|
67
|
+
if (objectName.includes(':'))
|
|
68
|
+
await this.access.delete(objectName).catch(() => { });
|
|
69
|
+
return result;
|
|
49
70
|
}
|
|
50
71
|
async open() {
|
|
51
72
|
if (this.access)
|
|
@@ -68,6 +89,9 @@ class JsonRepository {
|
|
|
68
89
|
}
|
|
69
90
|
}
|
|
70
91
|
async list(exclude) {
|
|
92
|
+
await this.open();
|
|
93
|
+
if (!this.access)
|
|
94
|
+
return null;
|
|
71
95
|
try {
|
|
72
96
|
let names = await this.access.list();
|
|
73
97
|
if (!names)
|
|
@@ -87,8 +111,11 @@ class JsonRepository {
|
|
|
87
111
|
async close() {
|
|
88
112
|
const db = (0, bindings_1.getBindings)().db;
|
|
89
113
|
db.release(this.name);
|
|
90
|
-
this.access
|
|
114
|
+
delete this.access;
|
|
91
115
|
return true;
|
|
92
116
|
}
|
|
117
|
+
toFileName(objectName) {
|
|
118
|
+
return objectName.replaceAll(':', '_');
|
|
119
|
+
}
|
|
93
120
|
}
|
|
94
121
|
exports.JsonRepository = JsonRepository;
|
package/lib/cjs/apps/service.js
CHANGED
|
@@ -103,6 +103,7 @@ let AppsService = (() => {
|
|
|
103
103
|
return false;
|
|
104
104
|
const success = await entry.connection.connect(credentials);
|
|
105
105
|
this.emit('connected', app, success);
|
|
106
|
+
return success;
|
|
106
107
|
}
|
|
107
108
|
isConnected(app) {
|
|
108
109
|
const entry = this.serviceMap.find(e => e.key === app);
|
|
@@ -23,8 +23,8 @@ class OptionManager {
|
|
|
23
23
|
}
|
|
24
24
|
async getStartOptions(way, crossing) {
|
|
25
25
|
const options = [];
|
|
26
|
-
const parts = this.map
|
|
27
|
-
const { segments, points } = this.map
|
|
26
|
+
const parts = this.map?.splitAtCrossingPoint(way, crossing) ?? [];
|
|
27
|
+
const { segments = [], points = [] } = this.map?.buildSegmentInfo(way, parts) ?? {};
|
|
28
28
|
for (const segment of segments ?? []) {
|
|
29
29
|
try {
|
|
30
30
|
const path = segment.path;
|
|
@@ -82,7 +82,7 @@ class OptionManager {
|
|
|
82
82
|
}
|
|
83
83
|
const map = await this.service.load(location);
|
|
84
84
|
if (!map) {
|
|
85
|
-
if (!this.map)
|
|
85
|
+
if (!this.map?.isWithinBoundary(location))
|
|
86
86
|
return [];
|
|
87
87
|
}
|
|
88
88
|
else {
|
|
@@ -92,20 +92,21 @@ class OptionManager {
|
|
|
92
92
|
const remaining = this.getRemaining(way);
|
|
93
93
|
let options = [];
|
|
94
94
|
if (node !== undefined && remaining !== undefined) {
|
|
95
|
-
node.ways.forEach((wid) => {
|
|
95
|
+
(node.ways ?? []).forEach((wid) => {
|
|
96
96
|
if (wid === remaining.id) {
|
|
97
97
|
options.push(...this.getOptionsOnCurrentWay(node, remaining, options));
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
const w = this.getWay(wid);
|
|
101
|
-
|
|
101
|
+
if (w)
|
|
102
|
+
options.push(...this.checkOptionsOnDifferentWay(node, w, options));
|
|
102
103
|
}
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
106
|
options = (0, utils_1.removeDuplicatePaths)(options);
|
|
106
|
-
const currentDirection = this.map
|
|
107
|
+
const currentDirection = this.map?.getHeading(way, 'end') ?? 0;
|
|
107
108
|
options.forEach((option) => {
|
|
108
|
-
const direction = this.map
|
|
109
|
+
const direction = this.map?.getHeading(option, 'start') ?? 0;
|
|
109
110
|
option.direction = direction - currentDirection;
|
|
110
111
|
if (option.direction > 180)
|
|
111
112
|
option.direction = option.direction - 360;
|
|
@@ -151,7 +152,7 @@ class OptionManager {
|
|
|
151
152
|
}
|
|
152
153
|
checkOptionsOnDifferentWay(location, w, options) {
|
|
153
154
|
if (!w?.path || !location)
|
|
154
|
-
return;
|
|
155
|
+
return [];
|
|
155
156
|
let roundabout = (0, utils_1.isRoundabout)(w);
|
|
156
157
|
if (roundabout)
|
|
157
158
|
return this.getOptionsRoundabout(location, w, options);
|
|
@@ -167,22 +168,24 @@ class OptionManager {
|
|
|
167
168
|
return (0, utils_1.removeDuplicates)(options);
|
|
168
169
|
}
|
|
169
170
|
getOptionsFirstPoint(location, w, options) {
|
|
170
|
-
let result = this.map
|
|
171
|
+
let result = this.map?.splitAtFirstBranch(w);
|
|
171
172
|
let expand = false;
|
|
172
|
-
if (result
|
|
173
|
+
if (!result?.path)
|
|
174
|
+
return;
|
|
175
|
+
if (result.path?.length === w.path.length) {
|
|
173
176
|
const pLast = w.path[w.path.length - 1];
|
|
174
|
-
if (pLast.ways
|
|
177
|
+
if (pLast.ways?.length === 2) {
|
|
175
178
|
const wIdNext = pLast.ways.find(wid => wid !== w.id);
|
|
176
|
-
const wNext = this.getWay(wIdNext);
|
|
177
|
-
if (!(0, utils_1.isRoundabout)(wNext)) {
|
|
179
|
+
const wNext = wIdNext ? this.getWay(wIdNext) : undefined;
|
|
180
|
+
if (wNext && !(0, utils_1.isRoundabout)(wNext)) {
|
|
178
181
|
const pNextStart = wNext.path[0];
|
|
179
182
|
const pNextEnd = wNext.path[wNext.path.length - 1];
|
|
180
183
|
if (pNextStart.id === pLast.id) {
|
|
181
184
|
expand = true;
|
|
182
|
-
const segment = this.map
|
|
185
|
+
const segment = this.map?.splitAtFirstBranch(wNext);
|
|
183
186
|
const combined = {
|
|
184
|
-
id: segment
|
|
185
|
-
path: w.path.concat(segment.path.slice(1)),
|
|
187
|
+
id: segment?.wayId,
|
|
188
|
+
path: segment?.path ? w.path.concat(segment.path.slice(1)) : w.path,
|
|
186
189
|
map: this.map
|
|
187
190
|
};
|
|
188
191
|
options.push(combined);
|
|
@@ -191,10 +194,10 @@ class OptionManager {
|
|
|
191
194
|
const wReverse = this.getRemaining(wNext);
|
|
192
195
|
if (wReverse?.path) {
|
|
193
196
|
wReverse.path.reverse();
|
|
194
|
-
const segment = this.map
|
|
197
|
+
const segment = this.map?.splitAtFirstBranch(wNext);
|
|
195
198
|
const combined = {
|
|
196
|
-
id: segment
|
|
197
|
-
path: w.path.concat(segment.path.slice(1)),
|
|
199
|
+
id: segment?.wayId,
|
|
200
|
+
path: segment?.path ? w.path.concat(segment.path.slice(1)) : w.path,
|
|
198
201
|
map: this.map
|
|
199
202
|
};
|
|
200
203
|
options.push(combined);
|
|
@@ -302,7 +305,7 @@ class OptionManager {
|
|
|
302
305
|
}
|
|
303
306
|
if (props.id !== undefined) {
|
|
304
307
|
const map = props.map ?? this.map;
|
|
305
|
-
return (0, clone_1.default)(map.getWay(props.id));
|
|
308
|
+
return map ? (0, clone_1.default)(map.getWay(props.id)) : undefined;
|
|
306
309
|
}
|
|
307
310
|
}
|
|
308
311
|
getNode(props) {
|
|
@@ -381,6 +384,8 @@ class OptionManager {
|
|
|
381
384
|
if (way.path.length > 1) {
|
|
382
385
|
let prev = way.path[way.path.length - 2];
|
|
383
386
|
const w = this.getWay(way);
|
|
387
|
+
if (!w)
|
|
388
|
+
return [];
|
|
384
389
|
if (w.roundabout) {
|
|
385
390
|
let branches = (0, utils_1.splitAtPoint)(w, location);
|
|
386
391
|
branches.forEach(b => {
|
|
@@ -391,8 +396,10 @@ class OptionManager {
|
|
|
391
396
|
});
|
|
392
397
|
}
|
|
393
398
|
else if (w.path.length > 1) {
|
|
394
|
-
let result = this.map
|
|
395
|
-
|
|
399
|
+
let result = this.map?.splitAtFirstBranch(way);
|
|
400
|
+
if (result) {
|
|
401
|
+
options.push({ id: result.wayId, path: result.path ?? [], map: this.map });
|
|
402
|
+
}
|
|
396
403
|
}
|
|
397
404
|
}
|
|
398
405
|
}
|
|
@@ -92,8 +92,7 @@ let MapAreaService = (() => {
|
|
|
92
92
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
93
93
|
}
|
|
94
94
|
static consts = { DEFAULT_RADIUS: consts_1.DEFAULT_RADIUS, DEFAULT_MIN_WAYS: consts_1.DEFAULT_MIN_WAYS, DEFAULT_MAX_WAYS: consts_1.DEFAULT_MAX_WAYS, MAX_DISTANCE_FROM_PATH: consts_1.MAX_DISTANCE_FROM_PATH, GET_WAYS_IN_AREA: consts_1.GET_WAYS_IN_AREA };
|
|
95
|
-
|
|
96
|
-
loaded = 'unknown';
|
|
95
|
+
loaded = (__runInitializers(this, _instanceExtraInitializers), 'unknown');
|
|
97
96
|
observer;
|
|
98
97
|
current;
|
|
99
98
|
minWays;
|
|
@@ -103,6 +102,7 @@ let MapAreaService = (() => {
|
|
|
103
102
|
maps;
|
|
104
103
|
optionManager;
|
|
105
104
|
iv;
|
|
105
|
+
pending = new Map();
|
|
106
106
|
constructor() {
|
|
107
107
|
super('MapArea');
|
|
108
108
|
this.minWays = consts_1.DEFAULT_MIN_WAYS;
|
|
@@ -113,21 +113,33 @@ let MapAreaService = (() => {
|
|
|
113
113
|
}
|
|
114
114
|
async load(location) {
|
|
115
115
|
const map = await this.findBestMap(location);
|
|
116
|
-
if (map)
|
|
116
|
+
if (map)
|
|
117
117
|
return map;
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
const key = this.mapsKey(location);
|
|
119
|
+
if (this.pending.has(key))
|
|
120
|
+
return this.pending.get(key);
|
|
121
|
+
const promise = this.loadMap(location).finally(() => {
|
|
122
|
+
this.pending.delete(key);
|
|
123
|
+
});
|
|
124
|
+
this.pending.set(key, promise);
|
|
125
|
+
return promise;
|
|
120
126
|
}
|
|
121
127
|
getMap(location) {
|
|
122
128
|
const maps = this.getAllMaps() ?? [];
|
|
123
|
-
|
|
129
|
+
const area = maps.find(m => m.isWithinBoundary(location));
|
|
130
|
+
return area;
|
|
124
131
|
}
|
|
125
132
|
getOptionManager() {
|
|
126
133
|
this.optionManager = this.optionManager ?? new options_1.OptionManager(this);
|
|
127
134
|
return this.optionManager;
|
|
128
135
|
}
|
|
129
136
|
setFilter(filter) {
|
|
130
|
-
|
|
137
|
+
if (filter === null) {
|
|
138
|
+
this.filter = [];
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
this.filter = filter;
|
|
142
|
+
}
|
|
131
143
|
}
|
|
132
144
|
async findBestMap(location) {
|
|
133
145
|
if (!this.hasLocationCovered(location))
|
|
@@ -140,7 +152,7 @@ let MapAreaService = (() => {
|
|
|
140
152
|
if (records.length === 0)
|
|
141
153
|
break;
|
|
142
154
|
const record = records.pop();
|
|
143
|
-
const { map, radius } = record;
|
|
155
|
+
const { map, radius = consts_1.DEFAULT_RADIUS } = record ?? {};
|
|
144
156
|
if (!map)
|
|
145
157
|
continue;
|
|
146
158
|
const dist = (0, geo_1.distanceBetween)(location, map.getQueryLocation());
|
|
@@ -175,9 +187,9 @@ let MapAreaService = (() => {
|
|
|
175
187
|
}
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
|
-
catch (
|
|
190
|
+
catch (err) {
|
|
179
191
|
const duration = ts ? Date.now() - ts : undefined;
|
|
180
|
-
this.logEvent({ message: 'overpass query result', status: 'failure', error: { code:
|
|
192
|
+
this.logEvent({ message: 'overpass query result', status: 'failure', error: { code: err.code, response: err.response }, duration });
|
|
181
193
|
}
|
|
182
194
|
await (0, sleep_1.sleep)(1000);
|
|
183
195
|
}
|
|
@@ -251,6 +263,8 @@ let MapAreaService = (() => {
|
|
|
251
263
|
this.iv = undefined;
|
|
252
264
|
}
|
|
253
265
|
garbageCollection() {
|
|
266
|
+
if (!this.current)
|
|
267
|
+
return;
|
|
254
268
|
const tsLastUsed = (m) => m.map.getLastUsed() ?? m.lastUsed;
|
|
255
269
|
const now = Date.now();
|
|
256
270
|
const maps = Object.values(this.maps).filter(m => now - tsLastUsed(m) < 1000 * 60 * 5);
|
|
@@ -263,9 +277,11 @@ let MapAreaService = (() => {
|
|
|
263
277
|
}
|
|
264
278
|
this.logEvent({ message: 'Garbage collection done', cnt: Object.keys(this.maps).length, maps: Object.keys(this.maps).map(k => (0, exports.getMapsInfo)(this.maps, k)) });
|
|
265
279
|
}
|
|
280
|
+
get overpass() {
|
|
281
|
+
return this.getOverpassAPI();
|
|
282
|
+
}
|
|
266
283
|
getOverpassAPI() {
|
|
267
|
-
|
|
268
|
-
return this.overpass;
|
|
284
|
+
return (0, overpass_1.useOverpassApi)();
|
|
269
285
|
}
|
|
270
286
|
reset() {
|
|
271
287
|
this.stopGarbageCollection();
|
|
@@ -40,13 +40,15 @@ const geo_1 = require("../../utils/geo");
|
|
|
40
40
|
const math_1 = require("../../utils/math");
|
|
41
41
|
const consts_1 = require("./consts");
|
|
42
42
|
function addNode(node, nodesLookup, id, path) {
|
|
43
|
-
|
|
44
|
-
if (point !== undefined)
|
|
43
|
+
const point = nodesLookup[node];
|
|
44
|
+
if (point !== undefined) {
|
|
45
45
|
path.push(point);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
point.ways = point.ways ?? [];
|
|
47
|
+
let found = point.ways.find(e => (e.toString() === id.toString()));
|
|
48
|
+
if (!found) {
|
|
49
|
+
point.ways.push(id.toString());
|
|
50
|
+
}
|
|
51
|
+
}
|
|
50
52
|
}
|
|
51
53
|
function addWay(w, ways, waysLookup) {
|
|
52
54
|
if (waysLookup[w.id] !== undefined)
|
|
@@ -114,6 +114,7 @@ let RidePageService = (() => {
|
|
|
114
114
|
catch (err) {
|
|
115
115
|
this.logError(err, 'openPage');
|
|
116
116
|
}
|
|
117
|
+
return this.getPageObserver();
|
|
117
118
|
}
|
|
118
119
|
closePage() {
|
|
119
120
|
try {
|
|
@@ -128,7 +129,7 @@ let RidePageService = (() => {
|
|
|
128
129
|
this.logError(err, 'closePage');
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
|
-
pausePage() {
|
|
132
|
+
async pausePage() {
|
|
132
133
|
try {
|
|
133
134
|
this.backgroundTimer = setTimeout(() => {
|
|
134
135
|
this.getRideDisplay().pause('user');
|
|
@@ -141,7 +142,7 @@ let RidePageService = (() => {
|
|
|
141
142
|
this.logError(err, 'pausePage');
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
|
-
resumePage() {
|
|
145
|
+
async resumePage() {
|
|
145
146
|
try {
|
|
146
147
|
if (this.backgroundTimer) {
|
|
147
148
|
clearTimeout(this.backgroundTimer);
|
|
@@ -153,20 +154,28 @@ let RidePageService = (() => {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
getRideObserver() {
|
|
156
|
-
return this.rideObserver;
|
|
157
|
+
return this.rideObserver ?? null;
|
|
157
158
|
}
|
|
158
159
|
getPageDisplayProps() {
|
|
160
|
+
const startOverlayProps = this.getRideDisplay().getStartOverlayProps();
|
|
161
|
+
const noRideProps = {
|
|
162
|
+
rideState: 'Error',
|
|
163
|
+
startOverlayProps,
|
|
164
|
+
rideType: null,
|
|
165
|
+
menuProps: null,
|
|
166
|
+
startGateProps: null
|
|
167
|
+
};
|
|
159
168
|
try {
|
|
160
169
|
const rideType = this.getRideDisplay().getRideType();
|
|
161
170
|
switch (rideType) {
|
|
162
171
|
case 'Video': return this.getVideoRideDisplayProps();
|
|
163
172
|
case 'GPX': return this.getGPXRideDisplayProps();
|
|
164
173
|
default:
|
|
165
|
-
return
|
|
174
|
+
return noRideProps;
|
|
166
175
|
}
|
|
167
176
|
}
|
|
168
|
-
catch
|
|
169
|
-
return
|
|
177
|
+
catch {
|
|
178
|
+
return noRideProps;
|
|
170
179
|
}
|
|
171
180
|
}
|
|
172
181
|
onRefreshSecrets() {
|
|
@@ -240,12 +249,15 @@ let RidePageService = (() => {
|
|
|
240
249
|
this.logError(err, 'onIgnoreStart');
|
|
241
250
|
}
|
|
242
251
|
}
|
|
243
|
-
|
|
252
|
+
onCancelStart() {
|
|
244
253
|
try {
|
|
245
254
|
this.rideObserver?.stop();
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
255
|
+
this.getRideDisplay().cancelStart()
|
|
256
|
+
.then(() => {
|
|
257
|
+
this.moveToPreviousPage();
|
|
258
|
+
this.closePage();
|
|
259
|
+
})
|
|
260
|
+
.catch((err) => { this.logError(err, 'onCancelStart'); });
|
|
249
261
|
}
|
|
250
262
|
catch (err) {
|
|
251
263
|
this.logError(err, 'onCancelStart');
|
|
@@ -285,8 +297,8 @@ let RidePageService = (() => {
|
|
|
285
297
|
return displayProps;
|
|
286
298
|
}
|
|
287
299
|
async checkSecretValidity() {
|
|
288
|
-
if (this.getBindings().appInfo
|
|
289
|
-
const secretsStatus = this.getSecretBinding()
|
|
300
|
+
if (this.getBindings().appInfo?.getChannel() === 'mobile') {
|
|
301
|
+
const secretsStatus = this.getSecretBinding()?.getSecretsStatus?.();
|
|
290
302
|
if (secretsStatus === 'stale' || secretsStatus === 'missing' || secretsStatus === undefined) {
|
|
291
303
|
if (!this.getOnlineStatusMonitoring().onlineStatus)
|
|
292
304
|
this.showStartGate();
|
|
@@ -318,7 +330,7 @@ let RidePageService = (() => {
|
|
|
318
330
|
const events = Object.keys(this.eventHandler);
|
|
319
331
|
events.forEach(event => { this.rideObserver?.off(event, this.eventHandler[event]); });
|
|
320
332
|
}
|
|
321
|
-
onDisplayStateUpdate(state
|
|
333
|
+
onDisplayStateUpdate(state) {
|
|
322
334
|
switch (state) {
|
|
323
335
|
case 'Paused':
|
|
324
336
|
this.menuProps = { showResume: true };
|
|
@@ -342,6 +354,7 @@ let RidePageService = (() => {
|
|
|
342
354
|
catch (err) {
|
|
343
355
|
this.logError(err, 'get rideObserver');
|
|
344
356
|
}
|
|
357
|
+
return null;
|
|
345
358
|
}
|
|
346
359
|
get rideDisplayProps() {
|
|
347
360
|
return this.getRideDisplay().getDisplayProperties();
|
|
@@ -182,7 +182,7 @@ let GpxDisplayService = (() => {
|
|
|
182
182
|
}
|
|
183
183
|
this.emit('state-update');
|
|
184
184
|
}
|
|
185
|
-
onMapViewEvent(state,
|
|
185
|
+
onMapViewEvent(state, _error) {
|
|
186
186
|
if (state === 'Loaded') {
|
|
187
187
|
this.mapLoaded = true;
|
|
188
188
|
}
|
|
@@ -300,7 +300,8 @@ let GpxDisplayService = (() => {
|
|
|
300
300
|
}
|
|
301
301
|
return val;
|
|
302
302
|
}
|
|
303
|
-
catch {
|
|
303
|
+
catch {
|
|
304
|
+
}
|
|
304
305
|
}
|
|
305
306
|
isMobile() {
|
|
306
307
|
return this.getBindings().appInfo?.getChannel() === 'mobile';
|
|
@@ -101,9 +101,9 @@ let RouteDisplayService = (() => {
|
|
|
101
101
|
return { realityFactor, startPos, route };
|
|
102
102
|
}
|
|
103
103
|
onActivityUpdate(activityPos, data) {
|
|
104
|
-
if (data.power > 0)
|
|
104
|
+
if ((data.power ?? 0) > 0)
|
|
105
105
|
this.prevPowerTs = Date.now();
|
|
106
|
-
if (data.power === 0 && (data.speed === 0 || data.speed < 5 && (Date.now() - (this.prevPowerTs ?? 0)) > MAX_INACTIVITY)) {
|
|
106
|
+
if (data.power === 0 && (data.speed === 0 || (data.speed ?? 0) < 5 && (Date.now() - (this.prevPowerTs ?? 0)) > MAX_INACTIVITY)) {
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
try {
|
|
@@ -130,7 +130,7 @@ let RouteDisplayService = (() => {
|
|
|
130
130
|
}
|
|
131
131
|
super.onActivityUpdate(activityPos, data);
|
|
132
132
|
}
|
|
133
|
-
onPositionUpdate(
|
|
133
|
+
onPositionUpdate(_state) {
|
|
134
134
|
}
|
|
135
135
|
onRideSettingsChanged(settings) {
|
|
136
136
|
try {
|
|
@@ -206,24 +206,26 @@ let RouteDisplayService = (() => {
|
|
|
206
206
|
const nearbyRides = this.getNearbyRidesProps(props);
|
|
207
207
|
const [C, U] = this.getUnitConversionShortcuts();
|
|
208
208
|
const isLoop = this.currentRoute?.description?.isLoop;
|
|
209
|
-
const xScale = { value: C(1, 'distance', U('distance')), unit: U('distance') };
|
|
210
|
-
const yScale = { value: C(1, 'elevation', U('elevation')), unit: U('elevation') };
|
|
209
|
+
const xScale = { value: C(1, 'distance', { from: U('distance') }), unit: U('distance') };
|
|
210
|
+
const yScale = { value: C(1, 'elevation', { from: U('elevation') }), unit: U('elevation') };
|
|
211
211
|
const mapStartPos = (isLoop && !loopOverwrite) ? undefined : startPos;
|
|
212
212
|
return {
|
|
213
213
|
...parent,
|
|
214
|
-
position: this.position,
|
|
214
|
+
position: this.position,
|
|
215
|
+
markers: this.getMarkers(props),
|
|
215
216
|
sideViews: this.sideViews,
|
|
216
217
|
route: this.getCurrentRoute(),
|
|
217
218
|
realityFactor,
|
|
218
|
-
startPos: mapStartPos
|
|
219
|
+
startPos: mapStartPos ?? 0,
|
|
220
|
+
endPos,
|
|
219
221
|
nearbyRides,
|
|
220
222
|
xScale, yScale,
|
|
221
223
|
map, upcomingElevation, totalElevation,
|
|
222
224
|
};
|
|
223
225
|
}
|
|
224
226
|
getScreenshotInfo(fileName, time) {
|
|
225
|
-
const { lat, lng, routeDistance, elevation } = this.position;
|
|
226
|
-
const position = { lat, lng, routeDistance, elevation };
|
|
227
|
+
const { lat, lng, routeDistance, elevation } = this.position ?? {};
|
|
228
|
+
const position = this.position === undefined ? undefined : { lat, lng, routeDistance, elevation };
|
|
227
229
|
return { fileName, position, time };
|
|
228
230
|
}
|
|
229
231
|
getRoutePosition(distance) {
|
|
@@ -237,8 +239,11 @@ let RouteDisplayService = (() => {
|
|
|
237
239
|
props = { cnt: 0 };
|
|
238
240
|
}
|
|
239
241
|
const pos = (0, routes_1.getPosition)(route, props);
|
|
242
|
+
const totalDistance = route.description?.distance;
|
|
243
|
+
if (!totalDistance)
|
|
244
|
+
return;
|
|
240
245
|
pos.distance = distance;
|
|
241
|
-
pos.lapDistance = pos.routeDistance %
|
|
246
|
+
pos.lapDistance = pos.routeDistance % totalDistance;
|
|
242
247
|
pos.heading = (0, routes_1.getHeading)(route, pos);
|
|
243
248
|
return pos;
|
|
244
249
|
}
|
|
@@ -340,7 +345,12 @@ let RouteDisplayService = (() => {
|
|
|
340
345
|
checkIsRouteFinished(position) {
|
|
341
346
|
if (this.isLoop() && !this.startSettings?.loopOverwrite)
|
|
342
347
|
return false;
|
|
343
|
-
|
|
348
|
+
if (this.startSettings.endPos !== undefined && position.routeDistance > this.startSettings.endPos)
|
|
349
|
+
return true;
|
|
350
|
+
const totalDistance = this.getCurrentRoute().description.distance;
|
|
351
|
+
if (totalDistance === undefined)
|
|
352
|
+
return false;
|
|
353
|
+
const finished = position.routeDistance >= totalDistance;
|
|
344
354
|
return finished;
|
|
345
355
|
}
|
|
346
356
|
onRideFinished() {
|
|
@@ -375,7 +385,7 @@ let RouteDisplayService = (() => {
|
|
|
375
385
|
this.logError(err, 'cleanupActiveRides');
|
|
376
386
|
}
|
|
377
387
|
}
|
|
378
|
-
savePosition(
|
|
388
|
+
savePosition(_startPos) {
|
|
379
389
|
}
|
|
380
390
|
getOriginalRoute() {
|
|
381
391
|
return this.route;
|
|
@@ -399,10 +409,7 @@ let RouteDisplayService = (() => {
|
|
|
399
409
|
return (0, api_1.getBindings)().appInfo;
|
|
400
410
|
}
|
|
401
411
|
getUnitConversionShortcuts() {
|
|
402
|
-
|
|
403
|
-
const C = c.convert.bind(c);
|
|
404
|
-
const U = c.getUnit.bind(c);
|
|
405
|
-
return [C, U];
|
|
412
|
+
return (0, i18n_1.getUnitConversionShortcuts)();
|
|
406
413
|
}
|
|
407
414
|
getUnitConverter() {
|
|
408
415
|
return (0, i18n_1.useUnitConverter)();
|
|
@@ -269,7 +269,7 @@ let RouteCard = (() => {
|
|
|
269
269
|
if (points && !Array.isArray(points)) {
|
|
270
270
|
points = undefined;
|
|
271
271
|
}
|
|
272
|
-
|
|
272
|
+
const isNew = (0, utils_2.checkIsNew)(descr);
|
|
273
273
|
const loaded = details !== undefined;
|
|
274
274
|
const loading = this.deleteObserver !== undefined;
|
|
275
275
|
const totalDistance = descr.distance === undefined ? undefined : {
|
|
@@ -405,12 +405,11 @@ let RouteCard = (() => {
|
|
|
405
405
|
value = p;
|
|
406
406
|
else {
|
|
407
407
|
const point = p;
|
|
408
|
-
value = C(point.routeDistance, 'distance');
|
|
408
|
+
value = C(point.routeDistance, 'distance') ?? 0;
|
|
409
409
|
}
|
|
410
|
-
console.log('# update start pos', p);
|
|
411
410
|
if (data?.startPos.value === value)
|
|
412
411
|
return null;
|
|
413
|
-
const startPos = { value, unit: U('distance') };
|
|
412
|
+
const startPos = { value, unit: U('distance') ?? 'm' };
|
|
414
413
|
const updated = { ...data };
|
|
415
414
|
updated.startPos = startPos;
|
|
416
415
|
this.adjustStartPosAvi(updated);
|
|
@@ -422,12 +421,12 @@ let RouteCard = (() => {
|
|
|
422
421
|
const [C, U] = (0, i18n_1.getUnitConversionShortcuts)();
|
|
423
422
|
const isUI = typeof props.startPos !== 'number';
|
|
424
423
|
try {
|
|
425
|
-
delete props
|
|
424
|
+
delete props.prevRides;
|
|
426
425
|
if (isUI) {
|
|
427
426
|
const uiProps = props;
|
|
428
427
|
const { realityFactor, segment, showPrev, loopOverwrite, nextOverwrite } = uiProps;
|
|
429
|
-
const startPos = C(uiProps.startPos.value, 'distance', { from: U('distance'), to: 'm' });
|
|
430
|
-
const endPos = uiProps.endPos === undefined ?
|
|
428
|
+
const startPos = C(uiProps.startPos.value, 'distance', { from: U('distance'), to: 'm' }) ?? 0;
|
|
429
|
+
const endPos = uiProps.endPos === undefined ? undefined : C(uiProps.endPos.value, 'distance', { from: U('distance'), to: 'm' });
|
|
431
430
|
this.startSettings = {
|
|
432
431
|
...this.startSettings,
|
|
433
432
|
startPos, endPos, realityFactor, segment, showPrev, loopOverwrite, nextOverwrite
|
|
@@ -42,6 +42,7 @@ const promise_any_1 = __importDefault(require("promise.any"));
|
|
|
42
42
|
const types_1 = require("../../base/types");
|
|
43
43
|
const sleep_1 = require("../../utils/sleep");
|
|
44
44
|
const base_1 = require("../../apps/base/api/base");
|
|
45
|
+
const gd_eventlog_1 = require("gd-eventlog");
|
|
45
46
|
const OVERPASS_URL_ALT1 = 'https://overpass.kumi.systems/api/interpreter';
|
|
46
47
|
const OVERPASS_URL_ALT2 = 'https://lz4.overpass-api.de/api/interpreter';
|
|
47
48
|
const OVERPASS_URL_ALT3 = 'https://z.overpass-api.de/api/interpreter';
|
|
@@ -63,10 +64,12 @@ let OverpassApi = (() => {
|
|
|
63
64
|
}
|
|
64
65
|
url;
|
|
65
66
|
mirrors = [];
|
|
67
|
+
logger;
|
|
66
68
|
constructor(props) {
|
|
67
69
|
super();
|
|
68
70
|
this.mirrors = [OVERPASS_URL_ALT1, OVERPASS_URL_ALT2, OVERPASS_URL_ALT3];
|
|
69
71
|
this.url = props?.url ?? this.mirrors[0];
|
|
72
|
+
this.logger = new gd_eventlog_1.EventLogger('Overpass');
|
|
70
73
|
if (props?.url) {
|
|
71
74
|
if (this.mirrors.indexOf(props.url) === -1) {
|
|
72
75
|
this.mirrors.push(props.url);
|
|
@@ -74,7 +77,10 @@ let OverpassApi = (() => {
|
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
async query(queryOL, timeout) {
|
|
77
|
-
|
|
80
|
+
this.logger.logEvent({ message: 'query', queryOL, timeout });
|
|
81
|
+
const res = await this.bulkQuery(queryOL, timeout);
|
|
82
|
+
this.logger.logEvent({ message: 'query result', hasData: res !== undefined });
|
|
83
|
+
return res;
|
|
78
84
|
}
|
|
79
85
|
async singleQuery(queryOL) {
|
|
80
86
|
const res = await this.post(this.url, queryOL);
|