incyclist-services 1.7.107 → 1.7.109

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.
@@ -260,9 +260,10 @@ let Activity = (() => {
260
260
  }
261
261
  getUploadStatus() {
262
262
  const uploads = [];
263
+ const stillLoading = !this.details && this.isLoading();
263
264
  const services = this.getAppsService().getConnectedServices('ActivityUpload');
264
265
  services.forEach(service => {
265
- let status = 'unknown';
266
+ let status = stillLoading ? 'loading' : 'unknown';
266
267
  const info = this.details?.links?.[service.key];
267
268
  if (info) {
268
269
  status = (info.error || !info.activity_id) ? 'failed' : 'success';
@@ -258,6 +258,7 @@ let ActivityListService = (() => {
258
258
  if (!activity) {
259
259
  return false;
260
260
  }
261
+ await activity.load();
261
262
  return new Promise(done => {
262
263
  const emitUpdate = async (update) => {
263
264
  this.exports = await this.selected.getExports();
@@ -275,6 +276,7 @@ let ActivityListService = (() => {
275
276
  if (!activity) {
276
277
  return false;
277
278
  }
279
+ await activity.load();
278
280
  return new Promise(done => {
279
281
  const emitUploadUpdate = (update) => {
280
282
  if (connectedApp === update.connectedApp) {
@@ -2,6 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._createUIActivityDetails = exports.createUIActivityDetails = exports.createUIActivitySummary = exports.createUIActivityInfo = void 0;
4
4
  const i18n_1 = require("../../i18n");
5
+ const formatOrUndefined = (value, dimension, C, U, digits) => {
6
+ const converted = C(value, dimension, { digits });
7
+ if (converted === undefined)
8
+ return undefined;
9
+ return { value: converted, unit: U(dimension) };
10
+ };
5
11
  const createUIActivityInfo = (a) => {
6
12
  if (!a)
7
13
  return a;
@@ -17,10 +23,10 @@ const createUIActivitySummary = (summary) => {
17
23
  return summary;
18
24
  const ui = { ...summary };
19
25
  const [C, U] = (0, i18n_1.getUnitConversionShortcuts)();
20
- ui.distance = { value: C(summary.distance, 'distance', { digits: 1 }), unit: U('distance') };
21
- if (ui.distance.value > 100)
26
+ ui.distance = formatOrUndefined(summary.distance, 'distance', C, U, 1);
27
+ if (ui.distance !== undefined && ui.distance.value > 100)
22
28
  ui.distance.value = Math.round(ui.distance.value);
23
- ui.totalElevation = { value: C(summary.totalElevation, 'elevation', { digits: 0 }), unit: U('elevation') };
29
+ ui.totalElevation = formatOrUndefined(summary.totalElevation, 'elevation', C, U, 0);
24
30
  return ui;
25
31
  };
26
32
  exports.createUIActivitySummary = createUIActivitySummary;
@@ -29,9 +35,7 @@ const createUIActivityDetails = (details) => {
29
35
  return details;
30
36
  const ui = { ...details };
31
37
  const [C, U] = (0, i18n_1.getUnitConversionShortcuts)();
32
- const formatSpeed = (v) => {
33
- return { value: C(v, 'speed', { digits: 1 }), unit: U('speed') };
34
- };
38
+ const formatSpeed = (v) => formatOrUndefined(v, 'speed', C, U, 1);
35
39
  if (details.stats?.speed) {
36
40
  ui.stats = {
37
41
  ...details.stats,
@@ -42,8 +46,8 @@ const createUIActivityDetails = (details) => {
42
46
  ui.stats.speed[field] = formatSpeed(ui.stats.speed[field]);
43
47
  }
44
48
  }
45
- ui.distance = { value: C(details.distance, 'distance', { digits: 1 }), unit: U('distance') };
46
- ui.totalElevation = { value: C(details.totalElevation, 'elevation', { digits: 0 }), unit: U('elevation') };
49
+ ui.distance = formatOrUndefined(details.distance, 'distance', C, U, 1);
50
+ ui.totalElevation = formatOrUndefined(details.totalElevation, 'elevation', C, U, 0);
47
51
  ui.logs = (details.logs ?? []).map(log => {
48
52
  const { speed, distance, elevation } = log;
49
53
  return {
@@ -61,13 +65,11 @@ const _createUIActivityDetails = (details) => {
61
65
  return details;
62
66
  const ui = structuredClone(details);
63
67
  const [C, U] = (0, i18n_1.getUnitConversionShortcuts)();
64
- ui.distance = { value: C(details.distance, 'distance', { digits: 1 }), unit: U('distance') };
65
- if (ui.distance.value > 100)
68
+ ui.distance = formatOrUndefined(details.distance, 'distance', C, U, 1);
69
+ if (ui.distance !== undefined && ui.distance.value > 100)
66
70
  ui.distance.value = Math.round(ui.distance.value);
67
- ui.totalElevation = { value: C(details.totalElevation, 'elevation', { digits: 0 }), unit: U('elevation') };
68
- const formatSpeed = (v) => {
69
- return { value: C(v, 'speed', { digits: 1 }), unit: U('speed') };
70
- };
71
+ ui.totalElevation = formatOrUndefined(details.totalElevation, 'elevation', C, U, 0);
72
+ const formatSpeed = (v) => formatOrUndefined(v, 'speed', C, U, 1);
71
73
  if (ui.stats?.speed) {
72
74
  const fields = ['min', 'max', 'avg'];
73
75
  for (const field of fields) {
@@ -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,31 +33,30 @@ 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.ActivityUploadFactory = void 0;
38
38
  const types_1 = require("../../base/types");
39
+ const Injection_1 = require("../../base/decorators/Injection");
40
+ const apps_1 = require("../../apps");
39
41
  let ActivityUploadFactory = (() => {
40
42
  let _classDecorators = [types_1.Singleton];
41
43
  let _classDescriptor;
42
44
  let _classExtraInitializers = [];
43
45
  let _classThis;
46
+ let _instanceExtraInitializers = [];
47
+ let _getAppsService_decorators;
44
48
  var ActivityUploadFactory = class {
45
49
  static { _classThis = this; }
46
50
  static {
47
51
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
52
+ _getAppsService_decorators = [Injection_1.Injectable];
53
+ __esDecorate(this, null, _getAppsService_decorators, { kind: "method", name: "getAppsService", static: false, private: false, access: { has: obj => "getAppsService" in obj, get: obj => obj.getAppsService }, metadata: _metadata }, null, _instanceExtraInitializers);
48
54
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
49
55
  ActivityUploadFactory = _classThis = _classDescriptor.value;
50
56
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
51
57
  __runInitializers(_classThis, _classExtraInitializers);
52
58
  }
53
- uploaders;
59
+ uploaders = __runInitializers(this, _instanceExtraInitializers);
54
60
  constructor() {
55
61
  this.uploaders = [];
56
62
  }
@@ -72,7 +78,7 @@ let ActivityUploadFactory = (() => {
72
78
  const uploads = [];
73
79
  this.uploaders.forEach(ui => {
74
80
  const { service, uploader } = ui;
75
- if (uploader.isConnected()) {
81
+ if (uploader.isConnected() && this.getAppsService().isEnabled(service, 'ActivityUpload')) {
76
82
  const promise = uploader.upload(activity, format)
77
83
  .then(success => ({ service, success }))
78
84
  .catch(err => ({ service, success: false, error: err.message }));
@@ -87,6 +93,16 @@ let ActivityUploadFactory = (() => {
87
93
  else
88
94
  return [];
89
95
  }
96
+ isUploadEnabled(service) {
97
+ const requested = this.uploaders.find(ui => ui.service === service);
98
+ if (!requested)
99
+ return false;
100
+ const uploader = requested.uploader;
101
+ return (uploader.isConnected() && this.getAppsService().isEnabled(service, 'ActivityUpload'));
102
+ }
103
+ getAppsService() {
104
+ return (0, apps_1.useAppsService)();
105
+ }
90
106
  };
91
107
  return ActivityUploadFactory = _classThis;
92
108
  })();
@@ -145,10 +145,13 @@ let AppsService = (() => {
145
145
  getConnectedServices(operation) {
146
146
  const available = this.services[operation];
147
147
  if (operation === 'ActivityUpload') {
148
- const uploaders = available.map(a => this.getActivityUploadFactory().get(a));
148
+ const factory = this.getActivityUploadFactory();
149
+ const uploaders = available.map(a => factory.get(a));
149
150
  const connected = uploaders.map((u, idx) => ({ connected: u?.isConnected(), key: available[idx] }))
150
151
  .filter(s => s.connected);
151
- return this.serviceMap.filter(s => connected.find(c => c.key === s.key));
152
+ const enabled = connected
153
+ .filter(s => factory.isUploadEnabled(s.key));
154
+ return this.serviceMap.filter(s => enabled.find(c => c.key === s.key));
152
155
  }
153
156
  else if (operation === 'WorkoutDownload') {
154
157
  return this.serviceMap.filter(s => available.includes(s.key) && s.connection.isConnected());
@@ -50,6 +50,7 @@ const service_2 = require("../../base/service");
50
50
  const types_1 = require("../../base/types");
51
51
  const Injection_1 = require("../../base/decorators/Injection");
52
52
  const apps_1 = require("../../apps");
53
+ const workouts_1 = require("../../workouts");
53
54
  const NO_DATA_THRESHOLD = 10000;
54
55
  const UNHEALTHY_THRESHOLD = 60000;
55
56
  let DeviceRideService = (() => {
@@ -63,6 +64,7 @@ let DeviceRideService = (() => {
63
64
  let _getUserSettings_decorators;
64
65
  let _getDeviceAccess_decorators;
65
66
  let _getGoogleMaps_decorators;
67
+ let _getWorkoutList_decorators;
66
68
  var DeviceRideService = class extends _classSuper {
67
69
  static { _classThis = this; }
68
70
  static {
@@ -71,10 +73,12 @@ let DeviceRideService = (() => {
71
73
  _getUserSettings_decorators = [Injection_1.Injectable];
72
74
  _getDeviceAccess_decorators = [Injection_1.Injectable];
73
75
  _getGoogleMaps_decorators = [Injection_1.Injectable];
76
+ _getWorkoutList_decorators = [Injection_1.Injectable];
74
77
  __esDecorate(this, null, _getDeviceConfiguration_decorators, { kind: "method", name: "getDeviceConfiguration", static: false, private: false, access: { has: obj => "getDeviceConfiguration" in obj, get: obj => obj.getDeviceConfiguration }, metadata: _metadata }, null, _instanceExtraInitializers);
75
78
  __esDecorate(this, null, _getUserSettings_decorators, { kind: "method", name: "getUserSettings", static: false, private: false, access: { has: obj => "getUserSettings" in obj, get: obj => obj.getUserSettings }, metadata: _metadata }, null, _instanceExtraInitializers);
76
79
  __esDecorate(this, null, _getDeviceAccess_decorators, { kind: "method", name: "getDeviceAccess", static: false, private: false, access: { has: obj => "getDeviceAccess" in obj, get: obj => obj.getDeviceAccess }, metadata: _metadata }, null, _instanceExtraInitializers);
77
80
  __esDecorate(this, null, _getGoogleMaps_decorators, { kind: "method", name: "getGoogleMaps", static: false, private: false, access: { has: obj => "getGoogleMaps" in obj, get: obj => obj.getGoogleMaps }, metadata: _metadata }, null, _instanceExtraInitializers);
81
+ __esDecorate(this, null, _getWorkoutList_decorators, { kind: "method", name: "getWorkoutList", static: false, private: false, access: { has: obj => "getWorkoutList" in obj, get: obj => obj.getWorkoutList }, metadata: _metadata }, null, _instanceExtraInitializers);
78
82
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
79
83
  DeviceRideService = _classThis = _classDescriptor.value;
80
84
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -1361,6 +1365,8 @@ let DeviceRideService = (() => {
1361
1365
  }
1362
1366
  canEnforceSimulator() {
1363
1367
  const selected = (0, routes_1.getRouteList)().getSelected();
1368
+ if (this.getWorkoutList().getSelected() && !selected)
1369
+ return true;
1364
1370
  const personalApiKey = this.getGoogleMaps().hasPersonalApiKey();
1365
1371
  if (!selected?.description)
1366
1372
  return false;
@@ -1416,6 +1422,9 @@ let DeviceRideService = (() => {
1416
1422
  getGoogleMaps() {
1417
1423
  return (0, apps_1.useGoogleMaps)();
1418
1424
  }
1425
+ getWorkoutList() {
1426
+ return (0, workouts_1.useWorkoutList)();
1427
+ }
1419
1428
  };
1420
1429
  return DeviceRideService = _classThis;
1421
1430
  })();
@@ -107,10 +107,14 @@ let RouteLibraryScannerService = (() => {
107
107
  observer.emit('error', err.message);
108
108
  });
109
109
  observer.on('success', (route) => {
110
+ if (!this.importProps)
111
+ return;
110
112
  this.importProps.phase = 'result';
111
113
  this.importProps.resultSuccess = { routeName: route.title };
112
114
  });
113
115
  observer.on('error', (error) => {
116
+ if (!this.importProps)
117
+ return;
114
118
  this.importProps.phase = 'result';
115
119
  this.importProps.error = error;
116
120
  });
@@ -200,6 +204,8 @@ let RouteLibraryScannerService = (() => {
200
204
  async importRoute(fileInfo, observer) {
201
205
  await (0, sleep_1.sleep)(0);
202
206
  observer.emit('parsing');
207
+ if (!this.importProps)
208
+ return;
203
209
  this.importProps.phase = 'parsing';
204
210
  if (fileInfo?.ext === 'gpx') {
205
211
  return this.importSingleGpxRoute(fileInfo, observer);
@@ -276,7 +276,7 @@ let RoutesPageService = (() => {
276
276
  this.importObserver.stop();
277
277
  this.getRouteLibraryScanner().done();
278
278
  this.importObserver = undefined;
279
- this.getPageObserver().emit('import-closed');
279
+ this.getPageObserver()?.emit('import-closed');
280
280
  this.serviceState = this.getRouteList().search();
281
281
  this.updatePageDisplay();
282
282
  }
@@ -257,9 +257,10 @@ let Activity = (() => {
257
257
  }
258
258
  getUploadStatus() {
259
259
  const uploads = [];
260
+ const stillLoading = !this.details && this.isLoading();
260
261
  const services = this.getAppsService().getConnectedServices('ActivityUpload');
261
262
  services.forEach(service => {
262
- let status = 'unknown';
263
+ let status = stillLoading ? 'loading' : 'unknown';
263
264
  const info = this.details?.links?.[service.key];
264
265
  if (info) {
265
266
  status = (info.error || !info.activity_id) ? 'failed' : 'success';
@@ -255,6 +255,7 @@ let ActivityListService = (() => {
255
255
  if (!activity) {
256
256
  return false;
257
257
  }
258
+ await activity.load();
258
259
  return new Promise(done => {
259
260
  const emitUpdate = async (update) => {
260
261
  this.exports = await this.selected.getExports();
@@ -272,6 +273,7 @@ let ActivityListService = (() => {
272
273
  if (!activity) {
273
274
  return false;
274
275
  }
276
+ await activity.load();
275
277
  return new Promise(done => {
276
278
  const emitUploadUpdate = (update) => {
277
279
  if (connectedApp === update.connectedApp) {
@@ -1,4 +1,10 @@
1
1
  import { getUnitConversionShortcuts } from "../../i18n";
2
+ const formatOrUndefined = (value, dimension, C, U, digits) => {
3
+ const converted = C(value, dimension, { digits });
4
+ if (converted === undefined)
5
+ return undefined;
6
+ return { value: converted, unit: U(dimension) };
7
+ };
2
8
  export const createUIActivityInfo = (a) => {
3
9
  if (!a)
4
10
  return a;
@@ -13,10 +19,10 @@ export const createUIActivitySummary = (summary) => {
13
19
  return summary;
14
20
  const ui = { ...summary };
15
21
  const [C, U] = getUnitConversionShortcuts();
16
- ui.distance = { value: C(summary.distance, 'distance', { digits: 1 }), unit: U('distance') };
17
- if (ui.distance.value > 100)
22
+ ui.distance = formatOrUndefined(summary.distance, 'distance', C, U, 1);
23
+ if (ui.distance !== undefined && ui.distance.value > 100)
18
24
  ui.distance.value = Math.round(ui.distance.value);
19
- ui.totalElevation = { value: C(summary.totalElevation, 'elevation', { digits: 0 }), unit: U('elevation') };
25
+ ui.totalElevation = formatOrUndefined(summary.totalElevation, 'elevation', C, U, 0);
20
26
  return ui;
21
27
  };
22
28
  export const createUIActivityDetails = (details) => {
@@ -24,9 +30,7 @@ export const createUIActivityDetails = (details) => {
24
30
  return details;
25
31
  const ui = { ...details };
26
32
  const [C, U] = getUnitConversionShortcuts();
27
- const formatSpeed = (v) => {
28
- return { value: C(v, 'speed', { digits: 1 }), unit: U('speed') };
29
- };
33
+ const formatSpeed = (v) => formatOrUndefined(v, 'speed', C, U, 1);
30
34
  if (details.stats?.speed) {
31
35
  ui.stats = {
32
36
  ...details.stats,
@@ -37,8 +41,8 @@ export const createUIActivityDetails = (details) => {
37
41
  ui.stats.speed[field] = formatSpeed(ui.stats.speed[field]);
38
42
  }
39
43
  }
40
- ui.distance = { value: C(details.distance, 'distance', { digits: 1 }), unit: U('distance') };
41
- ui.totalElevation = { value: C(details.totalElevation, 'elevation', { digits: 0 }), unit: U('elevation') };
44
+ ui.distance = formatOrUndefined(details.distance, 'distance', C, U, 1);
45
+ ui.totalElevation = formatOrUndefined(details.totalElevation, 'elevation', C, U, 0);
42
46
  ui.logs = (details.logs ?? []).map(log => {
43
47
  const { speed, distance, elevation } = log;
44
48
  return {
@@ -55,13 +59,11 @@ export const _createUIActivityDetails = (details) => {
55
59
  return details;
56
60
  const ui = structuredClone(details);
57
61
  const [C, U] = getUnitConversionShortcuts();
58
- ui.distance = { value: C(details.distance, 'distance', { digits: 1 }), unit: U('distance') };
59
- if (ui.distance.value > 100)
62
+ ui.distance = formatOrUndefined(details.distance, 'distance', C, U, 1);
63
+ if (ui.distance !== undefined && ui.distance.value > 100)
60
64
  ui.distance.value = Math.round(ui.distance.value);
61
- ui.totalElevation = { value: C(details.totalElevation, 'elevation', { digits: 0 }), unit: U('elevation') };
62
- const formatSpeed = (v) => {
63
- return { value: C(v, 'speed', { digits: 1 }), unit: U('speed') };
64
- };
65
+ ui.totalElevation = formatOrUndefined(details.totalElevation, 'elevation', C, U, 0);
66
+ const formatSpeed = (v) => formatOrUndefined(v, 'speed', C, U, 1);
65
67
  if (ui.stats?.speed) {
66
68
  const fields = ['min', 'max', 'avg'];
67
69
  for (const field of fields) {
@@ -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,29 +32,28 @@ 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 { Singleton } from "../../base/types";
36
+ import { Injectable } from "../../base/decorators/Injection";
37
+ import { useAppsService } from "../../apps";
36
38
  let ActivityUploadFactory = (() => {
37
39
  let _classDecorators = [Singleton];
38
40
  let _classDescriptor;
39
41
  let _classExtraInitializers = [];
40
42
  let _classThis;
43
+ let _instanceExtraInitializers = [];
44
+ let _getAppsService_decorators;
41
45
  var ActivityUploadFactory = class {
42
46
  static { _classThis = this; }
43
47
  static {
44
48
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
49
+ _getAppsService_decorators = [Injectable];
50
+ __esDecorate(this, null, _getAppsService_decorators, { kind: "method", name: "getAppsService", static: false, private: false, access: { has: obj => "getAppsService" in obj, get: obj => obj.getAppsService }, metadata: _metadata }, null, _instanceExtraInitializers);
45
51
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
46
52
  ActivityUploadFactory = _classThis = _classDescriptor.value;
47
53
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
48
54
  __runInitializers(_classThis, _classExtraInitializers);
49
55
  }
50
- uploaders;
56
+ uploaders = __runInitializers(this, _instanceExtraInitializers);
51
57
  constructor() {
52
58
  this.uploaders = [];
53
59
  }
@@ -69,7 +75,7 @@ let ActivityUploadFactory = (() => {
69
75
  const uploads = [];
70
76
  this.uploaders.forEach(ui => {
71
77
  const { service, uploader } = ui;
72
- if (uploader.isConnected()) {
78
+ if (uploader.isConnected() && this.getAppsService().isEnabled(service, 'ActivityUpload')) {
73
79
  const promise = uploader.upload(activity, format)
74
80
  .then(success => ({ service, success }))
75
81
  .catch(err => ({ service, success: false, error: err.message }));
@@ -84,6 +90,16 @@ let ActivityUploadFactory = (() => {
84
90
  else
85
91
  return [];
86
92
  }
93
+ isUploadEnabled(service) {
94
+ const requested = this.uploaders.find(ui => ui.service === service);
95
+ if (!requested)
96
+ return false;
97
+ const uploader = requested.uploader;
98
+ return (uploader.isConnected() && this.getAppsService().isEnabled(service, 'ActivityUpload'));
99
+ }
100
+ getAppsService() {
101
+ return useAppsService();
102
+ }
87
103
  };
88
104
  return ActivityUploadFactory = _classThis;
89
105
  })();
@@ -142,10 +142,13 @@ let AppsService = (() => {
142
142
  getConnectedServices(operation) {
143
143
  const available = this.services[operation];
144
144
  if (operation === 'ActivityUpload') {
145
- const uploaders = available.map(a => this.getActivityUploadFactory().get(a));
145
+ const factory = this.getActivityUploadFactory();
146
+ const uploaders = available.map(a => factory.get(a));
146
147
  const connected = uploaders.map((u, idx) => ({ connected: u?.isConnected(), key: available[idx] }))
147
148
  .filter(s => s.connected);
148
- return this.serviceMap.filter(s => connected.find(c => c.key === s.key));
149
+ const enabled = connected
150
+ .filter(s => factory.isUploadEnabled(s.key));
151
+ return this.serviceMap.filter(s => enabled.find(c => c.key === s.key));
149
152
  }
150
153
  else if (operation === 'WorkoutDownload') {
151
154
  return this.serviceMap.filter(s => available.includes(s.key) && s.connection.isConnected());
@@ -44,6 +44,7 @@ import { IncyclistService } from "../../base/service";
44
44
  import { Singleton } from "../../base/types";
45
45
  import { Injectable } from "../../base/decorators/Injection";
46
46
  import { useGoogleMaps } from "../../apps";
47
+ import { useWorkoutList } from "../../workouts";
47
48
  const NO_DATA_THRESHOLD = 10000;
48
49
  const UNHEALTHY_THRESHOLD = 60000;
49
50
  let DeviceRideService = (() => {
@@ -57,6 +58,7 @@ let DeviceRideService = (() => {
57
58
  let _getUserSettings_decorators;
58
59
  let _getDeviceAccess_decorators;
59
60
  let _getGoogleMaps_decorators;
61
+ let _getWorkoutList_decorators;
60
62
  var DeviceRideService = class extends _classSuper {
61
63
  static { _classThis = this; }
62
64
  static {
@@ -65,10 +67,12 @@ let DeviceRideService = (() => {
65
67
  _getUserSettings_decorators = [Injectable];
66
68
  _getDeviceAccess_decorators = [Injectable];
67
69
  _getGoogleMaps_decorators = [Injectable];
70
+ _getWorkoutList_decorators = [Injectable];
68
71
  __esDecorate(this, null, _getDeviceConfiguration_decorators, { kind: "method", name: "getDeviceConfiguration", static: false, private: false, access: { has: obj => "getDeviceConfiguration" in obj, get: obj => obj.getDeviceConfiguration }, metadata: _metadata }, null, _instanceExtraInitializers);
69
72
  __esDecorate(this, null, _getUserSettings_decorators, { kind: "method", name: "getUserSettings", static: false, private: false, access: { has: obj => "getUserSettings" in obj, get: obj => obj.getUserSettings }, metadata: _metadata }, null, _instanceExtraInitializers);
70
73
  __esDecorate(this, null, _getDeviceAccess_decorators, { kind: "method", name: "getDeviceAccess", static: false, private: false, access: { has: obj => "getDeviceAccess" in obj, get: obj => obj.getDeviceAccess }, metadata: _metadata }, null, _instanceExtraInitializers);
71
74
  __esDecorate(this, null, _getGoogleMaps_decorators, { kind: "method", name: "getGoogleMaps", static: false, private: false, access: { has: obj => "getGoogleMaps" in obj, get: obj => obj.getGoogleMaps }, metadata: _metadata }, null, _instanceExtraInitializers);
75
+ __esDecorate(this, null, _getWorkoutList_decorators, { kind: "method", name: "getWorkoutList", static: false, private: false, access: { has: obj => "getWorkoutList" in obj, get: obj => obj.getWorkoutList }, metadata: _metadata }, null, _instanceExtraInitializers);
72
76
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
73
77
  DeviceRideService = _classThis = _classDescriptor.value;
74
78
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -1355,6 +1359,8 @@ let DeviceRideService = (() => {
1355
1359
  }
1356
1360
  canEnforceSimulator() {
1357
1361
  const selected = getRouteList().getSelected();
1362
+ if (this.getWorkoutList().getSelected() && !selected)
1363
+ return true;
1358
1364
  const personalApiKey = this.getGoogleMaps().hasPersonalApiKey();
1359
1365
  if (!selected?.description)
1360
1366
  return false;
@@ -1410,6 +1416,9 @@ let DeviceRideService = (() => {
1410
1416
  getGoogleMaps() {
1411
1417
  return useGoogleMaps();
1412
1418
  }
1419
+ getWorkoutList() {
1420
+ return useWorkoutList();
1421
+ }
1413
1422
  };
1414
1423
  return DeviceRideService = _classThis;
1415
1424
  })();
@@ -104,10 +104,14 @@ let RouteLibraryScannerService = (() => {
104
104
  observer.emit('error', err.message);
105
105
  });
106
106
  observer.on('success', (route) => {
107
+ if (!this.importProps)
108
+ return;
107
109
  this.importProps.phase = 'result';
108
110
  this.importProps.resultSuccess = { routeName: route.title };
109
111
  });
110
112
  observer.on('error', (error) => {
113
+ if (!this.importProps)
114
+ return;
111
115
  this.importProps.phase = 'result';
112
116
  this.importProps.error = error;
113
117
  });
@@ -197,6 +201,8 @@ let RouteLibraryScannerService = (() => {
197
201
  async importRoute(fileInfo, observer) {
198
202
  await sleep(0);
199
203
  observer.emit('parsing');
204
+ if (!this.importProps)
205
+ return;
200
206
  this.importProps.phase = 'parsing';
201
207
  if (fileInfo?.ext === 'gpx') {
202
208
  return this.importSingleGpxRoute(fileInfo, observer);
@@ -273,7 +273,7 @@ let RoutesPageService = (() => {
273
273
  this.importObserver.stop();
274
274
  this.getRouteLibraryScanner().done();
275
275
  this.importObserver = undefined;
276
- this.getPageObserver().emit('import-closed');
276
+ this.getPageObserver()?.emit('import-closed');
277
277
  this.serviceState = this.getRouteList().search();
278
278
  this.updatePageDisplay();
279
279
  }
@@ -61,7 +61,7 @@ export type DisplayExportInfo = {
61
61
  file?: string;
62
62
  creating?: boolean;
63
63
  };
64
- export type ActivityUploadStatus = 'success' | 'failed' | 'unknown';
64
+ export type ActivityUploadStatus = 'success' | 'failed' | 'unknown' | 'loading';
65
65
  export type DisplayUploadInfo = {
66
66
  type: string;
67
67
  url?: string;
@@ -9,4 +9,6 @@ export declare class ActivityUploadFactory {
9
9
  string: any;
10
10
  boolean: any;
11
11
  }>>;
12
+ isUploadEnabled(service: string): boolean;
13
+ protected getAppsService(): import("../../apps").AppsService;
12
14
  }
@@ -135,6 +135,7 @@ export declare class DeviceRideService extends IncyclistService {
135
135
  protected getUserSettings(): import("../../settings").UserSettingsService;
136
136
  protected getDeviceAccess(): import("../access/service").DeviceAccessService;
137
137
  protected getGoogleMaps(): import("../../apps").GoogleMapsService;
138
+ protected getWorkoutList(): import("../../workouts").WorkoutListService;
138
139
  }
139
140
  export declare const useDeviceRide: () => DeviceRideService;
140
141
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.7.107",
3
+ "version": "1.7.109",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.27"
6
6
  },