incyclist-services 1.7.45 → 1.7.46

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.
@@ -1,4 +1,11 @@
1
1
  "use strict";
2
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
3
+ var useValue = arguments.length > 2;
4
+ for (var i = 0; i < initializers.length; i++) {
5
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
6
+ }
7
+ return useValue ? value : void 0;
8
+ };
2
9
  var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
10
  function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
11
  var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
@@ -26,13 +33,6 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
26
33
  if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
34
  done = true;
28
35
  };
29
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
- var useValue = arguments.length > 2;
31
- for (var i = 0; i < initializers.length; i++) {
32
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
- }
34
- return useValue ? value : void 0;
35
- };
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.useRouteDownload = exports.RouteDownloadService = void 0;
38
38
  const api_1 = require("../../api");
@@ -49,16 +49,20 @@ let RouteDownloadService = (() => {
49
49
  let _classExtraInitializers = [];
50
50
  let _classThis;
51
51
  let _classSuper = service_1.IncyclistService;
52
+ let _instanceExtraInitializers = [];
53
+ let _getBindings_decorators;
52
54
  var RouteDownloadService = class extends _classSuper {
53
55
  static { _classThis = this; }
54
56
  static {
55
57
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
58
+ _getBindings_decorators = [decorators_1.Injectable];
59
+ __esDecorate(this, null, _getBindings_decorators, { kind: "method", name: "getBindings", static: false, private: false, access: { has: obj => "getBindings" in obj, get: obj => obj.getBindings }, metadata: _metadata }, null, _instanceExtraInitializers);
56
60
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
57
61
  RouteDownloadService = _classThis = _classDescriptor.value;
58
62
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
59
63
  __runInitializers(_classThis, _classExtraInitializers);
60
64
  }
61
- downloads;
65
+ downloads = __runInitializers(this, _instanceExtraInitializers);
62
66
  progressLogTs;
63
67
  constructor() {
64
68
  super('Routes');
@@ -97,7 +101,7 @@ let RouteDownloadService = (() => {
97
101
  if (file) {
98
102
  try {
99
103
  const fs = (0, api_1.getBindings)().fs;
100
- fs.unlink(file);
104
+ fs?.unlink(file);
101
105
  }
102
106
  catch (err) {
103
107
  this.logError(err, 'deleteIncompleteFile');
@@ -111,18 +115,35 @@ let RouteDownloadService = (() => {
111
115
  async _download(route) {
112
116
  await (0, utils_1.waitNextTick)();
113
117
  const observer = this.getObserver(route);
118
+ if (!observer)
119
+ return;
114
120
  try {
115
121
  const videoDir = await this.waitForVideoDir(observer);
116
- observer.once('stopped', () => {
117
- this.deleteIncompleteFile(route, videoDir);
118
- });
119
- this.downloadRoute(route, videoDir, observer);
122
+ if (videoDir) {
123
+ observer.once('stopped', () => {
124
+ this.deleteIncompleteFile(route, videoDir);
125
+ });
126
+ this.downloadRoute(route, videoDir, observer);
127
+ }
128
+ else {
129
+ this.logEvent({ message: 'could not start download', reason: 'video dir not specified' });
130
+ }
120
131
  }
121
132
  catch (err) {
122
133
  observer.emit('error', err);
123
134
  }
124
135
  }
125
136
  waitForVideoDir(observer) {
137
+ if (this.isMobile()) {
138
+ try {
139
+ const getVideoDir = this.getBindings()?.downloadManager?.getVideoDir;
140
+ if (getVideoDir) {
141
+ const videoDir = getVideoDir();
142
+ return Promise.resolve(videoDir);
143
+ }
144
+ }
145
+ catch { }
146
+ }
126
147
  const settings = (0, settings_1.useUserSettings)();
127
148
  const videoDir = settings.get('videos.directory', null);
128
149
  if (!videoDir) {
@@ -169,12 +190,12 @@ let RouteDownloadService = (() => {
169
190
  try {
170
191
  const { file, url, error } = await this.getDownloadFileName(route, targetDir);
171
192
  urlLog = url;
172
- if (!file || error) {
193
+ if (!file || error || !url) {
173
194
  observer.emit('error', new Error(error ?? 'download not supported'));
174
195
  return;
175
196
  }
176
197
  const { id, title } = route.description;
177
- const { downloadManager } = (0, api_1.getBindings)();
198
+ const { downloadManager } = this.getBindings();
178
199
  if (!downloadManager) {
179
200
  observer.emit('error', new Error('download not supported'));
180
201
  return;
@@ -207,20 +228,30 @@ let RouteDownloadService = (() => {
207
228
  }
208
229
  }
209
230
  async restoreFromRepo(route) {
231
+ if (!route?.description?.id)
232
+ return;
210
233
  await this.getRoutesApi().loadDetails([{ route, added: false }], true);
211
234
  await (0, utils_1.waitNextTick)();
212
235
  const descr = this.getRepo().getDescription(route.description.id);
213
236
  return descr?.downloadUrl || descr?.videoUrl;
214
237
  }
215
238
  onDownloadProgress(id, observer, pct, speed, downloaded) {
216
- const prev = this.progressLogTs[id] || 0;
217
- const ts = Date.now();
218
- if (ts - prev > 1000) {
219
- this.logEvent({ message: 'download progress', pctComplete: pct, downloaded, downloadSpeed: speed });
220
- this.progressLogTs[id] = ts;
239
+ if (!this.isMobile()) {
240
+ const prev = this.progressLogTs[id] || 0;
241
+ const ts = Date.now();
242
+ if (ts - prev > 5000) {
243
+ this.logEvent({ message: 'download progress', pctComplete: pct, downloaded, downloadSpeed: speed });
244
+ this.progressLogTs[id] = ts;
245
+ }
221
246
  }
222
247
  observer.emit('progress', Number(pct));
223
248
  }
249
+ isMobile() {
250
+ return this.getBindings()?.appInfo?.getChannel() === 'mobile';
251
+ }
252
+ getBindings() {
253
+ return (0, api_1.getBindings)();
254
+ }
224
255
  };
225
256
  return RouteDownloadService = _classThis;
226
257
  })();
@@ -98,7 +98,7 @@ let RouteCard = (() => {
98
98
  deleteObserver;
99
99
  ready;
100
100
  logger;
101
- cntActive;
101
+ cntActive = 0;
102
102
  constructor(route, props) {
103
103
  super();
104
104
  const { list } = props || {};
@@ -114,9 +114,11 @@ let RouteCard = (() => {
114
114
  }
115
115
  canStart(status) {
116
116
  try {
117
- const { isOnline } = status;
118
- const route = this.route.description;
119
- if (!route.hasVideo || !(route.isLocal || route.isDownloaded) || route.videoUrl.startsWith('http'))
117
+ const { isOnline } = status ?? {};
118
+ const route = this.route?.description;
119
+ if (!route)
120
+ return false;
121
+ if (!route.hasVideo || !(route.isLocal || route.isDownloaded) || route.videoUrl?.startsWith('http'))
120
122
  return isOnline;
121
123
  if (route.requiresDownload)
122
124
  return isOnline;
@@ -285,6 +287,7 @@ let RouteCard = (() => {
285
287
  }
286
288
  catch (err) {
287
289
  this.logError(err, 'getDisplayProperties');
290
+ return null;
288
291
  }
289
292
  }
290
293
  getMarkers(settings) {
@@ -294,7 +297,8 @@ let RouteCard = (() => {
294
297
  this.adjustStartPosAvi(startSettings);
295
298
  const startDistance = startSettings.startPos ?? 0;
296
299
  const startPos = (0, route_1.getPosition)(this.route, { distance: startDistance, nearest: true });
297
- markers.push(startPos);
300
+ if (startPos)
301
+ markers.push(startPos);
298
302
  }
299
303
  catch (err) {
300
304
  this.logError(err, 'getMarkers');
@@ -308,7 +312,9 @@ let RouteCard = (() => {
308
312
  if (startPos !== undefined && startPos !== null) {
309
313
  const startDistance = C(startPos.value, 'distance', { from: startPos.unit, to: 'm' });
310
314
  const position = (0, route_1.getPosition)(this.route, { distance: startDistance, nearest: true });
311
- markers.push(position);
315
+ if (position) {
316
+ markers.push(position);
317
+ }
312
318
  }
313
319
  }
314
320
  catch (err) {
@@ -517,7 +523,7 @@ let RouteCard = (() => {
517
523
  deleted = false;
518
524
  }
519
525
  finally {
520
- this.deleteObserver.emit('done', deleted);
526
+ this.deleteObserver?.emit('done', deleted);
521
527
  (0, utils_1.waitNextTick)().then(() => {
522
528
  delete this.deleteObserver;
523
529
  this.emitUpdate();
@@ -609,7 +615,7 @@ let RouteCard = (() => {
609
615
  return v;
610
616
  };
611
617
  (0, service_1.getRouteList)().logEvent({ message: 'download started', route: routeDescr?.title, videoUrl: lv(routeDescr?.videoUrl), downloadUrl: lv(routeDescr?.downloadUrl) });
612
- const dl = new service_2.RouteDownloadService();
618
+ const dl = this.getRouteDownload();
613
619
  this.downloadObserver = dl.download(this.route);
614
620
  this.downloadObserver
615
621
  .on('done', this.onDownloadCompleted.bind(this))
@@ -623,19 +629,41 @@ let RouteCard = (() => {
623
629
  }
624
630
  stopDownload(immediate = false) {
625
631
  try {
626
- (0, service_1.getRouteList)().logEvent({ message: 'download stopped', route: this.route?.description?.title });
627
- this.getCurrentDownload()?.stop();
632
+ (0, service_1.getRouteList)().logEvent({ message: 'download stopped', route: this.route?.description?.title, });
633
+ this.getRouteDownload().stopDownload(this.route);
628
634
  if (immediate) {
629
635
  delete this.downloadObserver;
630
636
  }
631
637
  else {
632
- (0, utils_1.waitNextTick)().then(() => { delete this.downloadObserver; });
638
+ (0, sleep_1.sleep)(5).then(() => { delete this.downloadObserver; });
633
639
  }
634
640
  }
635
641
  catch (err) {
636
642
  this.logError(err, 'stopDownload');
637
643
  }
638
644
  }
645
+ async deleteDownload() {
646
+ try {
647
+ const descr = this.getRouteDescription();
648
+ const videoUrl = descr.videoUrl;
649
+ if (videoUrl?.startsWith('video:///') || videoUrl?.startsWith('file:///')) {
650
+ const filePath = videoUrl.startsWith('video:///')
651
+ ? videoUrl.replace('video:///', '')
652
+ : videoUrl.replace('file:///', '');
653
+ const fs = (0, api_1.getBindings)().fs;
654
+ if (fs) {
655
+ const exists = await this.fileExists(filePath);
656
+ if (exists) {
657
+ await fs.unlink(filePath);
658
+ }
659
+ }
660
+ }
661
+ await this.resetDownload();
662
+ }
663
+ catch (err) {
664
+ this.logError(err, 'deleteDownload');
665
+ }
666
+ }
639
667
  async onDownloadCompleted(url) {
640
668
  try {
641
669
  (0, service_1.getRouteList)().logEvent({ message: 'download completed', route: this.route?.description?.title });
@@ -647,7 +675,7 @@ let RouteCard = (() => {
647
675
  this.route.details.video.file = undefined;
648
676
  this.route.details.video.url = url;
649
677
  this.updateRoute(this.route);
650
- (0, utils_1.waitNextTick)().then(() => {
678
+ (0, sleep_1.sleep)(5).then(() => {
651
679
  this.downloadObserver.reset();
652
680
  delete this.downloadObserver;
653
681
  });
@@ -677,7 +705,7 @@ let RouteCard = (() => {
677
705
  try {
678
706
  (0, service_1.getRouteList)().logEvent({ message: 'download failed', reason: err.message, route: this.route?.description?.title });
679
707
  this.downloadObserver.stop();
680
- (0, utils_1.waitNextTick)().then(() => {
708
+ (0, sleep_1.sleep)(5).then(() => {
681
709
  this.downloadObserver.reset();
682
710
  delete this.downloadObserver;
683
711
  });
@@ -882,6 +910,9 @@ let RouteCard = (() => {
882
910
  getOnlineStatusMonitoring() {
883
911
  return (0, monitoring_1.useOnlineStatusMonitoring)();
884
912
  }
913
+ getRouteDownload() {
914
+ return (0, service_2.useRouteDownload)();
915
+ }
885
916
  };
886
917
  })();
887
918
  exports.RouteCard = RouteCard;
@@ -84,6 +84,7 @@ let RoutesPageService = (() => {
84
84
  importProps;
85
85
  downloadCache;
86
86
  downloadHandlers;
87
+ downloadObserver = new types_1.Observer();
87
88
  constructor() {
88
89
  super('RoutesPage');
89
90
  this.downloadCache = new Map();
@@ -118,11 +119,11 @@ let RoutesPageService = (() => {
118
119
  catch (err) {
119
120
  this.logError(err, 'openPage');
120
121
  }
121
- return this.getPageObserver();
122
122
  }
123
123
  catch (err) {
124
124
  this.logError(err, 'openPage');
125
125
  }
126
+ return this.getPageObserver();
126
127
  }
127
128
  closePage() {
128
129
  try {
@@ -130,13 +131,14 @@ let RoutesPageService = (() => {
130
131
  this.logEvent({ message: 'page closed', page: 'Routes' });
131
132
  this.stopEventListener();
132
133
  this.downloadCache.clear();
134
+ this.downloadObserver.stop();
133
135
  super.closePage();
134
136
  }
135
137
  catch (err) {
136
138
  this.logError(err, 'closePage');
137
139
  }
138
140
  }
139
- pausePage() {
141
+ async pausePage() {
140
142
  try {
141
143
  this.stopEventListener();
142
144
  return super.pausePage();
@@ -145,7 +147,7 @@ let RoutesPageService = (() => {
145
147
  this.logError(err, 'pausePage');
146
148
  }
147
149
  }
148
- resumePage() {
150
+ async resumePage() {
149
151
  try {
150
152
  this.startEventListener();
151
153
  return super.resumePage();
@@ -164,7 +166,7 @@ let RoutesPageService = (() => {
164
166
  if (loading) {
165
167
  return { loading, synchronizing: false, routes: [], displayType,
166
168
  filters, filterVisible,
167
- downloadRows: this.getDownloadDisplayProps(),
169
+ downloadObserver: this.downloadObserver,
168
170
  showImportDialog: false };
169
171
  }
170
172
  else {
@@ -176,7 +178,7 @@ let RoutesPageService = (() => {
176
178
  return { loading, synchronizing, routes, displayType,
177
179
  filters, filterVisible, filterOptions,
178
180
  detailRouteId,
179
- downloadRows: this.getDownloadDisplayProps(),
181
+ downloadObserver: this.downloadObserver,
180
182
  showImportDialog: this.showImportDialog };
181
183
  }
182
184
  }
@@ -235,7 +237,8 @@ let RoutesPageService = (() => {
235
237
  try {
236
238
  const service = this.getRouteList();
237
239
  const pairing = this.getDevicePairing();
238
- const { id, title, videoUrl } = service.getStartSettings() ?? {};
240
+ const setttings = service.getStartSettings() ?? {};
241
+ const { id, title, videoUrl } = setttings;
239
242
  this.logEvent({ message: 'Attempting to start a ride', id, title, videoUrl, readyToStart: pairing.isReadyToStart(), });
240
243
  service.close();
241
244
  const next = pairing.isReadyToStart() ? '/rideDeviceOK' : '/pairingStart';
@@ -255,11 +258,11 @@ let RoutesPageService = (() => {
255
258
  imports.forEach((i) => {
256
259
  this.prepareSingleImport(i);
257
260
  });
258
- return this.importObserver;
259
261
  }
260
262
  catch (err) {
261
263
  this.logError(err, 'start');
262
264
  }
265
+ return this.importObserver;
263
266
  }
264
267
  onImportClosed() {
265
268
  try {
@@ -276,12 +279,7 @@ let RoutesPageService = (() => {
276
279
  }
277
280
  }
278
281
  getImportDisplayProps() {
279
- try {
280
- return this.importProps;
281
- }
282
- catch (err) {
283
- this.logError(err, 'getImportDisplayProps');
284
- }
282
+ return this.importProps;
285
283
  }
286
284
  getDownloadDisplayProps() {
287
285
  return Array.from(this.downloadCache.values());
@@ -290,7 +288,7 @@ let RoutesPageService = (() => {
290
288
  this.getPageObserver()?.emit('page-update');
291
289
  }
292
290
  getRoutesDisplayProps() {
293
- const { routes } = this.serviceState ?? {};
291
+ const { routes = [] } = this.serviceState ?? {};
294
292
  const getRouteProps = (routeProps) => {
295
293
  return {
296
294
  ...routeProps,
@@ -302,7 +300,7 @@ let RoutesPageService = (() => {
302
300
  return this.getRouteList().getFilters();
303
301
  }
304
302
  startEventListener() {
305
- const { observer } = this.serviceState;
303
+ const { observer } = this.serviceState ?? {};
306
304
  if (!observer)
307
305
  return;
308
306
  observer.on('updated', this.updateStateHandler);
@@ -314,7 +312,7 @@ let RoutesPageService = (() => {
314
312
  this.getRouteDownload().on('download-started', this.downloadStartedHandler);
315
313
  }
316
314
  stopEventListener(final) {
317
- const { observer } = this.serviceState;
315
+ const { observer } = this.serviceState ?? {};
318
316
  if (!observer)
319
317
  return;
320
318
  if (final)
@@ -328,29 +326,37 @@ let RoutesPageService = (() => {
328
326
  this.getRouteDownload().off('download-started', this.downloadStartedHandler);
329
327
  }
330
328
  subscribeToActiveDownload(route, observer) {
331
- const routeId = route.description.id;
332
- const title = route.description.title;
329
+ const routeId = route?.description?.id;
330
+ const title = route?.description?.title ?? '';
331
+ if (!routeId)
332
+ return;
333
333
  if (this.downloadHandlers.has(routeId))
334
334
  return;
335
335
  const onProgress = (pct) => {
336
336
  this.downloadCache.set(routeId, { routeId, title, status: 'downloading', pct });
337
- this.updatePageDisplay();
337
+ this.emitDownloadUpdate();
338
338
  };
339
339
  const onDone = () => {
340
340
  this.downloadCache.set(routeId, { routeId, title, status: 'done' });
341
341
  this.downloadHandlers.delete(routeId);
342
- this.updatePageDisplay();
342
+ this.emitDownloadUpdate();
343
343
  };
344
344
  const onError = () => {
345
345
  this.downloadCache.set(routeId, { routeId, title, status: 'failed' });
346
346
  this.downloadHandlers.delete(routeId);
347
- this.updatePageDisplay();
347
+ this.emitDownloadUpdate();
348
+ };
349
+ const onStopped = () => {
350
+ this.downloadCache.delete(routeId);
351
+ this.downloadHandlers.delete(routeId);
352
+ this.emitDownloadUpdate();
348
353
  };
349
- this.downloadHandlers.set(routeId, { onProgress, onDone, onError });
354
+ this.downloadHandlers.set(routeId, { onProgress, onDone, onError, onStopped });
350
355
  this.downloadCache.set(routeId, { routeId, title, status: 'downloading' });
351
356
  observer.on('progress', onProgress);
352
357
  observer.on('done', onDone);
353
358
  observer.on('error', onError);
359
+ observer.on('stopped', onStopped);
354
360
  this.updatePageDisplay();
355
361
  }
356
362
  subscribeAllActiveDownloads() {
@@ -361,12 +367,15 @@ let RoutesPageService = (() => {
361
367
  unsubscribeAllActiveDownloads() {
362
368
  const active = this.getRouteDownload().getActiveDownloads();
363
369
  for (const { route, observer } of active) {
364
- const routeId = route.description.id;
365
- const handlers = this.downloadHandlers.get(routeId);
366
- if (handlers) {
367
- observer.off('progress', handlers.onProgress);
368
- observer.off('done', handlers.onDone);
369
- observer.off('error', handlers.onError);
370
+ const routeId = route?.description?.id;
371
+ if (routeId) {
372
+ const handlers = this.downloadHandlers.get(routeId);
373
+ if (handlers) {
374
+ observer.off('progress', handlers.onProgress);
375
+ observer.off('done', handlers.onDone);
376
+ observer.off('error', handlers.onError);
377
+ observer.off('stopped', handlers.onStopped);
378
+ }
370
379
  }
371
380
  }
372
381
  this.downloadHandlers.clear();
@@ -374,6 +383,13 @@ let RoutesPageService = (() => {
374
383
  downloadStartedHandler = (route, observer) => {
375
384
  this.subscribeToActiveDownload(route, observer);
376
385
  };
386
+ emitDownloadUpdate() {
387
+ this.downloadObserver.emit('download-update', {
388
+ rows: this.getDownloadDisplayProps(),
389
+ count: Array.from(this.downloadCache.values())
390
+ .filter(r => r.status === 'downloading').length
391
+ });
392
+ }
377
393
  onSycncStart() {
378
394
  this.updatePageDisplay();
379
395
  }
@@ -384,8 +400,7 @@ let RoutesPageService = (() => {
384
400
  this.updatePageDisplay();
385
401
  }
386
402
  onDialogClosed() {
387
- const route = this.getRouteList().getSelected();
388
- this.detailRouteId = null;
403
+ this.detailRouteId = undefined;
389
404
  this.updatePageDisplay();
390
405
  }
391
406
  prepareSingleImport(file) {
@@ -395,6 +410,7 @@ let RoutesPageService = (() => {
395
410
  status: 'idle',
396
411
  fileName: file.name
397
412
  };
413
+ this.importProps = this.importProps ?? [];
398
414
  this.importProps.push(props);
399
415
  observer.once('success', () => {
400
416
  props.status = 'success';
@@ -1,3 +1,10 @@
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
1
8
  var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
9
  function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
10
  var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
@@ -25,15 +32,8 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
25
32
  if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
33
  done = true;
27
34
  };
28
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
- var useValue = arguments.length > 2;
30
- for (var i = 0; i < initializers.length; i++) {
31
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
- }
33
- return useValue ? value : void 0;
34
- };
35
35
  import { getBindings } from "../../api";
36
- import { Singleton } from "../../base/decorators";
36
+ import { Injectable, Singleton } from "../../base/decorators";
37
37
  import { IncyclistService } from "../../base/service";
38
38
  import { useUserSettings } from "../../settings";
39
39
  import { waitNextTick } from "../../utils";
@@ -46,16 +46,20 @@ let RouteDownloadService = (() => {
46
46
  let _classExtraInitializers = [];
47
47
  let _classThis;
48
48
  let _classSuper = IncyclistService;
49
+ let _instanceExtraInitializers = [];
50
+ let _getBindings_decorators;
49
51
  var RouteDownloadService = class extends _classSuper {
50
52
  static { _classThis = this; }
51
53
  static {
52
54
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
55
+ _getBindings_decorators = [Injectable];
56
+ __esDecorate(this, null, _getBindings_decorators, { kind: "method", name: "getBindings", static: false, private: false, access: { has: obj => "getBindings" in obj, get: obj => obj.getBindings }, metadata: _metadata }, null, _instanceExtraInitializers);
53
57
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
54
58
  RouteDownloadService = _classThis = _classDescriptor.value;
55
59
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
56
60
  __runInitializers(_classThis, _classExtraInitializers);
57
61
  }
58
- downloads;
62
+ downloads = __runInitializers(this, _instanceExtraInitializers);
59
63
  progressLogTs;
60
64
  constructor() {
61
65
  super('Routes');
@@ -94,7 +98,7 @@ let RouteDownloadService = (() => {
94
98
  if (file) {
95
99
  try {
96
100
  const fs = getBindings().fs;
97
- fs.unlink(file);
101
+ fs?.unlink(file);
98
102
  }
99
103
  catch (err) {
100
104
  this.logError(err, 'deleteIncompleteFile');
@@ -108,18 +112,35 @@ let RouteDownloadService = (() => {
108
112
  async _download(route) {
109
113
  await waitNextTick();
110
114
  const observer = this.getObserver(route);
115
+ if (!observer)
116
+ return;
111
117
  try {
112
118
  const videoDir = await this.waitForVideoDir(observer);
113
- observer.once('stopped', () => {
114
- this.deleteIncompleteFile(route, videoDir);
115
- });
116
- this.downloadRoute(route, videoDir, observer);
119
+ if (videoDir) {
120
+ observer.once('stopped', () => {
121
+ this.deleteIncompleteFile(route, videoDir);
122
+ });
123
+ this.downloadRoute(route, videoDir, observer);
124
+ }
125
+ else {
126
+ this.logEvent({ message: 'could not start download', reason: 'video dir not specified' });
127
+ }
117
128
  }
118
129
  catch (err) {
119
130
  observer.emit('error', err);
120
131
  }
121
132
  }
122
133
  waitForVideoDir(observer) {
134
+ if (this.isMobile()) {
135
+ try {
136
+ const getVideoDir = this.getBindings()?.downloadManager?.getVideoDir;
137
+ if (getVideoDir) {
138
+ const videoDir = getVideoDir();
139
+ return Promise.resolve(videoDir);
140
+ }
141
+ }
142
+ catch { }
143
+ }
123
144
  const settings = useUserSettings();
124
145
  const videoDir = settings.get('videos.directory', null);
125
146
  if (!videoDir) {
@@ -166,12 +187,12 @@ let RouteDownloadService = (() => {
166
187
  try {
167
188
  const { file, url, error } = await this.getDownloadFileName(route, targetDir);
168
189
  urlLog = url;
169
- if (!file || error) {
190
+ if (!file || error || !url) {
170
191
  observer.emit('error', new Error(error ?? 'download not supported'));
171
192
  return;
172
193
  }
173
194
  const { id, title } = route.description;
174
- const { downloadManager } = getBindings();
195
+ const { downloadManager } = this.getBindings();
175
196
  if (!downloadManager) {
176
197
  observer.emit('error', new Error('download not supported'));
177
198
  return;
@@ -204,20 +225,30 @@ let RouteDownloadService = (() => {
204
225
  }
205
226
  }
206
227
  async restoreFromRepo(route) {
228
+ if (!route?.description?.id)
229
+ return;
207
230
  await this.getRoutesApi().loadDetails([{ route, added: false }], true);
208
231
  await waitNextTick();
209
232
  const descr = this.getRepo().getDescription(route.description.id);
210
233
  return descr?.downloadUrl || descr?.videoUrl;
211
234
  }
212
235
  onDownloadProgress(id, observer, pct, speed, downloaded) {
213
- const prev = this.progressLogTs[id] || 0;
214
- const ts = Date.now();
215
- if (ts - prev > 1000) {
216
- this.logEvent({ message: 'download progress', pctComplete: pct, downloaded, downloadSpeed: speed });
217
- this.progressLogTs[id] = ts;
236
+ if (!this.isMobile()) {
237
+ const prev = this.progressLogTs[id] || 0;
238
+ const ts = Date.now();
239
+ if (ts - prev > 5000) {
240
+ this.logEvent({ message: 'download progress', pctComplete: pct, downloaded, downloadSpeed: speed });
241
+ this.progressLogTs[id] = ts;
242
+ }
218
243
  }
219
244
  observer.emit('progress', Number(pct));
220
245
  }
246
+ isMobile() {
247
+ return this.getBindings()?.appInfo?.getChannel() === 'mobile';
248
+ }
249
+ getBindings() {
250
+ return getBindings();
251
+ }
221
252
  };
222
253
  return RouteDownloadService = _classThis;
223
254
  })();
@@ -41,7 +41,7 @@ import { getRouteList, useRouteList } from "../service";
41
41
  import { RoutesDbLoader } from "../loaders/db";
42
42
  import { valid } from "../../../utils/valid";
43
43
  import { waitNextTick } from "../../../utils";
44
- import { RouteDownloadService } from "../../download/service";
44
+ import { useRouteDownload } from "../../download/service";
45
45
  import { EventLogger } from "gd-eventlog";
46
46
  import { checkIsLoop, getNextVideoId, getPosition, updateSlopes } from "../../base/utils/route";
47
47
  import { getWorkoutList } from "../../../workouts";
@@ -95,7 +95,7 @@ let RouteCard = (() => {
95
95
  deleteObserver;
96
96
  ready;
97
97
  logger;
98
- cntActive;
98
+ cntActive = 0;
99
99
  constructor(route, props) {
100
100
  super();
101
101
  const { list } = props || {};
@@ -111,9 +111,11 @@ let RouteCard = (() => {
111
111
  }
112
112
  canStart(status) {
113
113
  try {
114
- const { isOnline } = status;
115
- const route = this.route.description;
116
- if (!route.hasVideo || !(route.isLocal || route.isDownloaded) || route.videoUrl.startsWith('http'))
114
+ const { isOnline } = status ?? {};
115
+ const route = this.route?.description;
116
+ if (!route)
117
+ return false;
118
+ if (!route.hasVideo || !(route.isLocal || route.isDownloaded) || route.videoUrl?.startsWith('http'))
117
119
  return isOnline;
118
120
  if (route.requiresDownload)
119
121
  return isOnline;
@@ -282,6 +284,7 @@ let RouteCard = (() => {
282
284
  }
283
285
  catch (err) {
284
286
  this.logError(err, 'getDisplayProperties');
287
+ return null;
285
288
  }
286
289
  }
287
290
  getMarkers(settings) {
@@ -291,7 +294,8 @@ let RouteCard = (() => {
291
294
  this.adjustStartPosAvi(startSettings);
292
295
  const startDistance = startSettings.startPos ?? 0;
293
296
  const startPos = getPosition(this.route, { distance: startDistance, nearest: true });
294
- markers.push(startPos);
297
+ if (startPos)
298
+ markers.push(startPos);
295
299
  }
296
300
  catch (err) {
297
301
  this.logError(err, 'getMarkers');
@@ -305,7 +309,9 @@ let RouteCard = (() => {
305
309
  if (startPos !== undefined && startPos !== null) {
306
310
  const startDistance = C(startPos.value, 'distance', { from: startPos.unit, to: 'm' });
307
311
  const position = getPosition(this.route, { distance: startDistance, nearest: true });
308
- markers.push(position);
312
+ if (position) {
313
+ markers.push(position);
314
+ }
309
315
  }
310
316
  }
311
317
  catch (err) {
@@ -514,7 +520,7 @@ let RouteCard = (() => {
514
520
  deleted = false;
515
521
  }
516
522
  finally {
517
- this.deleteObserver.emit('done', deleted);
523
+ this.deleteObserver?.emit('done', deleted);
518
524
  waitNextTick().then(() => {
519
525
  delete this.deleteObserver;
520
526
  this.emitUpdate();
@@ -606,7 +612,7 @@ let RouteCard = (() => {
606
612
  return v;
607
613
  };
608
614
  getRouteList().logEvent({ message: 'download started', route: routeDescr?.title, videoUrl: lv(routeDescr?.videoUrl), downloadUrl: lv(routeDescr?.downloadUrl) });
609
- const dl = new RouteDownloadService();
615
+ const dl = this.getRouteDownload();
610
616
  this.downloadObserver = dl.download(this.route);
611
617
  this.downloadObserver
612
618
  .on('done', this.onDownloadCompleted.bind(this))
@@ -620,19 +626,41 @@ let RouteCard = (() => {
620
626
  }
621
627
  stopDownload(immediate = false) {
622
628
  try {
623
- getRouteList().logEvent({ message: 'download stopped', route: this.route?.description?.title });
624
- this.getCurrentDownload()?.stop();
629
+ getRouteList().logEvent({ message: 'download stopped', route: this.route?.description?.title, });
630
+ this.getRouteDownload().stopDownload(this.route);
625
631
  if (immediate) {
626
632
  delete this.downloadObserver;
627
633
  }
628
634
  else {
629
- waitNextTick().then(() => { delete this.downloadObserver; });
635
+ sleep(5).then(() => { delete this.downloadObserver; });
630
636
  }
631
637
  }
632
638
  catch (err) {
633
639
  this.logError(err, 'stopDownload');
634
640
  }
635
641
  }
642
+ async deleteDownload() {
643
+ try {
644
+ const descr = this.getRouteDescription();
645
+ const videoUrl = descr.videoUrl;
646
+ if (videoUrl?.startsWith('video:///') || videoUrl?.startsWith('file:///')) {
647
+ const filePath = videoUrl.startsWith('video:///')
648
+ ? videoUrl.replace('video:///', '')
649
+ : videoUrl.replace('file:///', '');
650
+ const fs = getBindings().fs;
651
+ if (fs) {
652
+ const exists = await this.fileExists(filePath);
653
+ if (exists) {
654
+ await fs.unlink(filePath);
655
+ }
656
+ }
657
+ }
658
+ await this.resetDownload();
659
+ }
660
+ catch (err) {
661
+ this.logError(err, 'deleteDownload');
662
+ }
663
+ }
636
664
  async onDownloadCompleted(url) {
637
665
  try {
638
666
  getRouteList().logEvent({ message: 'download completed', route: this.route?.description?.title });
@@ -644,7 +672,7 @@ let RouteCard = (() => {
644
672
  this.route.details.video.file = undefined;
645
673
  this.route.details.video.url = url;
646
674
  this.updateRoute(this.route);
647
- waitNextTick().then(() => {
675
+ sleep(5).then(() => {
648
676
  this.downloadObserver.reset();
649
677
  delete this.downloadObserver;
650
678
  });
@@ -674,7 +702,7 @@ let RouteCard = (() => {
674
702
  try {
675
703
  getRouteList().logEvent({ message: 'download failed', reason: err.message, route: this.route?.description?.title });
676
704
  this.downloadObserver.stop();
677
- waitNextTick().then(() => {
705
+ sleep(5).then(() => {
678
706
  this.downloadObserver.reset();
679
707
  delete this.downloadObserver;
680
708
  });
@@ -879,6 +907,9 @@ let RouteCard = (() => {
879
907
  getOnlineStatusMonitoring() {
880
908
  return useOnlineStatusMonitoring();
881
909
  }
910
+ getRouteDownload() {
911
+ return useRouteDownload();
912
+ }
882
913
  };
883
914
  })();
884
915
  export { RouteCard };
@@ -81,6 +81,7 @@ let RoutesPageService = (() => {
81
81
  importProps;
82
82
  downloadCache;
83
83
  downloadHandlers;
84
+ downloadObserver = new Observer();
84
85
  constructor() {
85
86
  super('RoutesPage');
86
87
  this.downloadCache = new Map();
@@ -115,11 +116,11 @@ let RoutesPageService = (() => {
115
116
  catch (err) {
116
117
  this.logError(err, 'openPage');
117
118
  }
118
- return this.getPageObserver();
119
119
  }
120
120
  catch (err) {
121
121
  this.logError(err, 'openPage');
122
122
  }
123
+ return this.getPageObserver();
123
124
  }
124
125
  closePage() {
125
126
  try {
@@ -127,13 +128,14 @@ let RoutesPageService = (() => {
127
128
  this.logEvent({ message: 'page closed', page: 'Routes' });
128
129
  this.stopEventListener();
129
130
  this.downloadCache.clear();
131
+ this.downloadObserver.stop();
130
132
  super.closePage();
131
133
  }
132
134
  catch (err) {
133
135
  this.logError(err, 'closePage');
134
136
  }
135
137
  }
136
- pausePage() {
138
+ async pausePage() {
137
139
  try {
138
140
  this.stopEventListener();
139
141
  return super.pausePage();
@@ -142,7 +144,7 @@ let RoutesPageService = (() => {
142
144
  this.logError(err, 'pausePage');
143
145
  }
144
146
  }
145
- resumePage() {
147
+ async resumePage() {
146
148
  try {
147
149
  this.startEventListener();
148
150
  return super.resumePage();
@@ -161,7 +163,7 @@ let RoutesPageService = (() => {
161
163
  if (loading) {
162
164
  return { loading, synchronizing: false, routes: [], displayType,
163
165
  filters, filterVisible,
164
- downloadRows: this.getDownloadDisplayProps(),
166
+ downloadObserver: this.downloadObserver,
165
167
  showImportDialog: false };
166
168
  }
167
169
  else {
@@ -173,7 +175,7 @@ let RoutesPageService = (() => {
173
175
  return { loading, synchronizing, routes, displayType,
174
176
  filters, filterVisible, filterOptions,
175
177
  detailRouteId,
176
- downloadRows: this.getDownloadDisplayProps(),
178
+ downloadObserver: this.downloadObserver,
177
179
  showImportDialog: this.showImportDialog };
178
180
  }
179
181
  }
@@ -232,7 +234,8 @@ let RoutesPageService = (() => {
232
234
  try {
233
235
  const service = this.getRouteList();
234
236
  const pairing = this.getDevicePairing();
235
- const { id, title, videoUrl } = service.getStartSettings() ?? {};
237
+ const setttings = service.getStartSettings() ?? {};
238
+ const { id, title, videoUrl } = setttings;
236
239
  this.logEvent({ message: 'Attempting to start a ride', id, title, videoUrl, readyToStart: pairing.isReadyToStart(), });
237
240
  service.close();
238
241
  const next = pairing.isReadyToStart() ? '/rideDeviceOK' : '/pairingStart';
@@ -252,11 +255,11 @@ let RoutesPageService = (() => {
252
255
  imports.forEach((i) => {
253
256
  this.prepareSingleImport(i);
254
257
  });
255
- return this.importObserver;
256
258
  }
257
259
  catch (err) {
258
260
  this.logError(err, 'start');
259
261
  }
262
+ return this.importObserver;
260
263
  }
261
264
  onImportClosed() {
262
265
  try {
@@ -273,12 +276,7 @@ let RoutesPageService = (() => {
273
276
  }
274
277
  }
275
278
  getImportDisplayProps() {
276
- try {
277
- return this.importProps;
278
- }
279
- catch (err) {
280
- this.logError(err, 'getImportDisplayProps');
281
- }
279
+ return this.importProps;
282
280
  }
283
281
  getDownloadDisplayProps() {
284
282
  return Array.from(this.downloadCache.values());
@@ -287,7 +285,7 @@ let RoutesPageService = (() => {
287
285
  this.getPageObserver()?.emit('page-update');
288
286
  }
289
287
  getRoutesDisplayProps() {
290
- const { routes } = this.serviceState ?? {};
288
+ const { routes = [] } = this.serviceState ?? {};
291
289
  const getRouteProps = (routeProps) => {
292
290
  return {
293
291
  ...routeProps,
@@ -299,7 +297,7 @@ let RoutesPageService = (() => {
299
297
  return this.getRouteList().getFilters();
300
298
  }
301
299
  startEventListener() {
302
- const { observer } = this.serviceState;
300
+ const { observer } = this.serviceState ?? {};
303
301
  if (!observer)
304
302
  return;
305
303
  observer.on('updated', this.updateStateHandler);
@@ -311,7 +309,7 @@ let RoutesPageService = (() => {
311
309
  this.getRouteDownload().on('download-started', this.downloadStartedHandler);
312
310
  }
313
311
  stopEventListener(final) {
314
- const { observer } = this.serviceState;
312
+ const { observer } = this.serviceState ?? {};
315
313
  if (!observer)
316
314
  return;
317
315
  if (final)
@@ -325,29 +323,37 @@ let RoutesPageService = (() => {
325
323
  this.getRouteDownload().off('download-started', this.downloadStartedHandler);
326
324
  }
327
325
  subscribeToActiveDownload(route, observer) {
328
- const routeId = route.description.id;
329
- const title = route.description.title;
326
+ const routeId = route?.description?.id;
327
+ const title = route?.description?.title ?? '';
328
+ if (!routeId)
329
+ return;
330
330
  if (this.downloadHandlers.has(routeId))
331
331
  return;
332
332
  const onProgress = (pct) => {
333
333
  this.downloadCache.set(routeId, { routeId, title, status: 'downloading', pct });
334
- this.updatePageDisplay();
334
+ this.emitDownloadUpdate();
335
335
  };
336
336
  const onDone = () => {
337
337
  this.downloadCache.set(routeId, { routeId, title, status: 'done' });
338
338
  this.downloadHandlers.delete(routeId);
339
- this.updatePageDisplay();
339
+ this.emitDownloadUpdate();
340
340
  };
341
341
  const onError = () => {
342
342
  this.downloadCache.set(routeId, { routeId, title, status: 'failed' });
343
343
  this.downloadHandlers.delete(routeId);
344
- this.updatePageDisplay();
344
+ this.emitDownloadUpdate();
345
+ };
346
+ const onStopped = () => {
347
+ this.downloadCache.delete(routeId);
348
+ this.downloadHandlers.delete(routeId);
349
+ this.emitDownloadUpdate();
345
350
  };
346
- this.downloadHandlers.set(routeId, { onProgress, onDone, onError });
351
+ this.downloadHandlers.set(routeId, { onProgress, onDone, onError, onStopped });
347
352
  this.downloadCache.set(routeId, { routeId, title, status: 'downloading' });
348
353
  observer.on('progress', onProgress);
349
354
  observer.on('done', onDone);
350
355
  observer.on('error', onError);
356
+ observer.on('stopped', onStopped);
351
357
  this.updatePageDisplay();
352
358
  }
353
359
  subscribeAllActiveDownloads() {
@@ -358,12 +364,15 @@ let RoutesPageService = (() => {
358
364
  unsubscribeAllActiveDownloads() {
359
365
  const active = this.getRouteDownload().getActiveDownloads();
360
366
  for (const { route, observer } of active) {
361
- const routeId = route.description.id;
362
- const handlers = this.downloadHandlers.get(routeId);
363
- if (handlers) {
364
- observer.off('progress', handlers.onProgress);
365
- observer.off('done', handlers.onDone);
366
- observer.off('error', handlers.onError);
367
+ const routeId = route?.description?.id;
368
+ if (routeId) {
369
+ const handlers = this.downloadHandlers.get(routeId);
370
+ if (handlers) {
371
+ observer.off('progress', handlers.onProgress);
372
+ observer.off('done', handlers.onDone);
373
+ observer.off('error', handlers.onError);
374
+ observer.off('stopped', handlers.onStopped);
375
+ }
367
376
  }
368
377
  }
369
378
  this.downloadHandlers.clear();
@@ -371,6 +380,13 @@ let RoutesPageService = (() => {
371
380
  downloadStartedHandler = (route, observer) => {
372
381
  this.subscribeToActiveDownload(route, observer);
373
382
  };
383
+ emitDownloadUpdate() {
384
+ this.downloadObserver.emit('download-update', {
385
+ rows: this.getDownloadDisplayProps(),
386
+ count: Array.from(this.downloadCache.values())
387
+ .filter(r => r.status === 'downloading').length
388
+ });
389
+ }
374
390
  onSycncStart() {
375
391
  this.updatePageDisplay();
376
392
  }
@@ -381,8 +397,7 @@ let RoutesPageService = (() => {
381
397
  this.updatePageDisplay();
382
398
  }
383
399
  onDialogClosed() {
384
- const route = this.getRouteList().getSelected();
385
- this.detailRouteId = null;
400
+ this.detailRouteId = undefined;
386
401
  this.updatePageDisplay();
387
402
  }
388
403
  prepareSingleImport(file) {
@@ -392,6 +407,7 @@ let RoutesPageService = (() => {
392
407
  status: 'idle',
393
408
  fileName: file.name
394
409
  };
410
+ this.importProps = this.importProps ?? [];
395
411
  this.importProps.push(props);
396
412
  observer.once('success', () => {
397
413
  props.status = 'success';
@@ -8,4 +8,5 @@ export interface IDownloadSession extends EventEmitter {
8
8
  }
9
9
  export interface IDownloadManager {
10
10
  createSession(url: string, fileName: string, props?: DownloadProps): IDownloadSession;
11
+ getVideoDir?(): string;
11
12
  }
@@ -21,7 +21,7 @@ export declare class RouteDownloadService extends IncyclistService {
21
21
  protected deleteIncompleteFile(route: Route, videoDir: string): Promise<void>;
22
22
  protected getObserver(route: Route): DownloadObserver;
23
23
  protected _download(route: Route): Promise<void>;
24
- protected waitForVideoDir(observer: DownloadObserver): any;
24
+ protected waitForVideoDir(observer: DownloadObserver): Promise<string | undefined>;
25
25
  protected getDownloadFileName(route: Route, targetDir: string): Promise<{
26
26
  file?: string;
27
27
  url?: string;
@@ -29,6 +29,8 @@ export declare class RouteDownloadService extends IncyclistService {
29
29
  }>;
30
30
  protected downloadRoute(route: Route, targetDir: string, observer: DownloadObserver): Promise<void>;
31
31
  protected restoreFromRepo(route: Route): Promise<string>;
32
- protected onDownloadProgress(id: string, observer: DownloadObserver, pct: any, speed: any, downloaded: any): void;
32
+ protected onDownloadProgress(id: string, observer: DownloadObserver, pct: number | string, speed: number | string, downloaded: number | string): void;
33
+ protected isMobile(): boolean;
34
+ protected getBindings(): import("../../api").IncyclistBindings;
33
35
  }
34
36
  export declare const useRouteDownload: () => RouteDownloadService;
@@ -16,20 +16,20 @@ export declare const DEFAULT_FILTERS: {
16
16
  extensions: string[];
17
17
  }[];
18
18
  declare class ConvertObserver extends Observer {
19
- protected conversion: Observer;
19
+ protected conversion?: Observer;
20
20
  constructor();
21
21
  setConversion(conversion: Observer): void;
22
22
  stop(): void;
23
23
  }
24
24
  export declare class RouteCard extends BaseCard implements Card<Route> {
25
- protected downloadObserver: DownloadObserver;
26
- protected convertObserver: ConvertObserver;
25
+ protected downloadObserver?: DownloadObserver;
26
+ protected convertObserver?: ConvertObserver;
27
27
  protected route: Route;
28
- protected list: CardList<Route>;
28
+ protected list?: CardList<Route>;
29
29
  protected deleteable: boolean;
30
- protected startSettings: RouteSettings;
30
+ protected startSettings?: RouteSettings;
31
31
  protected cardObserver: Observer;
32
- protected deleteObserver: PromiseObserver<boolean>;
32
+ protected deleteObserver?: PromiseObserver<boolean>;
33
33
  protected ready: boolean;
34
34
  protected logger: EventLogger;
35
35
  protected cntActive: number;
@@ -42,7 +42,7 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
42
42
  verify(): void;
43
43
  protected isVideoMissing(): Promise<boolean>;
44
44
  videoExists(): Promise<boolean>;
45
- protected fileExists(path: any): Promise<boolean>;
45
+ protected fileExists(path: string): Promise<boolean>;
46
46
  cleanupEncoding(path: string): string;
47
47
  previewMissing(): boolean;
48
48
  setInitialized(init: boolean): void;
@@ -84,6 +84,7 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
84
84
  onVideoSelected(info: FileInfo): Promise<"Could not open file" | "Unsupported video format - Please select MP4 or AVI">;
85
85
  download(): Observer;
86
86
  stopDownload(immediate?: boolean): void;
87
+ deleteDownload(): Promise<void>;
87
88
  protected onDownloadCompleted(url: string): Promise<void>;
88
89
  private saveOriginalVideoUrl;
89
90
  private restoreVideoUrl;
@@ -113,5 +114,6 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
113
114
  protected isMobile(): boolean;
114
115
  protected getBindings(): import("../../../api").IncyclistBindings;
115
116
  protected getOnlineStatusMonitoring(): import("../../../monitoring").OnlineStateMonitoringService;
117
+ protected getRouteDownload(): import("../../download/service").RouteDownloadService;
116
118
  }
117
119
  export {};
@@ -2,6 +2,7 @@ import { ImportFilter } from "../../../base/cardlist/types";
2
2
  import { Observer } from "../../../base/types/observer";
3
3
  import { Unit } from "../../../i18n";
4
4
  import { RouteInfo } from "../../base/types";
5
+ import { DownloadObserver } from "../../download/types";
5
6
  import { RouteStartSettings } from "../types";
6
7
  export type RouteCardType = 'Import' | 'Route' | 'Free-Ride' | 'ActiveImport';
7
8
  export interface RouteImportProps {
@@ -26,14 +27,15 @@ export interface SummaryCardDisplayProps extends RouteInfo {
26
27
  loading?: boolean;
27
28
  isNew?: boolean;
28
29
  cntActive?: number;
29
- totalDistance: {
30
+ totalDistance?: {
30
31
  value: number;
31
32
  unit: Unit;
32
33
  };
33
- totalElevation: {
34
+ totalElevation?: {
34
35
  value: number;
35
36
  unit: Unit;
36
37
  };
38
+ downloadObserver?: DownloadObserver;
37
39
  }
38
40
  export interface DetailCardDisplayProps {
39
41
  }
@@ -6,7 +6,7 @@ import { Observer } from "../../base/types";
6
6
  import { Route } from "../base/model/route";
7
7
  import { DownloadObserver } from "../download/types";
8
8
  export declare class RoutesPageService extends IncyclistPageService implements IRoutePageService {
9
- protected serviceState: SearchState;
9
+ protected serviceState: SearchState | undefined;
10
10
  protected detailRouteId: string | undefined;
11
11
  protected updateStateHandler: any;
12
12
  protected syncStartHandler: any;
@@ -14,13 +14,15 @@ export declare class RoutesPageService extends IncyclistPageService implements I
14
14
  protected updateSelectStateHandler: any;
15
15
  protected showImportDialog: boolean;
16
16
  protected importObserver: Observer | undefined;
17
- protected importProps: Array<RouteImportDisplayProps>;
17
+ protected importProps: Array<RouteImportDisplayProps> | undefined;
18
18
  protected downloadCache: Map<string, DownloadRowDisplayProps>;
19
19
  protected downloadHandlers: Map<string, {
20
20
  onProgress: (pct: number) => void;
21
21
  onDone: () => void;
22
22
  onError: () => void;
23
+ onStopped: () => void;
23
24
  }>;
25
+ protected downloadObserver: Observer;
24
26
  constructor();
25
27
  openPage(): IObserver;
26
28
  closePage(): void;
@@ -46,6 +48,7 @@ export declare class RoutesPageService extends IncyclistPageService implements I
46
48
  protected subscribeAllActiveDownloads(): void;
47
49
  protected unsubscribeAllActiveDownloads(): void;
48
50
  protected downloadStartedHandler: (route: Route, observer: DownloadObserver) => void;
51
+ protected emitDownloadUpdate(): void;
49
52
  protected onSycncStart(): void;
50
53
  protected onSyncStop(): void;
51
54
  protected onStateUpdate(): void;
@@ -13,13 +13,13 @@ export interface RoutePageDisplayProps {
13
13
  filterOptions?: SearchFilterOptions;
14
14
  routes?: Array<RouteItemProps>;
15
15
  detailRouteId?: string;
16
- downloadRows?: DownloadRowDisplayProps[];
16
+ downloadObserver?: IObserver;
17
17
  showImportDialog?: boolean;
18
18
  }
19
19
  export interface RouteItemProps extends SummaryCardDisplayProps {
20
20
  }
21
21
  export interface IPageCallBacks {
22
- onFilterChanged(filters: SearchFilter): any;
22
+ onFilterChanged(filters: SearchFilter): void;
23
23
  onImportClicked(): void;
24
24
  onFilterVisibleChange(visible: boolean): void;
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.7.45",
3
+ "version": "1.7.46",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.27"
6
6
  },