incyclist-services 1.7.121 → 1.7.125
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/activities/active-rides/service.js +3 -2
- package/lib/cjs/activities/ride/service.js +2 -0
- package/lib/cjs/api/bindings/index.js +1 -0
- package/lib/cjs/api/mapAvailability/types.js +2 -0
- package/lib/cjs/devices/pairing/service.js +6 -4
- package/lib/cjs/ride/route/GpxDisplayService.js +45 -6
- package/lib/cjs/routes/list/cards/RouteCard.js +2 -0
- package/lib/cjs/settings/display/ride/service.js +19 -20
- package/lib/esm/activities/active-rides/service.js +3 -2
- package/lib/esm/activities/ride/service.js +2 -0
- package/lib/esm/api/bindings/index.js +1 -0
- package/lib/esm/api/mapAvailability/types.js +1 -0
- package/lib/esm/devices/pairing/service.js +6 -4
- package/lib/esm/ride/route/GpxDisplayService.js +45 -6
- package/lib/esm/routes/list/cards/RouteCard.js +2 -0
- package/lib/esm/settings/display/ride/service.js +19 -20
- package/lib/types/api/bindings/index.d.ts +2 -0
- package/lib/types/api/mapAvailability/types.d.ts +10 -0
- package/lib/types/ride/route/GpxDisplayService.d.ts +12 -4
- package/lib/types/settings/display/ride/service.d.ts +3 -5
- package/lib/types/settings/display/ride/types.d.ts +6 -1
- package/package.json +1 -1
|
@@ -356,15 +356,16 @@ let ActiveRidesService = (() => {
|
|
|
356
356
|
};
|
|
357
357
|
displayProps.push(displayItem);
|
|
358
358
|
});
|
|
359
|
+
const diffValue = (r) => r.diffDistance?.value ?? 0;
|
|
359
360
|
if (displayProps.length > this.maxLength) {
|
|
360
|
-
const absDiff = (r) => Math.abs(r
|
|
361
|
+
const absDiff = (r) => Math.abs(diffValue(r));
|
|
361
362
|
displayProps.sort((a, b) => {
|
|
362
363
|
return absDiff(b) > absDiff(a) ? -1 : 1;
|
|
363
364
|
});
|
|
364
365
|
return displayProps.filter((_r, idx) => idx < this.maxLength);
|
|
365
366
|
}
|
|
366
367
|
displayProps.sort((a, b) => {
|
|
367
|
-
return b
|
|
368
|
+
return diffValue(b) > diffValue(a) ? -1 : 1;
|
|
368
369
|
});
|
|
369
370
|
return displayProps;
|
|
370
371
|
}
|
|
@@ -428,6 +428,7 @@ let ActivityRideService = (() => {
|
|
|
428
428
|
const isFreeRide = startSettings?.type === 'Free-Ride';
|
|
429
429
|
const showWorkoutSummary = this.activity?.routeType === 'None';
|
|
430
430
|
const showSave = this.activity !== undefined && !this.isSaveDone;
|
|
431
|
+
const showDelete = this.activity !== undefined && !this.isSaveDone;
|
|
431
432
|
const showContinue = this.state !== 'completed';
|
|
432
433
|
const hasGPX = this.activity?.logs?.some((log) => !!log.lat && !!log.lng);
|
|
433
434
|
const showMap = hasGPX || isFreeRide || (route?.description?.hasGpx);
|
|
@@ -440,6 +441,7 @@ let ActivityRideService = (() => {
|
|
|
440
441
|
const props = {
|
|
441
442
|
activity: (0, utils_3.createUIActivityDetails)(this.activity),
|
|
442
443
|
showSave,
|
|
444
|
+
showDelete,
|
|
443
445
|
showContinue,
|
|
444
446
|
showMap,
|
|
445
447
|
showWorkoutSummary,
|
|
@@ -209,9 +209,6 @@ let DevicePairingService = (() => {
|
|
|
209
209
|
this.logEvent({ message: 'Stop Pairing (OK)', stillPairing, stillScanning });
|
|
210
210
|
try {
|
|
211
211
|
this.pauseAdapters(adapters.filter(a => !adapterFilter.includes(a.udid)));
|
|
212
|
-
if (this.isPairing()) {
|
|
213
|
-
this.removePairingCallbacks();
|
|
214
|
-
}
|
|
215
212
|
if (this.isScanning()) {
|
|
216
213
|
this.state.stopRequested = true;
|
|
217
214
|
await this._stop();
|
|
@@ -220,7 +217,9 @@ let DevicePairingService = (() => {
|
|
|
220
217
|
this.settings = {};
|
|
221
218
|
this.state.initialized = false;
|
|
222
219
|
this.state.waiting = false;
|
|
223
|
-
|
|
220
|
+
if (!stillPairing) {
|
|
221
|
+
this.state.check = null;
|
|
222
|
+
}
|
|
224
223
|
this.state.scan = null;
|
|
225
224
|
this.state.stopRequested = false;
|
|
226
225
|
this.state.stopped = true;
|
|
@@ -1011,6 +1010,9 @@ let DevicePairingService = (() => {
|
|
|
1011
1010
|
this.emit('pairing-done');
|
|
1012
1011
|
return;
|
|
1013
1012
|
}
|
|
1013
|
+
if (this.isPairing() && this.state.check?.promise !== undefined) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1014
1016
|
if (this.usage !== 'page' && this.isPairing()) {
|
|
1015
1017
|
return;
|
|
1016
1018
|
}
|
|
@@ -46,6 +46,7 @@ const SV_UPDATE_FREQ = 3000;
|
|
|
46
46
|
const SV_MIN_READY = 1500;
|
|
47
47
|
const SV_MIN_DELAY = 1000;
|
|
48
48
|
const SV_START_TIMEOUT = 15000;
|
|
49
|
+
const SAT_START_TIMEOUT = 15000;
|
|
49
50
|
let GpxDisplayService = (() => {
|
|
50
51
|
let _classSuper = RouteDisplayService_1.RouteDisplayService;
|
|
51
52
|
let _instanceExtraInitializers = [];
|
|
@@ -76,6 +77,8 @@ let GpxDisplayService = (() => {
|
|
|
76
77
|
updateDurations = [];
|
|
77
78
|
svStartTimedOut = false;
|
|
78
79
|
svStartTimeout;
|
|
80
|
+
satStartTimedOut = false;
|
|
81
|
+
satStartTimeout;
|
|
79
82
|
constructor() {
|
|
80
83
|
super();
|
|
81
84
|
}
|
|
@@ -90,6 +93,10 @@ let GpxDisplayService = (() => {
|
|
|
90
93
|
if (this.waitsForStreetView())
|
|
91
94
|
this.armStreetViewStartTimeout();
|
|
92
95
|
}
|
|
96
|
+
else if (rideView === 'sat') {
|
|
97
|
+
if (this.waitsForSatelliteView())
|
|
98
|
+
this.armSatelliteViewStartTimeout();
|
|
99
|
+
}
|
|
93
100
|
}
|
|
94
101
|
catch (err) {
|
|
95
102
|
this.logError(err, 'initView');
|
|
@@ -114,7 +121,12 @@ let GpxDisplayService = (() => {
|
|
|
114
121
|
return props;
|
|
115
122
|
}
|
|
116
123
|
getInitialStreetViewPosition() {
|
|
117
|
-
|
|
124
|
+
return this.enrichWithHeading(this.position, 'getInitialStreetViewPosition');
|
|
125
|
+
}
|
|
126
|
+
getSatelliteViewPosition() {
|
|
127
|
+
return this.enrichWithHeading(this.position, 'getSatelliteViewPosition');
|
|
128
|
+
}
|
|
129
|
+
enrichWithHeading(position, logContext) {
|
|
118
130
|
if (!position)
|
|
119
131
|
return undefined;
|
|
120
132
|
if (position.heading !== undefined)
|
|
@@ -123,17 +135,20 @@ let GpxDisplayService = (() => {
|
|
|
123
135
|
return { ...position, heading: (0, routes_1.getHeading)(this.getOriginalRoute(), position) };
|
|
124
136
|
}
|
|
125
137
|
catch (err) {
|
|
126
|
-
this.logError(err,
|
|
138
|
+
this.logError(err, logContext);
|
|
127
139
|
return position;
|
|
128
140
|
}
|
|
129
141
|
}
|
|
130
142
|
waitsForStreetView() {
|
|
131
143
|
return this.isMobile() && this.getRideSettingsDisplay().getRideView() === 'sv';
|
|
132
144
|
}
|
|
145
|
+
waitsForSatelliteView() {
|
|
146
|
+
return this.isMobile() && this.getRideSettingsDisplay().getRideView() === 'sat';
|
|
147
|
+
}
|
|
133
148
|
getSatelliteViewProps() {
|
|
134
149
|
return {
|
|
135
150
|
onDisplayEvent: this.onSatelliteViewEvent.bind(this),
|
|
136
|
-
displayPosition: this.
|
|
151
|
+
displayPosition: this.getSatelliteViewPosition()
|
|
137
152
|
};
|
|
138
153
|
}
|
|
139
154
|
getMapViewProps() {
|
|
@@ -145,7 +160,7 @@ let GpxDisplayService = (() => {
|
|
|
145
160
|
}
|
|
146
161
|
getStartOverlayProps() {
|
|
147
162
|
const rideView = this.getRideSettingsDisplay().getRideView();
|
|
148
|
-
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
|
|
163
|
+
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView() && !this.waitsForSatelliteView())) {
|
|
149
164
|
return {
|
|
150
165
|
mapType: this.getRideViewName(),
|
|
151
166
|
mapState: 'Loaded'
|
|
@@ -159,11 +174,11 @@ let GpxDisplayService = (() => {
|
|
|
159
174
|
}
|
|
160
175
|
isStartRideCompleted() {
|
|
161
176
|
const rideView = this.getRideSettingsDisplay().getRideView();
|
|
162
|
-
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
|
|
177
|
+
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView() && !this.waitsForSatelliteView())) {
|
|
163
178
|
this.mapLoaded = true;
|
|
164
179
|
return true;
|
|
165
180
|
}
|
|
166
|
-
if (this.svStartTimedOut)
|
|
181
|
+
if (this.svStartTimedOut || this.satStartTimedOut)
|
|
167
182
|
return true;
|
|
168
183
|
return this.mapLoaded;
|
|
169
184
|
}
|
|
@@ -199,6 +214,7 @@ let GpxDisplayService = (() => {
|
|
|
199
214
|
onSatelliteViewEvent(state, error) {
|
|
200
215
|
if (state === 'Loaded') {
|
|
201
216
|
this.mapLoaded = true;
|
|
217
|
+
this.clearSatelliteViewStartTimeout();
|
|
202
218
|
}
|
|
203
219
|
else if (state === 'Error') {
|
|
204
220
|
this.logEvent({ message: 'sat view error', error: this.mapError });
|
|
@@ -288,12 +304,35 @@ let GpxDisplayService = (() => {
|
|
|
288
304
|
getStreetViewStartTimeout() {
|
|
289
305
|
return this.getNumSetting('SV_START_TIMEOUT') ?? SV_START_TIMEOUT;
|
|
290
306
|
}
|
|
307
|
+
armSatelliteViewStartTimeout() {
|
|
308
|
+
this.clearSatelliteViewStartTimeout();
|
|
309
|
+
const timeout = this.getSatelliteViewStartTimeout();
|
|
310
|
+
this.satStartTimeout = setTimeout(() => {
|
|
311
|
+
this.satStartTimeout = undefined;
|
|
312
|
+
if (this.mapLoaded)
|
|
313
|
+
return;
|
|
314
|
+
this.satStartTimedOut = true;
|
|
315
|
+
this.logEvent({ message: 'satellite view start timeout', timeout });
|
|
316
|
+
this.emit('state-update');
|
|
317
|
+
}, timeout);
|
|
318
|
+
}
|
|
319
|
+
clearSatelliteViewStartTimeout() {
|
|
320
|
+
if (this.satStartTimeout) {
|
|
321
|
+
clearTimeout(this.satStartTimeout);
|
|
322
|
+
this.satStartTimeout = undefined;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
getSatelliteViewStartTimeout() {
|
|
326
|
+
return this.getNumSetting('SAT_START_TIMEOUT') ?? SAT_START_TIMEOUT;
|
|
327
|
+
}
|
|
291
328
|
onStarted() {
|
|
292
329
|
this.clearStreetViewStartTimeout();
|
|
330
|
+
this.clearSatelliteViewStartTimeout();
|
|
293
331
|
super.onStarted();
|
|
294
332
|
}
|
|
295
333
|
async stop() {
|
|
296
334
|
this.clearStreetViewStartTimeout();
|
|
335
|
+
this.clearSatelliteViewStartTimeout();
|
|
297
336
|
return super.stop();
|
|
298
337
|
}
|
|
299
338
|
getStreetViewObserver() {
|
|
@@ -40,6 +40,10 @@ const decorators_1 = require("../../../base/decorators");
|
|
|
40
40
|
const service_1 = require("../../../base/service");
|
|
41
41
|
const types_1 = require("../../../base/types");
|
|
42
42
|
const service_2 = require("../../service");
|
|
43
|
+
const UNAVAILABLE_MESSAGES = {
|
|
44
|
+
'need.playservices': 'Install Google Play Services to use this view',
|
|
45
|
+
};
|
|
46
|
+
const DEFAULT_UNAVAILABLE_MESSAGE = 'This view is currently unavailable on your device';
|
|
43
47
|
let RideSettingsDisplayService = (() => {
|
|
44
48
|
let _classDecorators = [decorators_1.Singleton];
|
|
45
49
|
let _classDescriptor;
|
|
@@ -83,8 +87,6 @@ let RideSettingsDisplayService = (() => {
|
|
|
83
87
|
};
|
|
84
88
|
}
|
|
85
89
|
setRideView(rideView) {
|
|
86
|
-
if (this.isRestricted())
|
|
87
|
-
return;
|
|
88
90
|
try {
|
|
89
91
|
this.getUserSettings().set('preferences.rideView', rideView);
|
|
90
92
|
}
|
|
@@ -97,29 +99,29 @@ let RideSettingsDisplayService = (() => {
|
|
|
97
99
|
this.observer.emit('changed', this.getDisplayProps());
|
|
98
100
|
}
|
|
99
101
|
getRideView() {
|
|
100
|
-
if (this.isRestricted())
|
|
101
|
-
return 'map';
|
|
102
102
|
const rideView = this.getUserSettings().get('preferences.rideView', 'sv');
|
|
103
|
+
const availability = this.getBindings().mapAvailability?.isAvailable(rideView);
|
|
104
|
+
if (availability?.status === 'unavailable' || availability?.status === 'not-supported')
|
|
105
|
+
return 'map';
|
|
103
106
|
return rideView;
|
|
104
107
|
}
|
|
105
108
|
getRideViewOptions() {
|
|
106
109
|
const map = new Map();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
map.set('sv', 'Street View');
|
|
112
|
-
map.set('map', 'Map');
|
|
113
|
-
if (!this.isMobile())
|
|
114
|
-
map.set('sat', 'Satellite View');
|
|
110
|
+
this.addRideViewOption(map, 'sv', 'Street View');
|
|
111
|
+
map.set('map', { label: 'Map' });
|
|
112
|
+
this.addRideViewOption(map, 'sat', 'Satellite View');
|
|
115
113
|
return map;
|
|
116
114
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return
|
|
115
|
+
addRideViewOption(map, key, label) {
|
|
116
|
+
const availability = this.getBindings().mapAvailability?.isAvailable(key);
|
|
117
|
+
if (availability?.status === 'not-supported')
|
|
118
|
+
return;
|
|
119
|
+
if (availability?.status === 'unavailable') {
|
|
120
|
+
const message = UNAVAILABLE_MESSAGES[availability.messageKey ?? ''] ?? DEFAULT_UNAVAILABLE_MESSAGE;
|
|
121
|
+
map.set(key, { label, disabled: true, message });
|
|
122
|
+
return;
|
|
121
123
|
}
|
|
122
|
-
|
|
124
|
+
map.set(key, { label });
|
|
123
125
|
}
|
|
124
126
|
isMobile() {
|
|
125
127
|
return this.getBindings().appInfo?.getChannel() === 'mobile';
|
|
@@ -136,9 +138,6 @@ let RideSettingsDisplayService = (() => {
|
|
|
136
138
|
getBindings() {
|
|
137
139
|
return (0, api_1.getBindings)();
|
|
138
140
|
}
|
|
139
|
-
getSecretBinding() {
|
|
140
|
-
return this.getBindings().secret;
|
|
141
|
-
}
|
|
142
141
|
};
|
|
143
142
|
return RideSettingsDisplayService = _classThis;
|
|
144
143
|
})();
|
|
@@ -353,15 +353,16 @@ let ActiveRidesService = (() => {
|
|
|
353
353
|
};
|
|
354
354
|
displayProps.push(displayItem);
|
|
355
355
|
});
|
|
356
|
+
const diffValue = (r) => r.diffDistance?.value ?? 0;
|
|
356
357
|
if (displayProps.length > this.maxLength) {
|
|
357
|
-
const absDiff = (r) => Math.abs(r
|
|
358
|
+
const absDiff = (r) => Math.abs(diffValue(r));
|
|
358
359
|
displayProps.sort((a, b) => {
|
|
359
360
|
return absDiff(b) > absDiff(a) ? -1 : 1;
|
|
360
361
|
});
|
|
361
362
|
return displayProps.filter((_r, idx) => idx < this.maxLength);
|
|
362
363
|
}
|
|
363
364
|
displayProps.sort((a, b) => {
|
|
364
|
-
return b
|
|
365
|
+
return diffValue(b) > diffValue(a) ? -1 : 1;
|
|
365
366
|
});
|
|
366
367
|
return displayProps;
|
|
367
368
|
}
|
|
@@ -422,6 +422,7 @@ let ActivityRideService = (() => {
|
|
|
422
422
|
const isFreeRide = startSettings?.type === 'Free-Ride';
|
|
423
423
|
const showWorkoutSummary = this.activity?.routeType === 'None';
|
|
424
424
|
const showSave = this.activity !== undefined && !this.isSaveDone;
|
|
425
|
+
const showDelete = this.activity !== undefined && !this.isSaveDone;
|
|
425
426
|
const showContinue = this.state !== 'completed';
|
|
426
427
|
const hasGPX = this.activity?.logs?.some((log) => !!log.lat && !!log.lng);
|
|
427
428
|
const showMap = hasGPX || isFreeRide || (route?.description?.hasGpx);
|
|
@@ -434,6 +435,7 @@ let ActivityRideService = (() => {
|
|
|
434
435
|
const props = {
|
|
435
436
|
activity: createUIActivityDetails(this.activity),
|
|
436
437
|
showSave,
|
|
438
|
+
showDelete,
|
|
437
439
|
showContinue,
|
|
438
440
|
showMap,
|
|
439
441
|
showWorkoutSummary,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -203,9 +203,6 @@ let DevicePairingService = (() => {
|
|
|
203
203
|
this.logEvent({ message: 'Stop Pairing (OK)', stillPairing, stillScanning });
|
|
204
204
|
try {
|
|
205
205
|
this.pauseAdapters(adapters.filter(a => !adapterFilter.includes(a.udid)));
|
|
206
|
-
if (this.isPairing()) {
|
|
207
|
-
this.removePairingCallbacks();
|
|
208
|
-
}
|
|
209
206
|
if (this.isScanning()) {
|
|
210
207
|
this.state.stopRequested = true;
|
|
211
208
|
await this._stop();
|
|
@@ -214,7 +211,9 @@ let DevicePairingService = (() => {
|
|
|
214
211
|
this.settings = {};
|
|
215
212
|
this.state.initialized = false;
|
|
216
213
|
this.state.waiting = false;
|
|
217
|
-
|
|
214
|
+
if (!stillPairing) {
|
|
215
|
+
this.state.check = null;
|
|
216
|
+
}
|
|
218
217
|
this.state.scan = null;
|
|
219
218
|
this.state.stopRequested = false;
|
|
220
219
|
this.state.stopped = true;
|
|
@@ -1005,6 +1004,9 @@ let DevicePairingService = (() => {
|
|
|
1005
1004
|
this.emit('pairing-done');
|
|
1006
1005
|
return;
|
|
1007
1006
|
}
|
|
1007
|
+
if (this.isPairing() && this.state.check?.promise !== undefined) {
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1008
1010
|
if (this.usage !== 'page' && this.isPairing()) {
|
|
1009
1011
|
return;
|
|
1010
1012
|
}
|
|
@@ -43,6 +43,7 @@ const SV_UPDATE_FREQ = 3000;
|
|
|
43
43
|
const SV_MIN_READY = 1500;
|
|
44
44
|
const SV_MIN_DELAY = 1000;
|
|
45
45
|
const SV_START_TIMEOUT = 15000;
|
|
46
|
+
const SAT_START_TIMEOUT = 15000;
|
|
46
47
|
let GpxDisplayService = (() => {
|
|
47
48
|
let _classSuper = RouteDisplayService;
|
|
48
49
|
let _instanceExtraInitializers = [];
|
|
@@ -73,6 +74,8 @@ let GpxDisplayService = (() => {
|
|
|
73
74
|
updateDurations = [];
|
|
74
75
|
svStartTimedOut = false;
|
|
75
76
|
svStartTimeout;
|
|
77
|
+
satStartTimedOut = false;
|
|
78
|
+
satStartTimeout;
|
|
76
79
|
constructor() {
|
|
77
80
|
super();
|
|
78
81
|
}
|
|
@@ -87,6 +90,10 @@ let GpxDisplayService = (() => {
|
|
|
87
90
|
if (this.waitsForStreetView())
|
|
88
91
|
this.armStreetViewStartTimeout();
|
|
89
92
|
}
|
|
93
|
+
else if (rideView === 'sat') {
|
|
94
|
+
if (this.waitsForSatelliteView())
|
|
95
|
+
this.armSatelliteViewStartTimeout();
|
|
96
|
+
}
|
|
90
97
|
}
|
|
91
98
|
catch (err) {
|
|
92
99
|
this.logError(err, 'initView');
|
|
@@ -111,7 +118,12 @@ let GpxDisplayService = (() => {
|
|
|
111
118
|
return props;
|
|
112
119
|
}
|
|
113
120
|
getInitialStreetViewPosition() {
|
|
114
|
-
|
|
121
|
+
return this.enrichWithHeading(this.position, 'getInitialStreetViewPosition');
|
|
122
|
+
}
|
|
123
|
+
getSatelliteViewPosition() {
|
|
124
|
+
return this.enrichWithHeading(this.position, 'getSatelliteViewPosition');
|
|
125
|
+
}
|
|
126
|
+
enrichWithHeading(position, logContext) {
|
|
115
127
|
if (!position)
|
|
116
128
|
return undefined;
|
|
117
129
|
if (position.heading !== undefined)
|
|
@@ -120,17 +132,20 @@ let GpxDisplayService = (() => {
|
|
|
120
132
|
return { ...position, heading: getHeading(this.getOriginalRoute(), position) };
|
|
121
133
|
}
|
|
122
134
|
catch (err) {
|
|
123
|
-
this.logError(err,
|
|
135
|
+
this.logError(err, logContext);
|
|
124
136
|
return position;
|
|
125
137
|
}
|
|
126
138
|
}
|
|
127
139
|
waitsForStreetView() {
|
|
128
140
|
return this.isMobile() && this.getRideSettingsDisplay().getRideView() === 'sv';
|
|
129
141
|
}
|
|
142
|
+
waitsForSatelliteView() {
|
|
143
|
+
return this.isMobile() && this.getRideSettingsDisplay().getRideView() === 'sat';
|
|
144
|
+
}
|
|
130
145
|
getSatelliteViewProps() {
|
|
131
146
|
return {
|
|
132
147
|
onDisplayEvent: this.onSatelliteViewEvent.bind(this),
|
|
133
|
-
displayPosition: this.
|
|
148
|
+
displayPosition: this.getSatelliteViewPosition()
|
|
134
149
|
};
|
|
135
150
|
}
|
|
136
151
|
getMapViewProps() {
|
|
@@ -142,7 +157,7 @@ let GpxDisplayService = (() => {
|
|
|
142
157
|
}
|
|
143
158
|
getStartOverlayProps() {
|
|
144
159
|
const rideView = this.getRideSettingsDisplay().getRideView();
|
|
145
|
-
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
|
|
160
|
+
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView() && !this.waitsForSatelliteView())) {
|
|
146
161
|
return {
|
|
147
162
|
mapType: this.getRideViewName(),
|
|
148
163
|
mapState: 'Loaded'
|
|
@@ -156,11 +171,11 @@ let GpxDisplayService = (() => {
|
|
|
156
171
|
}
|
|
157
172
|
isStartRideCompleted() {
|
|
158
173
|
const rideView = this.getRideSettingsDisplay().getRideView();
|
|
159
|
-
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
|
|
174
|
+
if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView() && !this.waitsForSatelliteView())) {
|
|
160
175
|
this.mapLoaded = true;
|
|
161
176
|
return true;
|
|
162
177
|
}
|
|
163
|
-
if (this.svStartTimedOut)
|
|
178
|
+
if (this.svStartTimedOut || this.satStartTimedOut)
|
|
164
179
|
return true;
|
|
165
180
|
return this.mapLoaded;
|
|
166
181
|
}
|
|
@@ -196,6 +211,7 @@ let GpxDisplayService = (() => {
|
|
|
196
211
|
onSatelliteViewEvent(state, error) {
|
|
197
212
|
if (state === 'Loaded') {
|
|
198
213
|
this.mapLoaded = true;
|
|
214
|
+
this.clearSatelliteViewStartTimeout();
|
|
199
215
|
}
|
|
200
216
|
else if (state === 'Error') {
|
|
201
217
|
this.logEvent({ message: 'sat view error', error: this.mapError });
|
|
@@ -285,12 +301,35 @@ let GpxDisplayService = (() => {
|
|
|
285
301
|
getStreetViewStartTimeout() {
|
|
286
302
|
return this.getNumSetting('SV_START_TIMEOUT') ?? SV_START_TIMEOUT;
|
|
287
303
|
}
|
|
304
|
+
armSatelliteViewStartTimeout() {
|
|
305
|
+
this.clearSatelliteViewStartTimeout();
|
|
306
|
+
const timeout = this.getSatelliteViewStartTimeout();
|
|
307
|
+
this.satStartTimeout = setTimeout(() => {
|
|
308
|
+
this.satStartTimeout = undefined;
|
|
309
|
+
if (this.mapLoaded)
|
|
310
|
+
return;
|
|
311
|
+
this.satStartTimedOut = true;
|
|
312
|
+
this.logEvent({ message: 'satellite view start timeout', timeout });
|
|
313
|
+
this.emit('state-update');
|
|
314
|
+
}, timeout);
|
|
315
|
+
}
|
|
316
|
+
clearSatelliteViewStartTimeout() {
|
|
317
|
+
if (this.satStartTimeout) {
|
|
318
|
+
clearTimeout(this.satStartTimeout);
|
|
319
|
+
this.satStartTimeout = undefined;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
getSatelliteViewStartTimeout() {
|
|
323
|
+
return this.getNumSetting('SAT_START_TIMEOUT') ?? SAT_START_TIMEOUT;
|
|
324
|
+
}
|
|
288
325
|
onStarted() {
|
|
289
326
|
this.clearStreetViewStartTimeout();
|
|
327
|
+
this.clearSatelliteViewStartTimeout();
|
|
290
328
|
super.onStarted();
|
|
291
329
|
}
|
|
292
330
|
async stop() {
|
|
293
331
|
this.clearStreetViewStartTimeout();
|
|
332
|
+
this.clearSatelliteViewStartTimeout();
|
|
294
333
|
return super.stop();
|
|
295
334
|
}
|
|
296
335
|
getStreetViewObserver() {
|
|
@@ -37,6 +37,10 @@ import { Injectable, Singleton } from "../../../base/decorators";
|
|
|
37
37
|
import { IncyclistService } from "../../../base/service";
|
|
38
38
|
import { Observer } from "../../../base/types";
|
|
39
39
|
import { useUserSettings } from "../../service";
|
|
40
|
+
const UNAVAILABLE_MESSAGES = {
|
|
41
|
+
'need.playservices': 'Install Google Play Services to use this view',
|
|
42
|
+
};
|
|
43
|
+
const DEFAULT_UNAVAILABLE_MESSAGE = 'This view is currently unavailable on your device';
|
|
40
44
|
let RideSettingsDisplayService = (() => {
|
|
41
45
|
let _classDecorators = [Singleton];
|
|
42
46
|
let _classDescriptor;
|
|
@@ -80,8 +84,6 @@ let RideSettingsDisplayService = (() => {
|
|
|
80
84
|
};
|
|
81
85
|
}
|
|
82
86
|
setRideView(rideView) {
|
|
83
|
-
if (this.isRestricted())
|
|
84
|
-
return;
|
|
85
87
|
try {
|
|
86
88
|
this.getUserSettings().set('preferences.rideView', rideView);
|
|
87
89
|
}
|
|
@@ -94,29 +96,29 @@ let RideSettingsDisplayService = (() => {
|
|
|
94
96
|
this.observer.emit('changed', this.getDisplayProps());
|
|
95
97
|
}
|
|
96
98
|
getRideView() {
|
|
97
|
-
if (this.isRestricted())
|
|
98
|
-
return 'map';
|
|
99
99
|
const rideView = this.getUserSettings().get('preferences.rideView', 'sv');
|
|
100
|
+
const availability = this.getBindings().mapAvailability?.isAvailable(rideView);
|
|
101
|
+
if (availability?.status === 'unavailable' || availability?.status === 'not-supported')
|
|
102
|
+
return 'map';
|
|
100
103
|
return rideView;
|
|
101
104
|
}
|
|
102
105
|
getRideViewOptions() {
|
|
103
106
|
const map = new Map();
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
map.set('sv', 'Street View');
|
|
109
|
-
map.set('map', 'Map');
|
|
110
|
-
if (!this.isMobile())
|
|
111
|
-
map.set('sat', 'Satellite View');
|
|
107
|
+
this.addRideViewOption(map, 'sv', 'Street View');
|
|
108
|
+
map.set('map', { label: 'Map' });
|
|
109
|
+
this.addRideViewOption(map, 'sat', 'Satellite View');
|
|
112
110
|
return map;
|
|
113
111
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return
|
|
112
|
+
addRideViewOption(map, key, label) {
|
|
113
|
+
const availability = this.getBindings().mapAvailability?.isAvailable(key);
|
|
114
|
+
if (availability?.status === 'not-supported')
|
|
115
|
+
return;
|
|
116
|
+
if (availability?.status === 'unavailable') {
|
|
117
|
+
const message = UNAVAILABLE_MESSAGES[availability.messageKey ?? ''] ?? DEFAULT_UNAVAILABLE_MESSAGE;
|
|
118
|
+
map.set(key, { label, disabled: true, message });
|
|
119
|
+
return;
|
|
118
120
|
}
|
|
119
|
-
|
|
121
|
+
map.set(key, { label });
|
|
120
122
|
}
|
|
121
123
|
isMobile() {
|
|
122
124
|
return this.getBindings().appInfo?.getChannel() === 'mobile';
|
|
@@ -133,9 +135,6 @@ let RideSettingsDisplayService = (() => {
|
|
|
133
135
|
getBindings() {
|
|
134
136
|
return getBindings();
|
|
135
137
|
}
|
|
136
|
-
getSecretBinding() {
|
|
137
|
-
return this.getBindings().secret;
|
|
138
|
-
}
|
|
139
138
|
};
|
|
140
139
|
return RideSettingsDisplayService = _classThis;
|
|
141
140
|
})();
|
|
@@ -12,6 +12,7 @@ import type { ISecretBinding } from '../secret';
|
|
|
12
12
|
import type { ISerialBinding } from '../serial/types';
|
|
13
13
|
import type { ICryptoBinding } from '../crypto/types';
|
|
14
14
|
import type { IFetchBinding } from '../fetch/types';
|
|
15
|
+
import type { IMapAvailabilityBinding } from '../mapAvailability/types';
|
|
15
16
|
export interface IUserSettingsBinding {
|
|
16
17
|
getAll(): Promise<any>;
|
|
17
18
|
set(key: string, value: any): Promise<boolean>;
|
|
@@ -28,6 +29,7 @@ export declare class IncyclistBindings {
|
|
|
28
29
|
downloadManager?: IDownloadManager;
|
|
29
30
|
form?: IFormPostBinding;
|
|
30
31
|
secret?: ISecretBinding;
|
|
32
|
+
mapAvailability?: IMapAvailabilityBinding;
|
|
31
33
|
mq: IMessageQueueBinding;
|
|
32
34
|
ui: INativeUI;
|
|
33
35
|
settings: IUserSettingsBinding;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TRideView } from '../../settings/display/ride/types';
|
|
2
|
+
export type AvailabilityStatus = 'available' | 'unavailable' | 'not-supported';
|
|
3
|
+
export interface AvailabilityResult {
|
|
4
|
+
status: AvailabilityStatus;
|
|
5
|
+
messageKey?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface IMapAvailabilityBinding {
|
|
8
|
+
isAvailable(key: TRideView): AvailabilityResult;
|
|
9
|
+
onChange(cb: (key: TRideView, result: AvailabilityResult) => void): void;
|
|
10
|
+
}
|
|
@@ -2,7 +2,7 @@ import { GoogleMapsService } from "../../apps";
|
|
|
2
2
|
import { Observer } from "../../base/types";
|
|
3
3
|
import { Route } from "../../routes/base/model/route";
|
|
4
4
|
import { RoutePoint } from "../../types";
|
|
5
|
-
import { CurrentRideDisplayProps, GpxDisplayProps } from "../base";
|
|
5
|
+
import { CurrentPosition, CurrentRideDisplayProps, GpxDisplayProps } from "../base";
|
|
6
6
|
import { RouteDisplayService } from "./RouteDisplayService";
|
|
7
7
|
import { SatelliteViewEvent, StreetViewEvent } from "./types";
|
|
8
8
|
export declare class GpxDisplayService extends RouteDisplayService {
|
|
@@ -23,19 +23,24 @@ export declare class GpxDisplayService extends RouteDisplayService {
|
|
|
23
23
|
protected updateDurations: Array<number>;
|
|
24
24
|
protected svStartTimedOut: boolean;
|
|
25
25
|
protected svStartTimeout: NodeJS.Timeout;
|
|
26
|
+
protected satStartTimedOut: boolean;
|
|
27
|
+
protected satStartTimeout: NodeJS.Timeout;
|
|
26
28
|
constructor();
|
|
27
29
|
protected initView(): void;
|
|
28
30
|
getStreetViewProps(rideProps: CurrentRideDisplayProps): any;
|
|
29
|
-
protected getInitialStreetViewPosition():
|
|
31
|
+
protected getInitialStreetViewPosition(): CurrentPosition;
|
|
32
|
+
protected getSatelliteViewPosition(): CurrentPosition;
|
|
33
|
+
protected enrichWithHeading(position: CurrentPosition | undefined, logContext: string): CurrentPosition;
|
|
30
34
|
protected waitsForStreetView(): boolean;
|
|
35
|
+
protected waitsForSatelliteView(): boolean;
|
|
31
36
|
getSatelliteViewProps(): {
|
|
32
37
|
onDisplayEvent: any;
|
|
33
|
-
displayPosition:
|
|
38
|
+
displayPosition: CurrentPosition;
|
|
34
39
|
};
|
|
35
40
|
getMapViewProps(): {
|
|
36
41
|
onDisplayEvent: any;
|
|
37
42
|
showMap: boolean;
|
|
38
|
-
displayPosition:
|
|
43
|
+
displayPosition: CurrentPosition;
|
|
39
44
|
};
|
|
40
45
|
getStartOverlayProps(): {
|
|
41
46
|
mapType: string;
|
|
@@ -57,6 +62,9 @@ export declare class GpxDisplayService extends RouteDisplayService {
|
|
|
57
62
|
protected armStreetViewStartTimeout(): void;
|
|
58
63
|
protected clearStreetViewStartTimeout(): void;
|
|
59
64
|
protected getStreetViewStartTimeout(): number;
|
|
65
|
+
protected armSatelliteViewStartTimeout(): void;
|
|
66
|
+
protected clearSatelliteViewStartTimeout(): void;
|
|
67
|
+
protected getSatelliteViewStartTimeout(): number;
|
|
60
68
|
onStarted(): void;
|
|
61
69
|
stop(): Promise<void>;
|
|
62
70
|
protected getStreetViewObserver(): Observer;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { ISecretBinding } from "../../../api";
|
|
2
1
|
import { IncyclistService } from "../../../base/service";
|
|
3
2
|
import { Observer } from "../../../base/types";
|
|
4
3
|
import { IObserver } from "../../../types";
|
|
5
4
|
import { UserSettingsService } from "../../service";
|
|
6
|
-
import { RideSettingsDisplayProps, TRideView } from "./types";
|
|
5
|
+
import { RideSettingsDisplayProps, TRideView, TRideViewOption } from "./types";
|
|
7
6
|
export declare class RideSettingsDisplayService extends IncyclistService {
|
|
8
7
|
protected observer: Observer;
|
|
9
8
|
constructor();
|
|
@@ -13,13 +12,12 @@ export declare class RideSettingsDisplayService extends IncyclistService {
|
|
|
13
12
|
setRideView(rideView: TRideView): void;
|
|
14
13
|
protected emitChanged(): void;
|
|
15
14
|
getRideView(): TRideView;
|
|
16
|
-
getRideViewOptions(): Map<TRideView,
|
|
17
|
-
protected
|
|
15
|
+
getRideViewOptions(): Map<TRideView, TRideViewOption>;
|
|
16
|
+
protected addRideViewOption(map: Map<TRideView, TRideViewOption>, key: TRideView, label: string): void;
|
|
18
17
|
protected isMobile(): boolean;
|
|
19
18
|
protected isAndroid(): boolean;
|
|
20
19
|
protected isIOS(): boolean;
|
|
21
20
|
protected getUserSettings(): UserSettingsService;
|
|
22
21
|
protected getBindings(): import("../../../api").IncyclistBindings;
|
|
23
|
-
protected getSecretBinding(): ISecretBinding | undefined;
|
|
24
22
|
}
|
|
25
23
|
export declare const useRideSettingsDisplay: () => RideSettingsDisplayService;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export type TRideView = 'sv' | 'sat' | 'map';
|
|
2
|
+
export interface TRideViewOption {
|
|
3
|
+
label: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
message?: string;
|
|
6
|
+
}
|
|
2
7
|
export interface RideSettingsDisplayProps {
|
|
3
8
|
rideView: TRideView;
|
|
4
|
-
rideViewOptions: Map<TRideView,
|
|
9
|
+
rideViewOptions: Map<TRideView, TRideViewOption>;
|
|
5
10
|
}
|