incyclist-services 1.1.102 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/activities/base/api/index.d.ts +0 -0
- package/lib/activities/base/api/index.js +0 -0
- package/lib/activities/base/loaders/db.d.ts +41 -0
- package/lib/activities/base/loaders/db.js +378 -0
- package/lib/activities/base/loaders/index.d.ts +2 -0
- package/lib/activities/base/loaders/index.js +18 -0
- package/lib/activities/base/loaders/types.d.ts +8 -0
- package/lib/activities/base/loaders/types.js +2 -0
- package/lib/activities/base/model/index.d.ts +116 -0
- package/lib/activities/base/model/index.js +2 -0
- package/lib/activities/index.d.ts +2 -0
- package/lib/activities/index.js +18 -0
- package/lib/api/repository/json/index.d.ts +1 -0
- package/lib/api/repository/json/index.js +19 -0
- package/lib/api/repository/types.d.ts +1 -0
- package/lib/devices/configuration/service.d.ts +0 -1
- package/lib/devices/configuration/service.js +22 -159
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/routes/base/utils/route.js +2 -2
- package/lib/workouts/base/model/Workout.js +4 -3
- package/lib/workouts/list/cards/WorkoutCard.d.ts +1 -1
- package/lib/workouts/list/cards/WorkoutCard.js +3 -3
- package/lib/workouts/list/loaders/db.d.ts +1 -1
- package/lib/workouts/list/loaders/db.js +3 -3
- package/package.json +2 -3
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EventLogger } from "gd-eventlog";
|
|
2
|
+
import { JsonRepository } from "../../../api";
|
|
3
|
+
import { Observer, PromiseObserver } from "../../../base/types/observer";
|
|
4
|
+
import { ActivityDetails, ActivityInfo, ActivitySummary } from "../model";
|
|
5
|
+
import { ActivitySearchCriteria } from "./types";
|
|
6
|
+
export declare class ActivitiesDbLoader {
|
|
7
|
+
protected repo: JsonRepository;
|
|
8
|
+
protected loadObserver: Observer;
|
|
9
|
+
protected saveObserver: PromiseObserver<void>;
|
|
10
|
+
protected isDirty: boolean;
|
|
11
|
+
protected tsLastWrite: number;
|
|
12
|
+
protected logger: EventLogger;
|
|
13
|
+
protected activities: Array<ActivityInfo>;
|
|
14
|
+
protected isDBComplete: boolean;
|
|
15
|
+
constructor();
|
|
16
|
+
load(): Observer;
|
|
17
|
+
stopLoad(): void;
|
|
18
|
+
save(activity: ActivityInfo, writeDetails?: boolean): Promise<void>;
|
|
19
|
+
delete(activity: ActivityInfo | string): Promise<void>;
|
|
20
|
+
get(id: string): ActivityInfo;
|
|
21
|
+
getWithDetails(id: string): Promise<ActivityInfo>;
|
|
22
|
+
search(criteria: ActivitySearchCriteria): Array<ActivityInfo>;
|
|
23
|
+
protected writeRepo(): Promise<void>;
|
|
24
|
+
protected write(enforce?: boolean): void;
|
|
25
|
+
protected emitDone(): void;
|
|
26
|
+
protected emitUpdated(activity: ActivityInfo | Array<ActivityInfo>): void;
|
|
27
|
+
protected emitAdded(activity: ActivityInfo | Array<ActivityInfo>): void;
|
|
28
|
+
protected loadSummaries(): Promise<void>;
|
|
29
|
+
protected buildFromLegacy(): Promise<void>;
|
|
30
|
+
protected listActivities(): Promise<Array<string>>;
|
|
31
|
+
protected loadDetailsByName(name: string): Promise<ActivityDetails>;
|
|
32
|
+
protected loadDetails(name: string, id?: string): Promise<void>;
|
|
33
|
+
protected writeDetails(activity: ActivityInfo): Promise<void>;
|
|
34
|
+
protected buildSummary(activity: ActivityDetails, name: string): ActivitySummary;
|
|
35
|
+
protected scanForActivities(): Promise<Array<ActivitySummary> | null>;
|
|
36
|
+
protected scanForActivitiesAndMerge(activities: Array<ActivitySummary>): Promise<Array<ActivitySummary>>;
|
|
37
|
+
protected _load(): Promise<void>;
|
|
38
|
+
protected getActivity(id: string): ActivityInfo;
|
|
39
|
+
protected logError(error: Error, fn: string, logProps?: any): void;
|
|
40
|
+
protected getRepo(): JsonRepository;
|
|
41
|
+
}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
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
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
39
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
40
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
41
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
42
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
46
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
47
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.ActivitiesDbLoader = void 0;
|
|
51
|
+
const gd_eventlog_1 = require("gd-eventlog");
|
|
52
|
+
const api_1 = require("../../../api");
|
|
53
|
+
const types_1 = require("../../../base/types");
|
|
54
|
+
const observer_1 = require("../../../base/types/observer");
|
|
55
|
+
const utils_1 = require("../../../utils");
|
|
56
|
+
const DB_VERSION = '1';
|
|
57
|
+
let ActivitiesDbLoader = (() => {
|
|
58
|
+
let _classDecorators = [types_1.Singleton];
|
|
59
|
+
let _classDescriptor;
|
|
60
|
+
let _classExtraInitializers = [];
|
|
61
|
+
let _classThis;
|
|
62
|
+
var ActivitiesDbLoader = _classThis = class {
|
|
63
|
+
constructor() {
|
|
64
|
+
this.logger = new gd_eventlog_1.EventLogger('ActivitiesDB');
|
|
65
|
+
}
|
|
66
|
+
load() {
|
|
67
|
+
if (this.loadObserver)
|
|
68
|
+
return this.loadObserver;
|
|
69
|
+
this.loadObserver = new observer_1.Observer();
|
|
70
|
+
this._load();
|
|
71
|
+
return this.loadObserver;
|
|
72
|
+
}
|
|
73
|
+
stopLoad() {
|
|
74
|
+
this.emitDone();
|
|
75
|
+
}
|
|
76
|
+
save(activity, writeDetails = true) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
const stringify = (json) => { try {
|
|
79
|
+
JSON.stringify(json);
|
|
80
|
+
}
|
|
81
|
+
catch (_a) { } };
|
|
82
|
+
let prev;
|
|
83
|
+
const idx = this.activities.findIndex(ai => ai.summary.id === activity.summary.id);
|
|
84
|
+
if (idx === -1) {
|
|
85
|
+
this.activities.push(activity);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
prev = stringify(this.activities[idx]);
|
|
89
|
+
this.activities[idx] = activity;
|
|
90
|
+
}
|
|
91
|
+
const changed = !prev || stringify(activity) !== prev;
|
|
92
|
+
if (changed) {
|
|
93
|
+
this.isDirty = true;
|
|
94
|
+
this.write();
|
|
95
|
+
if (writeDetails) {
|
|
96
|
+
this.writeDetails(activity);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
delete(activity) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
let target = activity;
|
|
104
|
+
if (typeof (activity) === 'string') {
|
|
105
|
+
target = this.getActivity(activity);
|
|
106
|
+
}
|
|
107
|
+
if (!target)
|
|
108
|
+
return;
|
|
109
|
+
const id = target.summary.id;
|
|
110
|
+
const idx = this.activities.findIndex(ai => ai.summary.id === id);
|
|
111
|
+
if (idx) {
|
|
112
|
+
this.activities.splice(idx, 1);
|
|
113
|
+
this.write(true);
|
|
114
|
+
}
|
|
115
|
+
const name = target.summary.name;
|
|
116
|
+
yield this.getRepo().delete(name);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
get(id) {
|
|
120
|
+
const info = this.getActivity(id);
|
|
121
|
+
if (!info)
|
|
122
|
+
return;
|
|
123
|
+
return info;
|
|
124
|
+
}
|
|
125
|
+
getWithDetails(id) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
const info = this.getActivity(id);
|
|
128
|
+
if (!info)
|
|
129
|
+
return;
|
|
130
|
+
if (!info.details) {
|
|
131
|
+
yield this.loadDetails(info.summary.name, id);
|
|
132
|
+
}
|
|
133
|
+
return info;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
search(criteria) {
|
|
137
|
+
let result = this.activities;
|
|
138
|
+
if ((result === null || result === void 0 ? void 0 : result.length) > 0 && (criteria === null || criteria === void 0 ? void 0 : criteria.routeId)) {
|
|
139
|
+
result = result.filter(ai => ai.summary.routeId === criteria.routeId);
|
|
140
|
+
}
|
|
141
|
+
if ((result === null || result === void 0 ? void 0 : result.length) > 0 && (criteria === null || criteria === void 0 ? void 0 : criteria.startPos) !== undefined) {
|
|
142
|
+
result = result.filter(ai => ai.summary.startPos === criteria.startPos);
|
|
143
|
+
}
|
|
144
|
+
if ((result === null || result === void 0 ? void 0 : result.length) > 0 && (criteria === null || criteria === void 0 ? void 0 : criteria.realityFactor) !== undefined) {
|
|
145
|
+
result = result.filter(ai => { var _a; return ((_a = ai.summary.realityFactor) !== null && _a !== void 0 ? _a : 100) === criteria.realityFactor; });
|
|
146
|
+
}
|
|
147
|
+
if ((result === null || result === void 0 ? void 0 : result.length) > 0 && (criteria === null || criteria === void 0 ? void 0 : criteria.isSaved) !== undefined) {
|
|
148
|
+
result = result.filter(ai => ai.summary.isSaved === criteria.isSaved);
|
|
149
|
+
}
|
|
150
|
+
if ((result === null || result === void 0 ? void 0 : result.length) > 0 && (criteria === null || criteria === void 0 ? void 0 : criteria.uploadStatus) !== undefined) {
|
|
151
|
+
if (Array.isArray(criteria.uploadStatus)) {
|
|
152
|
+
result = result.filter(ai => {
|
|
153
|
+
const requested = criteria.uploadStatus;
|
|
154
|
+
const actual = ai.summary.uploadStatus;
|
|
155
|
+
const r = requested.sort().map(us => `${us.service}:${us.status}`).join(';');
|
|
156
|
+
const a = actual.sort().map(us => `${us.service}:${us.status}`).join(';');
|
|
157
|
+
return r === a;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const status = criteria.uploadStatus;
|
|
162
|
+
result = result.filter(ai => {
|
|
163
|
+
const serviceInfo = ai.summary.uploadStatus.find(asi => asi.service === status.service);
|
|
164
|
+
if (!serviceInfo)
|
|
165
|
+
return false;
|
|
166
|
+
return serviceInfo.status === status.status;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
writeRepo() {
|
|
173
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
+
if (this.saveObserver)
|
|
175
|
+
yield this.saveObserver.wait();
|
|
176
|
+
const save = () => __awaiter(this, void 0, void 0, function* () {
|
|
177
|
+
const isComplete = this.isDBComplete;
|
|
178
|
+
try {
|
|
179
|
+
const dbData = {
|
|
180
|
+
version: DB_VERSION,
|
|
181
|
+
isComplete,
|
|
182
|
+
activties: this.activities.map(ai => ai.summary)
|
|
183
|
+
};
|
|
184
|
+
yield this.getRepo().write('db', dbData);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
this.logger.logEvent({ message: 'could not safe repo', error: err.message });
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
this.saveObserver = new observer_1.PromiseObserver(save());
|
|
191
|
+
yield this.saveObserver.start();
|
|
192
|
+
process.nextTick(() => { delete this.saveObserver; });
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
write(enforce = false) {
|
|
196
|
+
if (enforce)
|
|
197
|
+
this.isDirty = true;
|
|
198
|
+
if (this.isDirty && (this.tsLastWrite === undefined || Date.now() - this.tsLastWrite >= 1000)) {
|
|
199
|
+
this.isDirty = false;
|
|
200
|
+
this.tsLastWrite = Date.now();
|
|
201
|
+
this.writeRepo();
|
|
202
|
+
}
|
|
203
|
+
if (this.isDirty && Date.now() - this.tsLastWrite < 1000) {
|
|
204
|
+
setTimeout(() => { this.write(); }, this.tsLastWrite + 1000 - Date.now());
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
emitDone() {
|
|
208
|
+
if (this.loadObserver)
|
|
209
|
+
this.loadObserver.emit('done');
|
|
210
|
+
(0, utils_1.waitNextTick)().then(() => {
|
|
211
|
+
this.loadObserver.reset();
|
|
212
|
+
delete this.loadObserver;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
emitUpdated(activity) {
|
|
216
|
+
if (this.loadObserver)
|
|
217
|
+
this.loadObserver.emit('updated', activity);
|
|
218
|
+
}
|
|
219
|
+
emitAdded(activity) {
|
|
220
|
+
if (this.loadObserver)
|
|
221
|
+
this.loadObserver.emit('added', activity);
|
|
222
|
+
}
|
|
223
|
+
loadSummaries() {
|
|
224
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
225
|
+
const dbData = yield this.getRepo().read('db');
|
|
226
|
+
if (dbData) {
|
|
227
|
+
const { activities, isComplete } = dbData;
|
|
228
|
+
this.activities = activities.map(summary => ({ summary }));
|
|
229
|
+
this.emitAdded(this.activities);
|
|
230
|
+
this.isDBComplete = isComplete;
|
|
231
|
+
if (!isComplete) {
|
|
232
|
+
const cnt = activities.length;
|
|
233
|
+
const update = yield this.scanForActivitiesAndMerge(activities);
|
|
234
|
+
if (cnt !== update.length) {
|
|
235
|
+
yield this.write(true);
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
yield this.buildFromLegacy();
|
|
241
|
+
return;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
buildFromLegacy() {
|
|
245
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
246
|
+
const activities = yield this.scanForActivities();
|
|
247
|
+
if (activities !== null) {
|
|
248
|
+
this.activities = activities.map(summary => ({ summary }));
|
|
249
|
+
}
|
|
250
|
+
yield this.write(true);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
listActivities() {
|
|
254
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
255
|
+
return this.getRepo().list();
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
loadDetailsByName(name) {
|
|
259
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
let details;
|
|
261
|
+
try {
|
|
262
|
+
details = yield this.getRepo().read(name);
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
this.logger.logEvent({ message: 'could not load activity details', name, reason: err.message, stack: err.stack });
|
|
266
|
+
}
|
|
267
|
+
return details;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
loadDetails(name, id) {
|
|
271
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
272
|
+
const details = yield this.loadDetailsByName(name);
|
|
273
|
+
const aid = id !== null && id !== void 0 ? id : details.id;
|
|
274
|
+
const activity = this.getActivity(aid);
|
|
275
|
+
if (activity) {
|
|
276
|
+
activity.details = details;
|
|
277
|
+
this.emitUpdated(activity);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
writeDetails(activity) {
|
|
282
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
283
|
+
const name = activity.summary.name;
|
|
284
|
+
this.getRepo().write(name, activity.details);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
buildSummary(activity, name) {
|
|
288
|
+
var _a;
|
|
289
|
+
const { id, title, route, screenshots, startTime: startTimeUTC, time: rideTime, distance, startPos, realityFactor = 100, links, laps } = activity;
|
|
290
|
+
const routeId = route === null || route === void 0 ? void 0 : route.id;
|
|
291
|
+
const shots = screenshots !== null && screenshots !== void 0 ? screenshots : [];
|
|
292
|
+
const preview = (_a = shots.find(s => s.isHighlight)) !== null && _a !== void 0 ? _a : shots[0];
|
|
293
|
+
const previewImage = preview === null || preview === void 0 ? void 0 : preview.fileName;
|
|
294
|
+
let startTime;
|
|
295
|
+
if (startTimeUTC)
|
|
296
|
+
startTime = (new Date(startTimeUTC)).getTime();
|
|
297
|
+
const uploadStatus = [];
|
|
298
|
+
if (links === null || links === void 0 ? void 0 : links.strava) {
|
|
299
|
+
uploadStatus.push({ service: 'strava', status: 'success' });
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
id, title, name, routeId, previewImage, startTime, rideTime, distance, startPos, realityFactor, uploadStatus, laps
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
scanForActivities() {
|
|
306
|
+
var _a, _b;
|
|
307
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
308
|
+
try {
|
|
309
|
+
this.isDBComplete = (_a = this.isDBComplete) !== null && _a !== void 0 ? _a : false;
|
|
310
|
+
const names = yield this.listActivities();
|
|
311
|
+
if (!names)
|
|
312
|
+
return null;
|
|
313
|
+
const promises = [];
|
|
314
|
+
names.forEach(name => promises.push(this.loadDetailsByName(name).then((details) => ({ name, details }))));
|
|
315
|
+
const result = yield Promise.allSettled(promises);
|
|
316
|
+
const activities = [];
|
|
317
|
+
let isComplete = true;
|
|
318
|
+
result.forEach(result => {
|
|
319
|
+
var _a;
|
|
320
|
+
if (result.status === "rejected")
|
|
321
|
+
isComplete = false;
|
|
322
|
+
else {
|
|
323
|
+
const details = (_a = result.value) === null || _a === void 0 ? void 0 : _a.details;
|
|
324
|
+
const name = result.value.name;
|
|
325
|
+
const summary = this.buildSummary(details, name);
|
|
326
|
+
activities.push(summary);
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
this.isDBComplete = (_b = this.isDBComplete) !== null && _b !== void 0 ? _b : isComplete;
|
|
330
|
+
return activities;
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
scanForActivitiesAndMerge(activities) {
|
|
338
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
339
|
+
const total = yield this.scanForActivities();
|
|
340
|
+
if (total === null)
|
|
341
|
+
return activities;
|
|
342
|
+
total.forEach(activity => {
|
|
343
|
+
if (!activities.map(a => a.id).includes(activity.id))
|
|
344
|
+
activities.push(activity);
|
|
345
|
+
});
|
|
346
|
+
return activities;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
_load() {
|
|
350
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
351
|
+
yield this.loadSummaries();
|
|
352
|
+
this.emitDone();
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
getActivity(id) {
|
|
356
|
+
return this.activities.find(ai => ai.summary.id === id);
|
|
357
|
+
}
|
|
358
|
+
logError(error, fn, logProps) {
|
|
359
|
+
const props = logProps !== null && logProps !== void 0 ? logProps : {};
|
|
360
|
+
this.logger.logEvent(Object.assign({ message: 'error', error, fn }, props));
|
|
361
|
+
}
|
|
362
|
+
getRepo() {
|
|
363
|
+
if (!this.repo)
|
|
364
|
+
this.repo = api_1.JsonRepository.create('activities');
|
|
365
|
+
return this.repo;
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
__setFunctionName(_classThis, "ActivitiesDbLoader");
|
|
369
|
+
(() => {
|
|
370
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
371
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
372
|
+
ActivitiesDbLoader = _classThis = _classDescriptor.value;
|
|
373
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
374
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
375
|
+
})();
|
|
376
|
+
return ActivitiesDbLoader = _classThis;
|
|
377
|
+
})();
|
|
378
|
+
exports.ActivitiesDbLoader = ActivitiesDbLoader;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./db"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { RoutePoint } from "../../../routes/base/types";
|
|
2
|
+
export type ActivityUser = {
|
|
3
|
+
uuid?: string;
|
|
4
|
+
weight: number;
|
|
5
|
+
ftp: number;
|
|
6
|
+
};
|
|
7
|
+
export type ActivityRoute = {
|
|
8
|
+
id?: string;
|
|
9
|
+
hash: string;
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
export type ActivityStatsRecord = {
|
|
13
|
+
min: number;
|
|
14
|
+
max: number;
|
|
15
|
+
avg: number;
|
|
16
|
+
cntVal: number;
|
|
17
|
+
sum: number;
|
|
18
|
+
minAllowed: number;
|
|
19
|
+
};
|
|
20
|
+
export type ActivityLogRecord = {
|
|
21
|
+
time: number;
|
|
22
|
+
timeDelta: number;
|
|
23
|
+
speed: number;
|
|
24
|
+
slope: number;
|
|
25
|
+
cadence: number;
|
|
26
|
+
heartrate: number;
|
|
27
|
+
distance: number;
|
|
28
|
+
power: number;
|
|
29
|
+
lat?: number;
|
|
30
|
+
lon?: number;
|
|
31
|
+
elevation?: number;
|
|
32
|
+
};
|
|
33
|
+
export type ActivityStats = {
|
|
34
|
+
hrm?: ActivityStatsRecord;
|
|
35
|
+
cadence?: ActivityStatsRecord;
|
|
36
|
+
speed: ActivityStatsRecord;
|
|
37
|
+
slope?: ActivityStatsRecord;
|
|
38
|
+
power: ActivityStatsRecord;
|
|
39
|
+
};
|
|
40
|
+
export type StravaAppLink = {
|
|
41
|
+
upload_id: number;
|
|
42
|
+
activity_id: number;
|
|
43
|
+
};
|
|
44
|
+
export type ActivityAppLinks = {
|
|
45
|
+
strava?: StravaAppLink;
|
|
46
|
+
};
|
|
47
|
+
export type ScreenShotInfo = {
|
|
48
|
+
fileName: string;
|
|
49
|
+
position: RoutePoint;
|
|
50
|
+
isHighlight?: boolean;
|
|
51
|
+
};
|
|
52
|
+
export type ActivityType = 'IncyclistActivity';
|
|
53
|
+
export type UploadStatus = 'success' | 'failure';
|
|
54
|
+
export type UploadInfo = {
|
|
55
|
+
service: string;
|
|
56
|
+
status: UploadStatus;
|
|
57
|
+
};
|
|
58
|
+
export type ActivityDB = {
|
|
59
|
+
version: string;
|
|
60
|
+
activities: Array<ActivitySummary>;
|
|
61
|
+
isComplete: boolean;
|
|
62
|
+
};
|
|
63
|
+
export type ActivitySummary = {
|
|
64
|
+
id: string;
|
|
65
|
+
title: string;
|
|
66
|
+
name: string;
|
|
67
|
+
routeId: string;
|
|
68
|
+
previewImage?: string;
|
|
69
|
+
startTime: number;
|
|
70
|
+
rideTime: number;
|
|
71
|
+
distance: number;
|
|
72
|
+
startPos: number;
|
|
73
|
+
realityFactor: number;
|
|
74
|
+
uploadStatus: Array<UploadInfo>;
|
|
75
|
+
isCompleted?: boolean;
|
|
76
|
+
isSaved?: boolean;
|
|
77
|
+
saveRideTime?: number;
|
|
78
|
+
laps?: Array<LapSummary>;
|
|
79
|
+
};
|
|
80
|
+
export type LapSummary = {
|
|
81
|
+
num: number;
|
|
82
|
+
startPos: number;
|
|
83
|
+
distance: number;
|
|
84
|
+
startTime: number;
|
|
85
|
+
rideTime: number;
|
|
86
|
+
};
|
|
87
|
+
export type ActivityDetails = {
|
|
88
|
+
type?: ActivityType;
|
|
89
|
+
version?: string;
|
|
90
|
+
title: string;
|
|
91
|
+
id: string;
|
|
92
|
+
user: ActivityUser;
|
|
93
|
+
route: ActivityRoute;
|
|
94
|
+
startTime: string;
|
|
95
|
+
time: number;
|
|
96
|
+
timeTotal: number;
|
|
97
|
+
timePause: number;
|
|
98
|
+
distance: number;
|
|
99
|
+
startPos: number;
|
|
100
|
+
startpos: number;
|
|
101
|
+
endpos: number;
|
|
102
|
+
totalElevation: number;
|
|
103
|
+
stats: ActivityStats;
|
|
104
|
+
logs: Array<ActivityLogRecord>;
|
|
105
|
+
screenshots: Array<ScreenShotInfo>;
|
|
106
|
+
fileName?: string;
|
|
107
|
+
tcxFileName?: string;
|
|
108
|
+
fitFileName?: string;
|
|
109
|
+
links?: ActivityAppLinks;
|
|
110
|
+
realityFactor: number;
|
|
111
|
+
laps?: Array<LapSummary>;
|
|
112
|
+
};
|
|
113
|
+
export type ActivityInfo = {
|
|
114
|
+
summary: ActivitySummary;
|
|
115
|
+
details?: ActivityDetails;
|
|
116
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./base/model"), exports);
|
|
18
|
+
__exportStar(require("./base/loaders"), exports);
|
|
@@ -15,5 +15,6 @@ export declare class JsonRepository {
|
|
|
15
15
|
read(objectName: string): Promise<JSONObject>;
|
|
16
16
|
delete(objectName: string): Promise<boolean>;
|
|
17
17
|
protected open(): Promise<boolean>;
|
|
18
|
+
list(exclude?: string | Array<string>): Promise<Array<string>>;
|
|
18
19
|
protected close(): Promise<boolean>;
|
|
19
20
|
}
|
|
@@ -75,6 +75,25 @@ class JsonRepository {
|
|
|
75
75
|
}
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
+
list(exclude) {
|
|
79
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
+
try {
|
|
81
|
+
let names = yield this.access.list();
|
|
82
|
+
if (!names)
|
|
83
|
+
return null;
|
|
84
|
+
names = names.filter(name => name.toLowerCase().endsWith('.json'));
|
|
85
|
+
names = names.map(name => name.substring(0, name.length - 5));
|
|
86
|
+
if (exclude) {
|
|
87
|
+
const excludes = (typeof (exclude) === 'string') ? [exclude] : exclude;
|
|
88
|
+
names = names.filter(name => !excludes.includes(name));
|
|
89
|
+
}
|
|
90
|
+
return names;
|
|
91
|
+
}
|
|
92
|
+
catch (_a) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
78
97
|
close() {
|
|
79
98
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
99
|
const db = (0, bindings_1.getBindings)().db;
|
|
@@ -5,6 +5,7 @@ export type JsonAccess = {
|
|
|
5
5
|
read(resourceName: string): Promise<JSONObject>;
|
|
6
6
|
write(resourceName: string, data: JSONObject): Promise<boolean>;
|
|
7
7
|
delete(resourceName: string): Promise<boolean>;
|
|
8
|
+
list(): Promise<Array<string>>;
|
|
8
9
|
};
|
|
9
10
|
export interface IJsonRepositoryBinding {
|
|
10
11
|
create(name: string): Promise<JsonAccess | null>;
|
|
@@ -27,7 +27,6 @@ export declare class DeviceConfigurationService extends EventEmitter {
|
|
|
27
27
|
protected logError(err: Error, fn: string): void;
|
|
28
28
|
init(): Promise<void>;
|
|
29
29
|
setFeature(name: string, enabled: boolean): void;
|
|
30
|
-
protected isNewUi(): boolean;
|
|
31
30
|
protected verifyCapabilityExists(capability: any): void;
|
|
32
31
|
protected verifyCapabilitySettings(): void;
|
|
33
32
|
protected initCapabilties(): void;
|
|
@@ -106,9 +106,6 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
106
106
|
setFeature(name, enabled) {
|
|
107
107
|
this.features[name] = enabled;
|
|
108
108
|
}
|
|
109
|
-
isNewUi() {
|
|
110
|
-
return this.features['NEW_UI'] === true;
|
|
111
|
-
}
|
|
112
109
|
verifyCapabilityExists(capability) {
|
|
113
110
|
const { capabilities } = this.settings;
|
|
114
111
|
const found = capabilities.find(c => c.capability === capability);
|
|
@@ -117,74 +114,20 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
117
114
|
}
|
|
118
115
|
}
|
|
119
116
|
verifyCapabilitySettings() {
|
|
120
|
-
var _a;
|
|
121
117
|
const { capabilities } = this.settings;
|
|
122
|
-
const isNewUi = this.isNewUi();
|
|
123
118
|
const bikeCapIdx = capabilities.findIndex(c => c.capability === 'bike');
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
capabilities.splice(bikeCapIdx, 1);
|
|
132
|
-
}
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
if (bikeCapIdx === -1) {
|
|
137
|
-
const control = capabilities.find(c => c.capability === incyclist_devices_1.IncyclistCapability.Control && c.selected !== undefined);
|
|
138
|
-
const bike = Object.assign({}, control);
|
|
139
|
-
bike.capability = 'bike';
|
|
140
|
-
capabilities.push(bike);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const bikeCap = capabilities.find(c => c.capability === 'bike');
|
|
144
|
-
for (const capability of ['bike', incyclist_devices_1.IncyclistCapability.Control]) {
|
|
145
|
-
const info = capabilities.find(c => c.capability === capability);
|
|
146
|
-
if (((_a = info === null || info === void 0 ? void 0 : info.devices) === null || _a === void 0 ? void 0 : _a.length) > 0 && (info === null || info === void 0 ? void 0 : info.selected) === undefined)
|
|
147
|
-
this.select(info.devices[0], capability);
|
|
148
|
-
}
|
|
149
|
-
if (bikeCap === null || bikeCap === void 0 ? void 0 : bikeCap.selected) {
|
|
150
|
-
const bike = bikeCap.selected;
|
|
151
|
-
const power = capabilities.find(c => c.capability === incyclist_devices_1.IncyclistCapability.Power && c.selected !== undefined);
|
|
152
|
-
const control = capabilities.find(c => c.capability === incyclist_devices_1.IncyclistCapability.Control && c.selected !== undefined);
|
|
153
|
-
const speed = capabilities.find(c => c.capability === incyclist_devices_1.IncyclistCapability.Speed && c.selected !== undefined);
|
|
154
|
-
const cadence = capabilities.find(c => c.capability === incyclist_devices_1.IncyclistCapability.Cadence && c.selected !== undefined);
|
|
155
|
-
const adapter = this.getAdapter(bike);
|
|
156
|
-
let changed = false;
|
|
157
|
-
const verify = (uuid, cap) => {
|
|
158
|
-
if (!uuid && adapter.hasCapability(cap)) {
|
|
159
|
-
const setting = capabilities.find(c => c.capability === cap);
|
|
160
|
-
if (!setting) {
|
|
161
|
-
capabilities.push({ capability: cap, devices: [bike], selected: bike, disabled: false });
|
|
162
|
-
changed = true;
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
setting.selected = bike;
|
|
166
|
-
if (!setting.devices.includes(bike))
|
|
167
|
-
setting.devices.push(bike);
|
|
168
|
-
changed = true;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
verify(control, incyclist_devices_1.IncyclistCapability.Control);
|
|
173
|
-
verify(power, incyclist_devices_1.IncyclistCapability.Power);
|
|
174
|
-
verify(speed, incyclist_devices_1.IncyclistCapability.Speed);
|
|
175
|
-
verify(cadence, incyclist_devices_1.IncyclistCapability.Cadence);
|
|
176
|
-
if (changed) {
|
|
177
|
-
this.updateUserSettings();
|
|
178
|
-
this.logEvent({ message: 'capability changed after verification', capabilities });
|
|
179
|
-
}
|
|
119
|
+
this.verifyCapabilityExists(incyclist_devices_1.IncyclistCapability.Control);
|
|
120
|
+
this.verifyCapabilityExists(incyclist_devices_1.IncyclistCapability.Power);
|
|
121
|
+
this.verifyCapabilityExists(incyclist_devices_1.IncyclistCapability.HeartRate);
|
|
122
|
+
this.verifyCapabilityExists(incyclist_devices_1.IncyclistCapability.Speed);
|
|
123
|
+
this.verifyCapabilityExists(incyclist_devices_1.IncyclistCapability.Cadence);
|
|
124
|
+
if (bikeCapIdx !== -1) {
|
|
125
|
+
capabilities.splice(bikeCapIdx, 1);
|
|
180
126
|
}
|
|
127
|
+
return;
|
|
181
128
|
}
|
|
182
129
|
initCapabilties() {
|
|
183
|
-
const isNewUi = this.isNewUi();
|
|
184
130
|
const target = [incyclist_devices_1.IncyclistCapability.Control, incyclist_devices_1.IncyclistCapability.Power, incyclist_devices_1.IncyclistCapability.Cadence, incyclist_devices_1.IncyclistCapability.Speed, incyclist_devices_1.IncyclistCapability.HeartRate];
|
|
185
|
-
if (!isNewUi) {
|
|
186
|
-
target.push('bike');
|
|
187
|
-
}
|
|
188
131
|
if (!this.settings)
|
|
189
132
|
this.settings = {};
|
|
190
133
|
if (!this.settings.capabilities)
|
|
@@ -213,11 +156,7 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
213
156
|
var _a, _b, _c, _d, _e;
|
|
214
157
|
const { gearSelection, connections, modeSettings = {} } = settings;
|
|
215
158
|
this.logEvent({ message: 'converting settings.json', gearSelection, connections });
|
|
216
|
-
const isNewUi = this.isNewUi();
|
|
217
159
|
const all = [incyclist_devices_1.IncyclistCapability.Control, incyclist_devices_1.IncyclistCapability.Power, incyclist_devices_1.IncyclistCapability.Cadence, incyclist_devices_1.IncyclistCapability.Speed, incyclist_devices_1.IncyclistCapability.HeartRate];
|
|
218
|
-
if (!isNewUi) {
|
|
219
|
-
all.push('bike');
|
|
220
|
-
}
|
|
221
160
|
const gears = (0, clone_1.default)(gearSelection || {});
|
|
222
161
|
const { bikes = [], hrms = [] } = gears;
|
|
223
162
|
this.settings = { interfaces: [], devices: [], capabilities: [] };
|
|
@@ -275,7 +214,7 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
275
214
|
this.addToCapability(udid, cc);
|
|
276
215
|
if (isSelected) {
|
|
277
216
|
const cap = cc;
|
|
278
|
-
if (
|
|
217
|
+
if (adapter.hasCapability(cap)) {
|
|
279
218
|
const selectedDevice = capabilities.find(c => c.capability === cap);
|
|
280
219
|
selectedDevice.selected = udid;
|
|
281
220
|
}
|
|
@@ -407,8 +346,7 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
407
346
|
select(udid, capability, props) {
|
|
408
347
|
var _a, _b, _c;
|
|
409
348
|
this.logEvent({ message: 'select device', udid, capability, props });
|
|
410
|
-
const
|
|
411
|
-
const { noRecursive = false, legacy = false, emit = true } = props || {};
|
|
349
|
+
const { emit = true } = props || {};
|
|
412
350
|
const deviceSettings = (_b = (_a = this.settings.devices) === null || _a === void 0 ? void 0 : _a.find(d => d.udid === udid)) === null || _b === void 0 ? void 0 : _b.settings;
|
|
413
351
|
if (!deviceSettings)
|
|
414
352
|
return;
|
|
@@ -417,62 +355,13 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
417
355
|
this.logEvent({ message: 'error: could not find adapter', fn: 'select', udid, capability, adapters: (_c = Object.keys(this.adapters)) === null || _c === void 0 ? void 0 : _c.join(',') });
|
|
418
356
|
return;
|
|
419
357
|
}
|
|
420
|
-
if (
|
|
421
|
-
if (capability === 'bike')
|
|
422
|
-
return;
|
|
423
|
-
this.selectSingleDevice(udid, capability);
|
|
424
|
-
if (emit)
|
|
425
|
-
this.emitCapabiltyChanged(capability);
|
|
426
|
-
this.updateUserSettings();
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
if ((capability === 'bike') && !adapter.isControllable())
|
|
358
|
+
if (capability === 'bike')
|
|
430
359
|
return;
|
|
431
|
-
const isControl = adapter.hasCapability(incyclist_devices_1.IncyclistCapability.Control) || (legacy && !isNewUi && capability === 'bike');
|
|
432
360
|
this.selectSingleDevice(udid, capability);
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
return;
|
|
436
|
-
if (isControl) {
|
|
437
|
-
if (capability !== 'bike' && capability !== incyclist_devices_1.IncyclistCapability.Control) {
|
|
438
|
-
if (!isNewUi)
|
|
439
|
-
this.select(udid, 'bike', { noRecursive: true, legacy });
|
|
440
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.Control, { noRecursive: true, legacy });
|
|
441
|
-
}
|
|
442
|
-
else {
|
|
443
|
-
if (!isNewUi && capability === 'bike' && isControl) {
|
|
444
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.Control, { noRecursive: true, legacy });
|
|
445
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.Power, { noRecursive: true, legacy });
|
|
446
|
-
if (legacy) {
|
|
447
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.Speed, { noRecursive: true, legacy });
|
|
448
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.Cadence, { noRecursive: true, legacy });
|
|
449
|
-
}
|
|
450
|
-
if (adapter.hasCapability(incyclist_devices_1.IncyclistCapability.HeartRate)) {
|
|
451
|
-
const hrm = this.getSelected(incyclist_devices_1.IncyclistCapability.HeartRate);
|
|
452
|
-
if (!hrm && !this.isDisabled(incyclist_devices_1.IncyclistCapability.HeartRate)) {
|
|
453
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.HeartRate);
|
|
454
|
-
}
|
|
455
|
-
else if (hrm && hrm.hasCapability(incyclist_devices_1.IncyclistCapability.Control)) {
|
|
456
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.HeartRate);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
const otherCapabilties = this.settings.capabilities.filter(c => c.capability !== 'bike' && c.capability !== incyclist_devices_1.IncyclistCapability.Control && !c.disabled && c.selected !== udid);
|
|
461
|
-
const selectedControllable = otherCapabilties.filter(c => { var _a; return c.selected && ((_a = this.adapters[c.selected]) === null || _a === void 0 ? void 0 : _a.hasCapability(incyclist_devices_1.IncyclistCapability.Control)); });
|
|
462
|
-
selectedControllable.forEach(c => {
|
|
463
|
-
if (adapter.hasCapability(c.capability)) {
|
|
464
|
-
this.select(udid, c.capability);
|
|
465
|
-
}
|
|
466
|
-
else
|
|
467
|
-
this.unselect(c.capability);
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
else if (!isControl && !isNewUi && capability === 'bike') {
|
|
472
|
-
this.unselect(incyclist_devices_1.IncyclistCapability.Control);
|
|
473
|
-
this.select(udid, incyclist_devices_1.IncyclistCapability.Power, { noRecursive: true, legacy });
|
|
474
|
-
}
|
|
361
|
+
if (emit)
|
|
362
|
+
this.emitCapabiltyChanged(capability);
|
|
475
363
|
this.updateUserSettings();
|
|
364
|
+
return;
|
|
476
365
|
}
|
|
477
366
|
selectSingleDevice(udid, capability) {
|
|
478
367
|
var _a;
|
|
@@ -496,7 +385,6 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
496
385
|
}
|
|
497
386
|
add(deviceSettings, props) {
|
|
498
387
|
var _a, _b;
|
|
499
|
-
const isNewUi = this.isNewUi();
|
|
500
388
|
let udid = this.getUdid(deviceSettings);
|
|
501
389
|
const { legacy = false } = props || {};
|
|
502
390
|
this.logEvent({ message: 'add device', udid, deviceSettings, legacy });
|
|
@@ -525,30 +413,10 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
525
413
|
if (c.devices.includes(udid))
|
|
526
414
|
return udid;
|
|
527
415
|
const isBike = adapter.hasCapability(incyclist_devices_1.IncyclistCapability.Control);
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const isHrmCap = c.capability === incyclist_devices_1.IncyclistCapability.HeartRate;
|
|
533
|
-
const canAdd = (isBikeCap && (isBike || isPower)) ||
|
|
534
|
-
(isControlCap && isBike) ||
|
|
535
|
-
(!isHrmCap && !isControlCap && (isBike || isPower)) ||
|
|
536
|
-
adapter.hasCapability(c.capability);
|
|
537
|
-
const canSelect = (isBikeCap || isControlCap || isHrmCap) &&
|
|
538
|
-
(!c.selected && !c.disabled &&
|
|
539
|
-
(isBike || isPower || c.capability === incyclist_devices_1.IncyclistCapability.HeartRate));
|
|
540
|
-
if (canAdd) {
|
|
541
|
-
c.devices.push(udid);
|
|
542
|
-
if (canSelect)
|
|
543
|
-
c.selected = udid;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
if (adapter.hasCapability(c.capability) || (!isNewUi && c.capability === 'bike' && (isBike || isPower))) {
|
|
548
|
-
c.devices.push(udid);
|
|
549
|
-
if (!c.selected && !c.disabled && (isBike || c.capability === incyclist_devices_1.IncyclistCapability.HeartRate))
|
|
550
|
-
c.selected = udid;
|
|
551
|
-
}
|
|
416
|
+
if (adapter.hasCapability(c.capability) && c.capability !== 'bike') {
|
|
417
|
+
c.devices.push(udid);
|
|
418
|
+
if (!c.selected && !c.disabled && (isBike || c.capability === incyclist_devices_1.IncyclistCapability.HeartRate))
|
|
419
|
+
c.selected = udid;
|
|
552
420
|
}
|
|
553
421
|
});
|
|
554
422
|
this.updateUserSettings();
|
|
@@ -611,8 +479,8 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
611
479
|
}
|
|
612
480
|
}
|
|
613
481
|
addToCapability(udid, capability) {
|
|
614
|
-
|
|
615
|
-
if (
|
|
482
|
+
var _a;
|
|
483
|
+
if (capability === 'bike')
|
|
616
484
|
return;
|
|
617
485
|
if (!this.settings)
|
|
618
486
|
this.settings = {};
|
|
@@ -624,12 +492,9 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
624
492
|
capabilities.push({ capability, devices: [udid], selected: udid });
|
|
625
493
|
}
|
|
626
494
|
else {
|
|
627
|
-
if (!record.devices.includes(udid))
|
|
495
|
+
if (!((_a = record.devices) === null || _a === void 0 ? void 0 : _a.includes(udid)))
|
|
628
496
|
record.devices.push(udid);
|
|
629
497
|
}
|
|
630
|
-
if (capability !== 'bike' && !this.adapters[udid].hasCapability(capability)) {
|
|
631
|
-
this.adapters[udid].addCapability(capability);
|
|
632
|
-
}
|
|
633
498
|
}
|
|
634
499
|
getUdid(deviceSettings) {
|
|
635
500
|
const udids = Object.keys(this.adapters);
|
|
@@ -661,12 +526,10 @@ class DeviceConfigurationService extends events_1.default {
|
|
|
661
526
|
this.userSettings.set('interfaces', this.settings.interfaces);
|
|
662
527
|
}
|
|
663
528
|
canStartRide() {
|
|
664
|
-
const isNewUi = this.isNewUi();
|
|
665
529
|
const { devices, capabilities } = this.settings || {};
|
|
666
530
|
if (!devices || !capabilities)
|
|
667
531
|
return false;
|
|
668
|
-
const canStart = (
|
|
669
|
-
this.getSelected(incyclist_devices_1.IncyclistCapability.Control) !== undefined ||
|
|
532
|
+
const canStart = (this.getSelected(incyclist_devices_1.IncyclistCapability.Control) !== undefined ||
|
|
670
533
|
this.getSelected(incyclist_devices_1.IncyclistCapability.Power) !== undefined ||
|
|
671
534
|
this.getSelected(incyclist_devices_1.IncyclistCapability.Speed) !== undefined);
|
|
672
535
|
return canStart;
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -21,6 +21,7 @@ __exportStar(require("./api"), exports);
|
|
|
21
21
|
__exportStar(require("./routes"), exports);
|
|
22
22
|
__exportStar(require("./workouts"), exports);
|
|
23
23
|
__exportStar(require("./coaches"), exports);
|
|
24
|
+
__exportStar(require("./activities"), exports);
|
|
24
25
|
var settings_1 = require("./settings");
|
|
25
26
|
Object.defineProperty(exports, "useUserSettings", { enumerable: true, get: function () { return settings_1.useUserSettings; } });
|
|
26
27
|
Object.defineProperty(exports, "initUserSettings", { enumerable: true, get: function () { return settings_1.initUserSettings; } });
|
|
@@ -7,7 +7,7 @@ exports.getPosition = exports.getNextPosition = exports.getRouteHash = exports.g
|
|
|
7
7
|
const utils_1 = require("../../../utils");
|
|
8
8
|
const geo_1 = require("../../../utils/geo");
|
|
9
9
|
const valid_1 = require("../../../utils/valid");
|
|
10
|
-
const
|
|
10
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
11
11
|
const MAX_LAPMODE_DISTANCE = 50;
|
|
12
12
|
const checkIsLoop = (_route) => {
|
|
13
13
|
var _a;
|
|
@@ -155,7 +155,7 @@ const getRouteHash = (route) => {
|
|
|
155
155
|
else {
|
|
156
156
|
json = { decoded: route.points.map(p => ({ lat: p.lat, lng: p.lng })) };
|
|
157
157
|
}
|
|
158
|
-
const routeHash =
|
|
158
|
+
const routeHash = crypto_1.default.createHash('md5').update(JSON.stringify(json)).digest('hex');
|
|
159
159
|
return routeHash;
|
|
160
160
|
};
|
|
161
161
|
exports.getRouteHash = getRouteHash;
|
|
@@ -7,7 +7,7 @@ exports.Plan = exports.Workout = void 0;
|
|
|
7
7
|
const Step_1 = require("./Step");
|
|
8
8
|
const Segment_1 = require("./Segment");
|
|
9
9
|
const valid_1 = require("../../../utils/valid");
|
|
10
|
-
const
|
|
10
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
11
11
|
class Workout extends Segment_1.Segment {
|
|
12
12
|
constructor(opts) {
|
|
13
13
|
var _a;
|
|
@@ -36,7 +36,7 @@ class Workout extends Segment_1.Segment {
|
|
|
36
36
|
if (this._hash)
|
|
37
37
|
return this.hash;
|
|
38
38
|
const { name, description, steps, repeat } = this;
|
|
39
|
-
this._hash =
|
|
39
|
+
this._hash = crypto_1.default.createHash('md5').update(JSON.stringify({ name, description, steps, repeat })).digest('hex');
|
|
40
40
|
return this._hash;
|
|
41
41
|
}
|
|
42
42
|
getSegment(time) {
|
|
@@ -85,7 +85,8 @@ class Plan {
|
|
|
85
85
|
if (this._hash)
|
|
86
86
|
return this.hash;
|
|
87
87
|
const { name, description, workouts } = this;
|
|
88
|
-
|
|
88
|
+
const data = JSON.stringify({ name, description, workouts });
|
|
89
|
+
this._hash = crypto_1.default.createHash('md5').update(data).digest('hex');
|
|
89
90
|
return this._hash;
|
|
90
91
|
}
|
|
91
92
|
addWorkoutSchedule(week, day, workoutId) {
|
|
@@ -19,7 +19,7 @@ export declare class WorkoutCard extends BaseCard implements Card<Workout> {
|
|
|
19
19
|
select(settings?: WorkoutSettings): void;
|
|
20
20
|
unselect(): void;
|
|
21
21
|
move(targetListName: string): void;
|
|
22
|
-
save(): Promise<void>;
|
|
22
|
+
save(enforce?: boolean): Promise<void>;
|
|
23
23
|
delete(): PromiseObserver<boolean>;
|
|
24
24
|
getId(): string;
|
|
25
25
|
getTitle(): string;
|
|
@@ -71,12 +71,12 @@ class WorkoutCard extends base_1.BaseCard {
|
|
|
71
71
|
this.list = newList;
|
|
72
72
|
}
|
|
73
73
|
this.workout.category = { name: targetListName, index: newList === null || newList === void 0 ? void 0 : newList.length };
|
|
74
|
-
this.save();
|
|
74
|
+
this.save(true);
|
|
75
75
|
}
|
|
76
|
-
save() {
|
|
76
|
+
save(enforce = false) {
|
|
77
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
78
78
|
try {
|
|
79
|
-
return yield this.getRepo().save(this.workout);
|
|
79
|
+
return yield this.getRepo().save(this.workout, enforce);
|
|
80
80
|
}
|
|
81
81
|
catch (err) {
|
|
82
82
|
this.logError(err, 'save');
|
|
@@ -16,7 +16,7 @@ export declare class WorkoutsDbLoader extends Loader {
|
|
|
16
16
|
constructor();
|
|
17
17
|
load(): Observer;
|
|
18
18
|
stopLoad(): void;
|
|
19
|
-
save(workout: Workout | Plan): Promise<void>;
|
|
19
|
+
save(workout: Workout | Plan, enforceWrite?: boolean): Promise<void>;
|
|
20
20
|
delete(workout: Workout | Plan): Promise<void>;
|
|
21
21
|
protected getRepo(): JsonRepository;
|
|
22
22
|
protected _load(): Promise<void>;
|
|
@@ -85,7 +85,7 @@ let WorkoutsDbLoader = (() => {
|
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
save(workout) {
|
|
88
|
+
save(workout, enforceWrite = false) {
|
|
89
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
90
90
|
if (!(0, valid_1.valid)(workout))
|
|
91
91
|
return;
|
|
@@ -106,9 +106,9 @@ let WorkoutsDbLoader = (() => {
|
|
|
106
106
|
else {
|
|
107
107
|
prev = stringify(Object.assign({}, this.workouts[idx]));
|
|
108
108
|
this.workouts[idx] = workout;
|
|
109
|
-
changed = stringify(Object.assign({},
|
|
109
|
+
changed = stringify(Object.assign({}, workout)) !== prev;
|
|
110
110
|
}
|
|
111
|
-
if (changed) {
|
|
111
|
+
if (changed || enforceWrite) {
|
|
112
112
|
this.isDirty = true;
|
|
113
113
|
this.write();
|
|
114
114
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "incyclist-services",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"gd-eventlog": "^0.1.26"
|
|
6
6
|
},
|
|
@@ -39,8 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"axios": "^1.6.1",
|
|
42
|
-
"incyclist-devices": "^2.1
|
|
43
|
-
"md5": "^2.3.0",
|
|
42
|
+
"incyclist-devices": "^2.2.1",
|
|
44
43
|
"promise.any": "^2.0.6",
|
|
45
44
|
"uuid": "^9.0.0",
|
|
46
45
|
"xml2js": "^0.6.2"
|