incyclist-services 1.6.1 → 1.6.2

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.
@@ -79,7 +79,7 @@ let ActivityListService = (() => {
79
79
  preload(props) {
80
80
  let preloadObserver = this.getPreloadObserver();
81
81
  try {
82
- if (!preloadObserver) {
82
+ if (preloadObserver === undefined || preloadObserver === null) {
83
83
  this.logEvent({ message: 'preload activity list' });
84
84
  const promise = this.loadActivities();
85
85
  preloadObserver = this.observers.preload = new observer_1.PromiseObserver(promise);
@@ -247,10 +247,17 @@ let ActivityListService = (() => {
247
247
  if (!activity) {
248
248
  return false;
249
249
  }
250
- const emitUpdate = () => { this.emitSelected('updated'); };
251
- const observer = new observer_1.Observer();
252
- observer.on('export', emitUpdate);
253
- return yield activity.export(format, observer);
250
+ return new Promise(done => {
251
+ const emitUpdate = (update) => __awaiter(this, void 0, void 0, function* () {
252
+ this.exports = yield this.selected.getExports();
253
+ this.emitSelected('updated');
254
+ if (update.status === 'done')
255
+ done(update.success);
256
+ });
257
+ const observer = new observer_1.Observer();
258
+ observer.on('export', emitUpdate);
259
+ activity.export(format, observer);
260
+ });
254
261
  });
255
262
  }
256
263
  upload(connectedApp) {
@@ -259,11 +266,24 @@ let ActivityListService = (() => {
259
266
  if (!activity) {
260
267
  return false;
261
268
  }
262
- const emitUpdate = () => { this.emitSelected('updated'); };
263
- const observer = new observer_1.Observer();
264
- observer.on('upload', emitUpdate);
265
- observer.on('export', emitUpdate);
266
- return yield activity.upload(connectedApp, observer);
269
+ return new Promise(done => {
270
+ const emitUploadUpdate = (update) => {
271
+ if (connectedApp === update.connectedApp) {
272
+ this.emitSelected('updated');
273
+ if (update.status === 'done') {
274
+ done(update.success);
275
+ }
276
+ }
277
+ };
278
+ const emitExportUpdate = (update) => __awaiter(this, void 0, void 0, function* () {
279
+ this.exports = yield this.selected.getExports();
280
+ this.emitSelected('updated');
281
+ });
282
+ const observer = new observer_1.Observer();
283
+ observer.on('upload', emitUploadUpdate);
284
+ observer.on('export', emitExportUpdate);
285
+ activity.upload(connectedApp, observer);
286
+ });
267
287
  });
268
288
  }
269
289
  openRoute() {
@@ -28,6 +28,7 @@ export declare class StravaApi extends AppApiBase {
28
28
  protected verifyToken(): Promise<void>;
29
29
  protected isTokenStillValid(): boolean;
30
30
  protected verifyAuthentication(): Promise<void>;
31
+ protected waitForReady(): Promise<void>;
31
32
  protected waitForUploadResponse(response: StravaUploadResponse): Promise<StravaUploadResult>;
32
33
  protected createUpload(request: StravaUploadRequest): Promise<StravaUploadResponse>;
33
34
  protected getUploadById(id: string): Promise<StravaUploadResponse>;
@@ -125,11 +125,16 @@ class StravaApi extends base_1.AppApiBase {
125
125
  yield this.verifyToken();
126
126
  });
127
127
  }
128
+ waitForReady() {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ yield (0, utils_1.sleep)(1000);
131
+ });
132
+ }
128
133
  waitForUploadResponse(response) {
129
134
  return __awaiter(this, void 0, void 0, function* () {
130
135
  let data = response;
131
136
  while (data.status !== 'Your activity is ready.' && !data.error) {
132
- yield (0, utils_1.sleep)(1000);
137
+ yield this.waitForReady();
133
138
  data = yield this.getUploadById(data.id_str);
134
139
  }
135
140
  if (data.error) {
@@ -391,7 +391,7 @@ let DeviceConfigurationService = (() => {
391
391
  if (adapter.getSupportedCyclingModes) {
392
392
  modes = adapter.getSupportedCyclingModes();
393
393
  }
394
- const options = modes.map(M => new M(adapter));
394
+ const options = modes.map(M => adapter.createMode(M));
395
395
  mode = requestedMode || device.mode;
396
396
  if (!mode) {
397
397
  modeObj = adapter.getDefaultCyclingMode();
@@ -173,6 +173,9 @@ let RideDisplayService = (() => {
173
173
  }
174
174
  pause(requester = 'user') {
175
175
  var _a, _b;
176
+ if (requester === 'device' && this.isResuming) {
177
+ return;
178
+ }
176
179
  try {
177
180
  if (this.state !== 'Active')
178
181
  return;
@@ -198,10 +201,8 @@ let RideDisplayService = (() => {
198
201
  this.state = 'Active';
199
202
  this.getActivityRide().resume();
200
203
  this.getWorkoutRide().resume();
201
- this.displayService.resume();
204
+ this.pauseReason = 'device';
202
205
  (_b = this.observer) === null || _b === void 0 ? void 0 : _b.emit('state-update', this.state);
203
- (0, utils_1.waitNextTick)().then(() => this.isResuming = false);
204
- delete this.pauseReason;
205
206
  }
206
207
  catch (err) {
207
208
  this.logError(err, 'resume');
@@ -545,10 +546,15 @@ let RideDisplayService = (() => {
545
546
  const currentValues = this.getActivityRide().getCurrentValues();
546
547
  if (!currentValues)
547
548
  return;
548
- if (currentValues.speed === 0) {
549
+ if (currentValues.speed === 0 && !this.isResuming) {
549
550
  this.pause('device');
550
551
  return;
551
552
  }
553
+ if (currentValues.speed > 0 && this.isResuming) {
554
+ this.displayService.resume();
555
+ this.isResuming = false;
556
+ delete this.pauseReason;
557
+ }
552
558
  this.getRideModeService().onActivityUpdate(data, currentValues);
553
559
  this.observer.emit('data-update', data, currentValues);
554
560
  }
@@ -591,7 +597,6 @@ let RideDisplayService = (() => {
591
597
  }
592
598
  }
593
599
  onLapCompleted(oldLap, newLap) {
594
- console.log('# lap completed', oldLap, newLap);
595
600
  }
596
601
  onRouteUpdated(route) {
597
602
  this.getActivityRide().onRouteUpdate(route.points);
@@ -891,7 +896,7 @@ let RideDisplayService = (() => {
891
896
  udid: d.udid,
892
897
  isControl: d.isControl,
893
898
  capabilities: d.capabilities,
894
- status: d.isStarted ? 'Started' : 'Starting'
899
+ status: 'Starting'
895
900
  }));
896
901
  this.updateStartOverlay();
897
902
  }
@@ -974,6 +979,7 @@ let RideDisplayService = (() => {
974
979
  const pct = Math.round(completed / total * 100);
975
980
  this.logEvent({ message: 'onDeviceStartStatusUpdate', pct });
976
981
  startDevice.stateText = `uploading (${pct}%)`;
982
+ this.checkStartStatus();
977
983
  }
978
984
  onDeviceData(data, udid) {
979
985
  this.deviceData = data;
@@ -35,11 +35,13 @@ export declare class RLVDisplayService extends RouteDisplayService {
35
35
  protected infotext?: InfotextDisplayProps;
36
36
  protected videosInitialized: boolean;
37
37
  protected startTime: number;
38
+ protected isVideoPaused: boolean;
38
39
  constructor();
39
40
  initView(): void;
40
41
  getOverlayProps(overlay: any, props: CurrentRideDisplayProps): OverlayDisplayProps;
41
42
  protected addVideo(route: Route, isCurrent?: boolean, parent?: VideoState): Promise<void>;
42
43
  pause(): void;
44
+ resume(): void;
43
45
  getDisplayProperties(props: CurrentRideDisplayProps): RLVDisplayProps;
44
46
  protected getInfotextDisplayProps(): InfotextDisplayProps;
45
47
  protected checkFinishOptions(position: CurrentPosition): boolean;
@@ -62,6 +62,7 @@ let RLVDisplayService = (() => {
62
62
  super();
63
63
  this.currentVideo = __runInitializers(this, _instanceExtraInitializers);
64
64
  this.videosInitialized = false;
65
+ this.isVideoPaused = false;
65
66
  this.isInitialized = false;
66
67
  }
67
68
  initView() {
@@ -130,6 +131,12 @@ let RLVDisplayService = (() => {
130
131
  pause() {
131
132
  super.pause();
132
133
  this.currentVideo.syncHelper.pause();
134
+ this.isVideoPaused = true;
135
+ }
136
+ resume() {
137
+ super.resume();
138
+ this.currentVideo.syncHelper.resume();
139
+ this.isVideoPaused = false;
133
140
  }
134
141
  getDisplayProperties(props) {
135
142
  var _b, _c, _d, _e;
@@ -380,7 +387,9 @@ let RLVDisplayService = (() => {
380
387
  super.onActivityUpdate(activityPos, data);
381
388
  const offset = (_b = this.offset) !== null && _b !== void 0 ? _b : 0;
382
389
  const { routeDistance, speed } = activityPos;
383
- this.currentVideo.syncHelper.onActivityUpdate(routeDistance - offset, speed);
390
+ if (!this.isVideoPaused) {
391
+ this.currentVideo.syncHelper.onActivityUpdate(routeDistance - offset, speed);
392
+ }
384
393
  }
385
394
  initVideoSource(video) {
386
395
  var _b, _c;
@@ -176,6 +176,7 @@ export declare class RouteListService extends IncyclistService implements IRoute
176
176
  private selectListForSource;
177
177
  private addCustomList;
178
178
  createPreview(descr: RouteInfo): Promise<unknown>;
179
+ protected checkExistingPreviewFiles(descr: RouteInfo): Promise<string | undefined>;
179
180
  protected doCreatePreview(descr: RouteInfo): Promise<string>;
180
181
  protected processPreviewQueue(): PromiseObserver<void>;
181
182
  protected findCard(target: Route | string): {
@@ -993,6 +993,45 @@ let RouteListService = (() => {
993
993
  });
994
994
  });
995
995
  }
996
+ checkExistingPreviewFiles(descr) {
997
+ return __awaiter(this, void 0, void 0, function* () {
998
+ var _a;
999
+ const videoUrl = descr.videoUrl || descr.downloadUrl;
1000
+ const path = (0, api_1.getBindings)().path;
1001
+ const fs = (0, api_1.getBindings)().fs;
1002
+ let existingPreview;
1003
+ let fileUrl = false;
1004
+ try {
1005
+ let { dir, name } = (_a = path.parse(videoUrl)) !== null && _a !== void 0 ? _a : {};
1006
+ if (!dir.startsWith('htttp')) {
1007
+ if (dir.startsWith('video:')) {
1008
+ dir = dir.replace('video:', 'file:');
1009
+ }
1010
+ if (dir.startsWith('file:///')) {
1011
+ dir = dir.replace('file:///', '');
1012
+ fileUrl = true;
1013
+ }
1014
+ const check = (name) => __awaiter(this, void 0, void 0, function* () {
1015
+ if (existingPreview)
1016
+ return;
1017
+ if (yield fs.existsFile(name))
1018
+ existingPreview = name;
1019
+ });
1020
+ yield check(path.join(dir, 'preview.png'));
1021
+ yield check(path.join(dir, 'preview.jpg'));
1022
+ yield check(path.join(dir, `${name}_preview.png`));
1023
+ yield check(path.join(dir, `${name}_preview.jpg`));
1024
+ if (existingPreview) {
1025
+ this.logEvent({ message: 'found preview', title: descr.title, id: descr.id, video: videoUrl, existingPreview });
1026
+ descr.previewUrl = fileUrl ? `file:///${existingPreview}` : existingPreview;
1027
+ return descr.previewUrl;
1028
+ }
1029
+ }
1030
+ }
1031
+ catch (_b) {
1032
+ }
1033
+ });
1034
+ }
996
1035
  doCreatePreview(descr) {
997
1036
  return __awaiter(this, void 0, void 0, function* () {
998
1037
  let props;
@@ -1005,6 +1044,9 @@ let RouteListService = (() => {
1005
1044
  const fs = (0, api_1.getBindings)().fs;
1006
1045
  const outDir = path.join(appInfo.getAppDir(), 'previewImg');
1007
1046
  yield fs.ensureDir(outDir);
1047
+ const existing = yield this.checkExistingPreviewFiles(descr);
1048
+ if (existing)
1049
+ return existing;
1008
1050
  if (!videoUrl)
1009
1051
  return;
1010
1052
  if (videoUrl.startsWith('http')) {
@@ -24,12 +24,16 @@ class VideoSyncHelper extends service_1.IncyclistService {
24
24
  this.logPlaybackSummary();
25
25
  this.isPaused = true;
26
26
  this.send('rate-update', 0);
27
+ this.activityStatus.ts = Date.now();
28
+ this.rlvStatus.ts = Date.now();
27
29
  }
28
30
  resume() {
29
31
  if (this.isStopped)
30
32
  return;
31
33
  this.logEvent({ message: 'video resumed', route: this.route.details.title });
32
34
  this.isPaused = false;
35
+ this.activityStatus.ts = Date.now();
36
+ this.rlvStatus.ts = Date.now();
33
37
  }
34
38
  reset() {
35
39
  this.logEvent({ message: 'video reset', route: this.route.details.title });
@@ -64,7 +68,7 @@ class VideoSyncHelper extends service_1.IncyclistService {
64
68
  try {
65
69
  this.endTime = (_a = this.endTime) !== null && _a !== void 0 ? _a : this.getVideoTimeByPosition((_b = this.route.description) === null || _b === void 0 ? void 0 : _b.distance);
66
70
  const endTime = this.endTime;
67
- if (this.isStopped)
71
+ if (this.isStopped || this.isPaused)
68
72
  return;
69
73
  if (time > endTime - 0.3 && !this.loopMode && !this.rlvStatus.timeRequested) {
70
74
  this.updateRate(0);
@@ -305,6 +309,10 @@ class VideoSyncHelper extends service_1.IncyclistService {
305
309
  if (this.isPaused && rate > 0) {
306
310
  this.resume();
307
311
  }
312
+ else if (this.isPaused && rate === 0) {
313
+ delete this.rlvStatus.rateRequested;
314
+ return;
315
+ }
308
316
  this.rlvStatus.rateRequested = rate;
309
317
  this.send('rate-update', rate);
310
318
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.26"
6
6
  },
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "axios": "^1.8.2",
45
- "incyclist-devices": "^2.4.6-beta.3",
45
+ "incyclist-devices": "^2.4.7",
46
46
  "promise.any": "^2.0.6",
47
47
  "semver": "^7.6.3",
48
48
  "tcx-builder": "^1.1.1",