incyclist-services 1.7.105 → 1.7.107

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.
@@ -359,7 +359,9 @@ let RidePageService = (() => {
359
359
  ...this.buildWorkoutOverlayProps(props, base.startOverlayProps === null),
360
360
  rideView: props.rideView,
361
361
  route: props.route,
362
- displayObserver: props.displayObserver
362
+ displayObserver: props.displayObserver,
363
+ displayPosition: props.displayPosition,
364
+ onDisplayEvent: props.onDisplayEvent
363
365
  };
364
366
  return displayProps;
365
367
  }
@@ -45,6 +45,7 @@ const RouteDisplayService_1 = require("./RouteDisplayService");
45
45
  const SV_UPDATE_FREQ = 3000;
46
46
  const SV_MIN_READY = 1500;
47
47
  const SV_MIN_DELAY = 1000;
48
+ const SV_START_TIMEOUT = 15000;
48
49
  let GpxDisplayService = (() => {
49
50
  let _classSuper = RouteDisplayService_1.RouteDisplayService;
50
51
  let _instanceExtraInitializers = [];
@@ -73,6 +74,8 @@ let GpxDisplayService = (() => {
73
74
  tsLastPovChanged;
74
75
  povTimeout;
75
76
  updateDurations = [];
77
+ svStartTimedOut = false;
78
+ svStartTimeout;
76
79
  constructor() {
77
80
  super();
78
81
  }
@@ -84,6 +87,8 @@ let GpxDisplayService = (() => {
84
87
  const minimalPause = this.getMinimalPause();
85
88
  const bestFreq = this.getBestCaseUpdateFrequency();
86
89
  this.logEvent({ message: 'init streetview', updateFreq, minimalPause, bestFreq });
90
+ if (this.waitsForStreetView())
91
+ this.armStreetViewStartTimeout();
87
92
  }
88
93
  }
89
94
  catch (err) {
@@ -104,9 +109,27 @@ let GpxDisplayService = (() => {
104
109
  sideViews
105
110
  };
106
111
  if (this.isMobile()) {
112
+ props.displayPosition = this.mapLoaded ? null : this.getInitialStreetViewPosition();
107
113
  }
108
114
  return props;
109
115
  }
116
+ getInitialStreetViewPosition() {
117
+ const position = this.position;
118
+ if (!position)
119
+ return undefined;
120
+ if (position.heading !== undefined)
121
+ return position;
122
+ try {
123
+ return { ...position, heading: (0, routes_1.getHeading)(this.getOriginalRoute(), position) };
124
+ }
125
+ catch (err) {
126
+ this.logError(err, 'getInitialStreetViewPosition');
127
+ return position;
128
+ }
129
+ }
130
+ waitsForStreetView() {
131
+ return this.isMobile() && this.getRideSettingsDisplay().getRideView() === 'sv';
132
+ }
110
133
  getSatelliteViewProps() {
111
134
  return {
112
135
  onDisplayEvent: this.onSatelliteViewEvent.bind(this),
@@ -122,7 +145,7 @@ let GpxDisplayService = (() => {
122
145
  }
123
146
  getStartOverlayProps() {
124
147
  const rideView = this.getRideSettingsDisplay().getRideView();
125
- if (rideView === 'map' || this.isMobile()) {
148
+ if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
126
149
  return {
127
150
  mapType: this.getRideViewName(),
128
151
  mapState: 'Loaded'
@@ -136,10 +159,12 @@ let GpxDisplayService = (() => {
136
159
  }
137
160
  isStartRideCompleted() {
138
161
  const rideView = this.getRideSettingsDisplay().getRideView();
139
- if (rideView === 'map' || this.isMobile()) {
162
+ if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
140
163
  this.mapLoaded = true;
141
164
  return true;
142
165
  }
166
+ if (this.svStartTimedOut)
167
+ return true;
143
168
  return this.mapLoaded;
144
169
  }
145
170
  getDisplayProperties(props) {
@@ -196,6 +221,7 @@ let GpxDisplayService = (() => {
196
221
  };
197
222
  if (event === 'Loaded') {
198
223
  this.mapLoaded = true;
224
+ this.clearStreetViewStartTimeout();
199
225
  this.emit('state-update');
200
226
  this.tsLastSVEvent = Date.now();
201
227
  }
@@ -208,6 +234,8 @@ let GpxDisplayService = (() => {
208
234
  else if (event === 'pano_changed') {
209
235
  this.logEvent({ message: 'street view panorama changed', panorama: data });
210
236
  this.tsLastSVEvent = Date.now();
237
+ if (this.isMobile())
238
+ this.recordUpdateDuration();
211
239
  }
212
240
  else if (event === 'pov_changed') {
213
241
  if (this.tsLastPovChanged) {
@@ -216,19 +244,7 @@ let GpxDisplayService = (() => {
216
244
  resetTimeout();
217
245
  this.povTimeout = setTimeout(() => {
218
246
  this.povTimeout = undefined;
219
- let duration;
220
- if (this.tsPrevSVUpdate) {
221
- duration = Date.now() - this.tsPrevSVUpdate;
222
- if (duration > 250) {
223
- if (this.updateDurations.length == 10) {
224
- this.updateDurations.shift();
225
- }
226
- this.updateDurations.push(duration);
227
- }
228
- }
229
- if (duration !== undefined && duration > 250) {
230
- this.logEvent({ message: 'street view position update confirmed', duration });
231
- }
247
+ this.recordUpdateDuration();
232
248
  }, 100);
233
249
  }
234
250
  else {
@@ -239,6 +255,47 @@ let GpxDisplayService = (() => {
239
255
  this.tsLastSVEvent = Date.now();
240
256
  }
241
257
  }
258
+ recordUpdateDuration() {
259
+ if (!this.tsPrevSVUpdate)
260
+ return;
261
+ const duration = Date.now() - this.tsPrevSVUpdate;
262
+ if (duration <= 250)
263
+ return;
264
+ if (this.updateDurations.length == 10) {
265
+ this.updateDurations.shift();
266
+ }
267
+ this.updateDurations.push(duration);
268
+ this.logEvent({ message: 'street view position update confirmed', duration });
269
+ }
270
+ armStreetViewStartTimeout() {
271
+ this.clearStreetViewStartTimeout();
272
+ const timeout = this.getStreetViewStartTimeout();
273
+ this.svStartTimeout = setTimeout(() => {
274
+ this.svStartTimeout = undefined;
275
+ if (this.mapLoaded)
276
+ return;
277
+ this.svStartTimedOut = true;
278
+ this.logEvent({ message: 'street view start timeout', timeout });
279
+ this.emit('state-update');
280
+ }, timeout);
281
+ }
282
+ clearStreetViewStartTimeout() {
283
+ if (this.svStartTimeout) {
284
+ clearTimeout(this.svStartTimeout);
285
+ this.svStartTimeout = undefined;
286
+ }
287
+ }
288
+ getStreetViewStartTimeout() {
289
+ return this.getNumSetting('SV_START_TIMEOUT') ?? SV_START_TIMEOUT;
290
+ }
291
+ onStarted() {
292
+ this.clearStreetViewStartTimeout();
293
+ super.onStarted();
294
+ }
295
+ async stop() {
296
+ this.clearStreetViewStartTimeout();
297
+ return super.stop();
298
+ }
242
299
  getStreetViewObserver() {
243
300
  this.svObserver = this.svObserver ?? new types_1.Observer();
244
301
  return this.svObserver;
@@ -99,8 +99,6 @@ let RideSettingsDisplayService = (() => {
99
99
  getRideView() {
100
100
  if (this.isRestricted())
101
101
  return 'map';
102
- if (this.isMobile() && !this.isAndroid())
103
- return 'map';
104
102
  const rideView = this.getUserSettings().get('preferences.rideView', 'sv');
105
103
  return rideView;
106
104
  }
@@ -110,8 +108,7 @@ let RideSettingsDisplayService = (() => {
110
108
  map.set('map', 'Map');
111
109
  return map;
112
110
  }
113
- if (!this.isIOS())
114
- map.set('sv', 'Street View');
111
+ map.set('sv', 'Street View');
115
112
  map.set('map', 'Map');
116
113
  if (!this.isMobile())
117
114
  map.set('sat', 'Satellite View');
@@ -356,7 +356,9 @@ let RidePageService = (() => {
356
356
  ...this.buildWorkoutOverlayProps(props, base.startOverlayProps === null),
357
357
  rideView: props.rideView,
358
358
  route: props.route,
359
- displayObserver: props.displayObserver
359
+ displayObserver: props.displayObserver,
360
+ displayPosition: props.displayPosition,
361
+ onDisplayEvent: props.onDisplayEvent
360
362
  };
361
363
  return displayProps;
362
364
  }
@@ -42,6 +42,7 @@ import { RouteDisplayService } from "./RouteDisplayService";
42
42
  const SV_UPDATE_FREQ = 3000;
43
43
  const SV_MIN_READY = 1500;
44
44
  const SV_MIN_DELAY = 1000;
45
+ const SV_START_TIMEOUT = 15000;
45
46
  let GpxDisplayService = (() => {
46
47
  let _classSuper = RouteDisplayService;
47
48
  let _instanceExtraInitializers = [];
@@ -70,6 +71,8 @@ let GpxDisplayService = (() => {
70
71
  tsLastPovChanged;
71
72
  povTimeout;
72
73
  updateDurations = [];
74
+ svStartTimedOut = false;
75
+ svStartTimeout;
73
76
  constructor() {
74
77
  super();
75
78
  }
@@ -81,6 +84,8 @@ let GpxDisplayService = (() => {
81
84
  const minimalPause = this.getMinimalPause();
82
85
  const bestFreq = this.getBestCaseUpdateFrequency();
83
86
  this.logEvent({ message: 'init streetview', updateFreq, minimalPause, bestFreq });
87
+ if (this.waitsForStreetView())
88
+ this.armStreetViewStartTimeout();
84
89
  }
85
90
  }
86
91
  catch (err) {
@@ -101,9 +106,27 @@ let GpxDisplayService = (() => {
101
106
  sideViews
102
107
  };
103
108
  if (this.isMobile()) {
109
+ props.displayPosition = this.mapLoaded ? null : this.getInitialStreetViewPosition();
104
110
  }
105
111
  return props;
106
112
  }
113
+ getInitialStreetViewPosition() {
114
+ const position = this.position;
115
+ if (!position)
116
+ return undefined;
117
+ if (position.heading !== undefined)
118
+ return position;
119
+ try {
120
+ return { ...position, heading: getHeading(this.getOriginalRoute(), position) };
121
+ }
122
+ catch (err) {
123
+ this.logError(err, 'getInitialStreetViewPosition');
124
+ return position;
125
+ }
126
+ }
127
+ waitsForStreetView() {
128
+ return this.isMobile() && this.getRideSettingsDisplay().getRideView() === 'sv';
129
+ }
107
130
  getSatelliteViewProps() {
108
131
  return {
109
132
  onDisplayEvent: this.onSatelliteViewEvent.bind(this),
@@ -119,7 +142,7 @@ let GpxDisplayService = (() => {
119
142
  }
120
143
  getStartOverlayProps() {
121
144
  const rideView = this.getRideSettingsDisplay().getRideView();
122
- if (rideView === 'map' || this.isMobile()) {
145
+ if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
123
146
  return {
124
147
  mapType: this.getRideViewName(),
125
148
  mapState: 'Loaded'
@@ -133,10 +156,12 @@ let GpxDisplayService = (() => {
133
156
  }
134
157
  isStartRideCompleted() {
135
158
  const rideView = this.getRideSettingsDisplay().getRideView();
136
- if (rideView === 'map' || this.isMobile()) {
159
+ if (rideView === 'map' || (this.isMobile() && !this.waitsForStreetView())) {
137
160
  this.mapLoaded = true;
138
161
  return true;
139
162
  }
163
+ if (this.svStartTimedOut)
164
+ return true;
140
165
  return this.mapLoaded;
141
166
  }
142
167
  getDisplayProperties(props) {
@@ -193,6 +218,7 @@ let GpxDisplayService = (() => {
193
218
  };
194
219
  if (event === 'Loaded') {
195
220
  this.mapLoaded = true;
221
+ this.clearStreetViewStartTimeout();
196
222
  this.emit('state-update');
197
223
  this.tsLastSVEvent = Date.now();
198
224
  }
@@ -205,6 +231,8 @@ let GpxDisplayService = (() => {
205
231
  else if (event === 'pano_changed') {
206
232
  this.logEvent({ message: 'street view panorama changed', panorama: data });
207
233
  this.tsLastSVEvent = Date.now();
234
+ if (this.isMobile())
235
+ this.recordUpdateDuration();
208
236
  }
209
237
  else if (event === 'pov_changed') {
210
238
  if (this.tsLastPovChanged) {
@@ -213,19 +241,7 @@ let GpxDisplayService = (() => {
213
241
  resetTimeout();
214
242
  this.povTimeout = setTimeout(() => {
215
243
  this.povTimeout = undefined;
216
- let duration;
217
- if (this.tsPrevSVUpdate) {
218
- duration = Date.now() - this.tsPrevSVUpdate;
219
- if (duration > 250) {
220
- if (this.updateDurations.length == 10) {
221
- this.updateDurations.shift();
222
- }
223
- this.updateDurations.push(duration);
224
- }
225
- }
226
- if (duration !== undefined && duration > 250) {
227
- this.logEvent({ message: 'street view position update confirmed', duration });
228
- }
244
+ this.recordUpdateDuration();
229
245
  }, 100);
230
246
  }
231
247
  else {
@@ -236,6 +252,47 @@ let GpxDisplayService = (() => {
236
252
  this.tsLastSVEvent = Date.now();
237
253
  }
238
254
  }
255
+ recordUpdateDuration() {
256
+ if (!this.tsPrevSVUpdate)
257
+ return;
258
+ const duration = Date.now() - this.tsPrevSVUpdate;
259
+ if (duration <= 250)
260
+ return;
261
+ if (this.updateDurations.length == 10) {
262
+ this.updateDurations.shift();
263
+ }
264
+ this.updateDurations.push(duration);
265
+ this.logEvent({ message: 'street view position update confirmed', duration });
266
+ }
267
+ armStreetViewStartTimeout() {
268
+ this.clearStreetViewStartTimeout();
269
+ const timeout = this.getStreetViewStartTimeout();
270
+ this.svStartTimeout = setTimeout(() => {
271
+ this.svStartTimeout = undefined;
272
+ if (this.mapLoaded)
273
+ return;
274
+ this.svStartTimedOut = true;
275
+ this.logEvent({ message: 'street view start timeout', timeout });
276
+ this.emit('state-update');
277
+ }, timeout);
278
+ }
279
+ clearStreetViewStartTimeout() {
280
+ if (this.svStartTimeout) {
281
+ clearTimeout(this.svStartTimeout);
282
+ this.svStartTimeout = undefined;
283
+ }
284
+ }
285
+ getStreetViewStartTimeout() {
286
+ return this.getNumSetting('SV_START_TIMEOUT') ?? SV_START_TIMEOUT;
287
+ }
288
+ onStarted() {
289
+ this.clearStreetViewStartTimeout();
290
+ super.onStarted();
291
+ }
292
+ async stop() {
293
+ this.clearStreetViewStartTimeout();
294
+ return super.stop();
295
+ }
239
296
  getStreetViewObserver() {
240
297
  this.svObserver = this.svObserver ?? new Observer();
241
298
  return this.svObserver;
@@ -96,8 +96,6 @@ let RideSettingsDisplayService = (() => {
96
96
  getRideView() {
97
97
  if (this.isRestricted())
98
98
  return 'map';
99
- if (this.isMobile() && !this.isAndroid())
100
- return 'map';
101
99
  const rideView = this.getUserSettings().get('preferences.rideView', 'sv');
102
100
  return rideView;
103
101
  }
@@ -107,8 +105,7 @@ let RideSettingsDisplayService = (() => {
107
105
  map.set('map', 'Map');
108
106
  return map;
109
107
  }
110
- if (!this.isIOS())
111
- map.set('sv', 'Street View');
108
+ map.set('sv', 'Street View');
112
109
  map.set('map', 'Map');
113
110
  if (!this.isMobile())
114
111
  map.set('sat', 'Satellite View');
@@ -8,7 +8,7 @@ import { EventEmitter } from "node:events";
8
8
  import { ActiveRideListAvatar, ActivityDetails, PrevRidesListDisplayProps, ScreenShotInfo } from "../../activities";
9
9
  import { Workout } from "../../workouts";
10
10
  import { FreeRideOption } from "../../routes/list/types";
11
- import { MapViewPort } from "../route/types";
11
+ import { MapViewPort, StreetViewEvent } from "../route/types";
12
12
  import { LatLng } from "../../utils/geo";
13
13
  import { Unit } from "../../i18n";
14
14
  import { IObserver } from "../../types";
@@ -104,6 +104,8 @@ export type RideViewType = 'sv' | 'map' | 'sat';
104
104
  export interface GpxDisplayProps extends RouteDisplayProps {
105
105
  rideView: RideViewType;
106
106
  displayObserver?: IObserver;
107
+ displayPosition?: CurrentPosition;
108
+ onDisplayEvent?: (event: StreetViewEvent, data?: any) => void;
107
109
  }
108
110
  export interface RouteOptionDisplayProps {
109
111
  optionsDelay?: number;
@@ -1,7 +1,7 @@
1
1
  import { IPageService } from "../../base/pages";
2
2
  import { Route } from "../../routes/base/model/route";
3
3
  import { IObserver, RideType } from "../../types";
4
- import { CurrentRideState, GPXStartOverlayProps, RideViewType, StartOverlayProps, VideoDisplayProps, VideoStartOverlayProps } from "../types";
4
+ import { CurrentPosition, CurrentRideState, GPXStartOverlayProps, RideViewType, StartOverlayProps, StreetViewEvent, VideoDisplayProps, VideoStartOverlayProps } from "../types";
5
5
  import type { LoadButtonMode, PowerAdjustmentResult } from "../../workouts/ride/types";
6
6
  import type { WorkoutGraphPlanBar } from "../../workouts/base/graph/types";
7
7
  export interface StartGateProps {
@@ -38,6 +38,8 @@ export interface VideoRidePageDisplayProps extends RidePageDisplayProps {
38
38
  export interface GPXRidePageDisplayProps extends RidePageDisplayProps {
39
39
  rideView?: RideViewType;
40
40
  displayObserver?: IObserver;
41
+ displayPosition?: CurrentPosition;
42
+ onDisplayEvent?: (event: StreetViewEvent, data?: any) => void;
41
43
  }
42
44
  export type AnyRidePageDisplayProps = VideoRidePageDisplayProps | GPXRidePageDisplayProps | RidePageDisplayProps;
43
45
  interface RidePageCallbacks {
@@ -21,9 +21,13 @@ export declare class GpxDisplayService extends RouteDisplayService {
21
21
  protected tsLastPovChanged: number;
22
22
  protected povTimeout: NodeJS.Timeout;
23
23
  protected updateDurations: Array<number>;
24
+ protected svStartTimedOut: boolean;
25
+ protected svStartTimeout: NodeJS.Timeout;
24
26
  constructor();
25
27
  protected initView(): void;
26
28
  getStreetViewProps(rideProps: CurrentRideDisplayProps): any;
29
+ protected getInitialStreetViewPosition(): import("../base").CurrentPosition;
30
+ protected waitsForStreetView(): boolean;
27
31
  getSatelliteViewProps(): {
28
32
  onDisplayEvent: any;
29
33
  displayPosition: import("../base").CurrentPosition;
@@ -49,6 +53,12 @@ export declare class GpxDisplayService extends RouteDisplayService {
49
53
  protected onSatelliteViewEvent(state: SatelliteViewEvent, error?: string): void;
50
54
  protected onMapViewEvent(state: SatelliteViewEvent, _error?: string): void;
51
55
  protected onStreetViewEvent(event: StreetViewEvent, data: any): void;
56
+ protected recordUpdateDuration(): void;
57
+ protected armStreetViewStartTimeout(): void;
58
+ protected clearStreetViewStartTimeout(): void;
59
+ protected getStreetViewStartTimeout(): number;
60
+ onStarted(): void;
61
+ stop(): Promise<void>;
52
62
  protected getStreetViewObserver(): Observer;
53
63
  protected getStreetViewUpdateDelay(): any;
54
64
  protected onPositionUpdate(state: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.7.105",
3
+ "version": "1.7.107",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.27"
6
6
  },