incyclist-services 1.7.16 → 1.7.18
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/cjs/activities/list/service.js +15 -10
- package/lib/cjs/base/pages/service.js +3 -0
- package/lib/cjs/devices/access/service.js +14 -0
- package/lib/cjs/devices/page/service.js +42 -5
- package/lib/cjs/devices/page/statemachine.js +3 -2
- package/lib/cjs/devices/pairing/service.js +1 -1
- package/lib/cjs/ui/service.js +19 -1
- package/lib/esm/activities/list/service.js +15 -10
- package/lib/esm/base/pages/service.js +3 -0
- package/lib/esm/devices/access/service.js +14 -0
- package/lib/esm/devices/page/service.js +42 -5
- package/lib/esm/devices/page/statemachine.js +3 -2
- package/lib/esm/devices/pairing/service.js +1 -1
- package/lib/esm/ui/service.js +19 -1
- package/lib/types/api/ui/index.d.ts +3 -2
- package/lib/types/base/pages/service.d.ts +1 -0
- package/lib/types/devices/access/service.d.ts +1 -0
- package/lib/types/devices/page/service.d.ts +14 -2
- package/lib/types/devices/page/types.d.ts +8 -0
- package/lib/types/ui/service.d.ts +1 -0
- package/package.json +2 -2
|
@@ -229,19 +229,24 @@ let ActivityListService = (() => {
|
|
|
229
229
|
}
|
|
230
230
|
const startStettings = this.selected.createStartSettings();
|
|
231
231
|
const card = this.selected.getRouteCard();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
route.details = await routes.getRouteDetails(route.description.id);
|
|
232
|
+
if (card) {
|
|
233
|
+
const routes = this.getRouteList();
|
|
234
|
+
routes.selectCard(card);
|
|
235
|
+
routes.setStartSettings(startStettings);
|
|
236
|
+
const route = routes.getSelected();
|
|
238
237
|
if (!route.details) {
|
|
239
|
-
|
|
238
|
+
route.details = await routes.getRouteDetails(route.description.id);
|
|
239
|
+
if (!route.details) {
|
|
240
|
+
return { canStart: false };
|
|
241
|
+
}
|
|
240
242
|
}
|
|
243
|
+
card.changeSettings(startStettings);
|
|
244
|
+
card.start();
|
|
245
|
+
return { canStart: true, route };
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
return { canStart: false };
|
|
241
249
|
}
|
|
242
|
-
card.changeSettings(startStettings);
|
|
243
|
-
card.start();
|
|
244
|
-
return { canStart: true, route };
|
|
245
250
|
}
|
|
246
251
|
catch (err) {
|
|
247
252
|
this.logError(err, 'rideAgain');
|
|
@@ -53,6 +53,9 @@ let IncyclistPageService = (() => {
|
|
|
53
53
|
name = __runInitializers(this, _instanceExtraInitializers);
|
|
54
54
|
pageObserver;
|
|
55
55
|
static currentPage;
|
|
56
|
+
static closePage() {
|
|
57
|
+
this.currentPage?.closePage();
|
|
58
|
+
}
|
|
56
59
|
static async pausePage() {
|
|
57
60
|
await this.currentPage?.pausePage();
|
|
58
61
|
}
|
|
@@ -92,6 +92,10 @@ let DeviceAccessService = (() => {
|
|
|
92
92
|
this.logEvent({ message: 'Illegal State, enable Interface cannot be called during an ongoing scan', interface: ifaceName });
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
|
+
existing.interface.removeAllListeners('disconnect');
|
|
96
|
+
existing.interface.on('disconnect', () => {
|
|
97
|
+
this.emit('interface-changed', ifaceName, { ...existing, state: 'disconnected' });
|
|
98
|
+
});
|
|
95
99
|
if (existing.enabled && ((existing.state === 'connected' && existing?.interface?.isConnected()) || existing.state === 'connecting')) {
|
|
96
100
|
return;
|
|
97
101
|
}
|
|
@@ -267,6 +271,16 @@ let DeviceAccessService = (() => {
|
|
|
267
271
|
this.emit('interface-changed', ifaceName, { ...this.interfaces[ifaceName] });
|
|
268
272
|
return disconnected;
|
|
269
273
|
}
|
|
274
|
+
async terminate(ifaceName) {
|
|
275
|
+
await this.disconnect(ifaceName);
|
|
276
|
+
if (!ifaceName) {
|
|
277
|
+
const promises = Object.keys(this.interfaces).map(i => this.terminate(i));
|
|
278
|
+
await Promise.allSettled(promises);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const impl = this.getInterface(ifaceName);
|
|
282
|
+
await impl.terminate();
|
|
283
|
+
}
|
|
270
284
|
async scan(filter = {}, props = {}) {
|
|
271
285
|
this.logEvent({ message: 'device scan start', filter, props });
|
|
272
286
|
const detected = [];
|
|
@@ -45,6 +45,7 @@ const access_1 = require("../access");
|
|
|
45
45
|
const configuration_1 = require("../configuration");
|
|
46
46
|
const api_1 = require("../../api");
|
|
47
47
|
const ui_1 = require("../../ui");
|
|
48
|
+
const types_1 = require("../../base/types");
|
|
48
49
|
let DevicesPageService = (() => {
|
|
49
50
|
let _classDecorators = [decorators_1.Singleton];
|
|
50
51
|
let _classDescriptor;
|
|
@@ -77,6 +78,8 @@ let DevicesPageService = (() => {
|
|
|
77
78
|
stateMachine;
|
|
78
79
|
logObserver;
|
|
79
80
|
openedCapability;
|
|
81
|
+
openedInterfaceSettings;
|
|
82
|
+
interfaceSettingsObserver;
|
|
80
83
|
constructor() {
|
|
81
84
|
super('Pairing');
|
|
82
85
|
this.stateMachine = new statemachine_1.PairingPageStateMachine();
|
|
@@ -163,7 +166,7 @@ let DevicesPageService = (() => {
|
|
|
163
166
|
const caps = this.state.capabilities ?? [];
|
|
164
167
|
const ifs = this.state.interfaces ?? [];
|
|
165
168
|
(0, access_1.useDeviceAccess)().enrichWithAccessState(ifs);
|
|
166
|
-
const interfaces = ifs.map(i => this.getInterfaceDisplayProps(i));
|
|
169
|
+
const interfaces = ifs.map(i => { return this.getInterfaceDisplayProps(i); });
|
|
167
170
|
const capProps = caps.map(c => this.getCapabilityDisplayProps(c));
|
|
168
171
|
const loading = this.promiseOpen != undefined;
|
|
169
172
|
const CP = (cap) => capProps.find(c => c.capability === cap);
|
|
@@ -183,6 +186,7 @@ let DevicesPageService = (() => {
|
|
|
183
186
|
capabilities: { top, bottom },
|
|
184
187
|
interfaces,
|
|
185
188
|
deviceSelection: this.getDeviceListDisplayProps(),
|
|
189
|
+
showInterfaceSettings: this.openedInterfaceSettings,
|
|
186
190
|
buttons,
|
|
187
191
|
onExit
|
|
188
192
|
};
|
|
@@ -193,10 +197,34 @@ let DevicesPageService = (() => {
|
|
|
193
197
|
capabilities: { top: [], bottom: [] },
|
|
194
198
|
interfaces: [],
|
|
195
199
|
buttons: [{ label: 'Skip', primary: true, onClick: this.onSkip.bind(this) }],
|
|
200
|
+
showInterfaceSettings: this.openedInterfaceSettings,
|
|
196
201
|
onExit
|
|
197
202
|
};
|
|
198
203
|
}
|
|
199
204
|
}
|
|
205
|
+
getInterfaceSettingsObserver() {
|
|
206
|
+
this.interfaceSettingsObserver = this.interfaceSettingsObserver ?? new types_1.Observer();
|
|
207
|
+
return this.interfaceSettingsObserver;
|
|
208
|
+
}
|
|
209
|
+
getInterfaceSettingsDisplayProps() {
|
|
210
|
+
if (!this.openedInterfaceSettings)
|
|
211
|
+
return;
|
|
212
|
+
const ifs = this.state.interfaces ?? [];
|
|
213
|
+
const info = ifs.find(isd => isd.name == this.openedInterfaceSettings);
|
|
214
|
+
return {
|
|
215
|
+
state: this.mapInterfaceState(info.state),
|
|
216
|
+
enabled: info.enabled,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
enableInterface(i) { }
|
|
220
|
+
disableInterface(i) { }
|
|
221
|
+
reconnectInterface(i) { }
|
|
222
|
+
refreshInterface(i) { }
|
|
223
|
+
closeInterfaceSettings() {
|
|
224
|
+
this.openedInterfaceSettings = undefined;
|
|
225
|
+
this.interfaceSettingsObserver?.stop();
|
|
226
|
+
this.updatePage();
|
|
227
|
+
}
|
|
200
228
|
getCapabilityDisplayProps(data) {
|
|
201
229
|
const { capability: cap, deviceName, connectState, value, unit, disabled } = data;
|
|
202
230
|
const capability = this.getTCapability(cap);
|
|
@@ -210,8 +238,7 @@ let DevicesPageService = (() => {
|
|
|
210
238
|
onClick
|
|
211
239
|
};
|
|
212
240
|
}
|
|
213
|
-
|
|
214
|
-
const { name, state } = info;
|
|
241
|
+
mapInterfaceState(state) {
|
|
215
242
|
const mapping = {
|
|
216
243
|
connected: 'scanning',
|
|
217
244
|
connecting: "idle",
|
|
@@ -220,9 +247,14 @@ let DevicesPageService = (() => {
|
|
|
220
247
|
unavailable: 'error',
|
|
221
248
|
unknown: 'idle'
|
|
222
249
|
};
|
|
250
|
+
return mapping[state];
|
|
251
|
+
}
|
|
252
|
+
getInterfaceDisplayProps(info) {
|
|
253
|
+
const { name, state } = info;
|
|
223
254
|
return {
|
|
224
255
|
name,
|
|
225
|
-
state:
|
|
256
|
+
state: this.mapInterfaceState(state),
|
|
257
|
+
onClick: () => { this.openInterfaceSettings(name); }
|
|
226
258
|
};
|
|
227
259
|
}
|
|
228
260
|
getDeviceListDisplayProps() {
|
|
@@ -253,6 +285,11 @@ let DevicesPageService = (() => {
|
|
|
253
285
|
updatePage() {
|
|
254
286
|
this.getPageObserver().emit('page-update');
|
|
255
287
|
}
|
|
288
|
+
openInterfaceSettings(i) {
|
|
289
|
+
const info = this.state.interfaces.find(id => id.name === i);
|
|
290
|
+
this.openedInterfaceSettings = i;
|
|
291
|
+
this.updatePage();
|
|
292
|
+
}
|
|
256
293
|
onEnableCapability(enabled) {
|
|
257
294
|
const all = this.state.capabilities ?? [];
|
|
258
295
|
const requested = all.find(c => c.capability === this.openedCapability);
|
|
@@ -260,7 +297,7 @@ let DevicesPageService = (() => {
|
|
|
260
297
|
this.updatePage();
|
|
261
298
|
}
|
|
262
299
|
openDeviceSelection(cap) {
|
|
263
|
-
this.logEvent({ message: 'capability clicked', capability: cap });
|
|
300
|
+
this.logEvent({ message: 'capability clicked', capability: cap, eventSource: 'user' });
|
|
264
301
|
this.openedCapability = cap;
|
|
265
302
|
this.stateMachine.onDeviceSelectionOpened(() => { this.updatePage(); });
|
|
266
303
|
this.updatePage();
|
|
@@ -93,13 +93,14 @@ let PairingPageStateMachine = (() => {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
stop() {
|
|
96
|
+
console.log('# statemachin stop');
|
|
96
97
|
try {
|
|
97
98
|
const prev = this.state;
|
|
98
99
|
this.unregisterServiceEventHandlers();
|
|
99
100
|
delete this.stateChangeCallback;
|
|
100
101
|
this.resetTimeouts();
|
|
101
102
|
this.setState('Closed');
|
|
102
|
-
this.logIncomingEvent('stop', prev, '
|
|
103
|
+
this.logIncomingEvent('stop', prev, 'Closed');
|
|
103
104
|
}
|
|
104
105
|
catch (err) {
|
|
105
106
|
this.logError(err, 'stop');
|
|
@@ -180,7 +181,7 @@ let PairingPageStateMachine = (() => {
|
|
|
180
181
|
}
|
|
181
182
|
else {
|
|
182
183
|
if (this.selectStateChangeCallback)
|
|
183
|
-
this.selectStateChangeCallback;
|
|
184
|
+
this.selectStateChangeCallback();
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
performCheck(prevState) {
|
package/lib/cjs/ui/service.js
CHANGED
|
@@ -49,6 +49,7 @@ const activities_1 = require("../activities");
|
|
|
49
49
|
const monitoring_1 = require("../monitoring");
|
|
50
50
|
const appstate_1 = require("../appstate");
|
|
51
51
|
const pages_1 = require("../base/pages");
|
|
52
|
+
const utils_1 = require("../utils");
|
|
52
53
|
let UserInterfaceServcie = (() => {
|
|
53
54
|
let _classDecorators = [decorators_1.Singleton];
|
|
54
55
|
let _classDescriptor;
|
|
@@ -84,6 +85,7 @@ let UserInterfaceServcie = (() => {
|
|
|
84
85
|
platform;
|
|
85
86
|
version;
|
|
86
87
|
isTerminating;
|
|
88
|
+
isTerminated;
|
|
87
89
|
queuedMessages = [];
|
|
88
90
|
iv;
|
|
89
91
|
heartbeatIv;
|
|
@@ -93,6 +95,7 @@ let UserInterfaceServcie = (() => {
|
|
|
93
95
|
super('Incyclist');
|
|
94
96
|
this.bindings = this.getBindings();
|
|
95
97
|
this.isTerminating = false;
|
|
98
|
+
this.isTerminated = false;
|
|
96
99
|
}
|
|
97
100
|
getBindings() {
|
|
98
101
|
return (0, api_1.getBindings)();
|
|
@@ -103,6 +106,8 @@ let UserInterfaceServcie = (() => {
|
|
|
103
106
|
};
|
|
104
107
|
}
|
|
105
108
|
async onAppLaunch(platform, version, appFeatures) {
|
|
109
|
+
this.isTerminated = false;
|
|
110
|
+
this.isTerminating = false;
|
|
106
111
|
try {
|
|
107
112
|
this.platform = platform;
|
|
108
113
|
this.version = version;
|
|
@@ -128,16 +133,21 @@ let UserInterfaceServcie = (() => {
|
|
|
128
133
|
}
|
|
129
134
|
}
|
|
130
135
|
async onAppExit() {
|
|
136
|
+
if (this.isTerminated)
|
|
137
|
+
return;
|
|
131
138
|
try {
|
|
132
139
|
if (!this.isTerminating) {
|
|
133
140
|
this.isTerminating = true;
|
|
134
141
|
this.logEvent({ message: 'onAppExit called' });
|
|
135
142
|
this.stopHeartbeatWorker();
|
|
136
143
|
this.sendAppExitMessage();
|
|
144
|
+
pages_1.IncyclistPageService.closePage();
|
|
145
|
+
await (0, utils_1.waitNextTick)();
|
|
137
146
|
await (0, devices_1.useDevicePairing)().exit();
|
|
138
|
-
await (0, devices_1.useDeviceAccess)().
|
|
147
|
+
await (0, devices_1.useDeviceAccess)().terminate();
|
|
139
148
|
this.appState = 'Stopped';
|
|
140
149
|
this.logEvent({ message: 'onAppExit finished' });
|
|
150
|
+
this.isTerminated = true;
|
|
141
151
|
return true;
|
|
142
152
|
}
|
|
143
153
|
return false;
|
|
@@ -148,6 +158,8 @@ let UserInterfaceServcie = (() => {
|
|
|
148
158
|
}
|
|
149
159
|
}
|
|
150
160
|
async onAppPause() {
|
|
161
|
+
if (this.isTerminated || this.isTerminating)
|
|
162
|
+
return;
|
|
151
163
|
try {
|
|
152
164
|
this.appState = 'Background';
|
|
153
165
|
this.logEvent({ message: 'onAppPause called' });
|
|
@@ -161,6 +173,12 @@ let UserInterfaceServcie = (() => {
|
|
|
161
173
|
return true;
|
|
162
174
|
}
|
|
163
175
|
async onAppResume() {
|
|
176
|
+
if (this.isTerminated) {
|
|
177
|
+
await this.onAppLaunch(this.platform, this.version, this.appFeatures);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.isTerminated = false;
|
|
181
|
+
this.isTerminating = false;
|
|
164
182
|
try {
|
|
165
183
|
this.appState = 'Active';
|
|
166
184
|
this.logEvent({ message: 'onAppResume called' });
|
|
@@ -226,19 +226,24 @@ let ActivityListService = (() => {
|
|
|
226
226
|
}
|
|
227
227
|
const startStettings = this.selected.createStartSettings();
|
|
228
228
|
const card = this.selected.getRouteCard();
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
route.details = await routes.getRouteDetails(route.description.id);
|
|
229
|
+
if (card) {
|
|
230
|
+
const routes = this.getRouteList();
|
|
231
|
+
routes.selectCard(card);
|
|
232
|
+
routes.setStartSettings(startStettings);
|
|
233
|
+
const route = routes.getSelected();
|
|
235
234
|
if (!route.details) {
|
|
236
|
-
|
|
235
|
+
route.details = await routes.getRouteDetails(route.description.id);
|
|
236
|
+
if (!route.details) {
|
|
237
|
+
return { canStart: false };
|
|
238
|
+
}
|
|
237
239
|
}
|
|
240
|
+
card.changeSettings(startStettings);
|
|
241
|
+
card.start();
|
|
242
|
+
return { canStart: true, route };
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
return { canStart: false };
|
|
238
246
|
}
|
|
239
|
-
card.changeSettings(startStettings);
|
|
240
|
-
card.start();
|
|
241
|
-
return { canStart: true, route };
|
|
242
247
|
}
|
|
243
248
|
catch (err) {
|
|
244
249
|
this.logError(err, 'rideAgain');
|
|
@@ -50,6 +50,9 @@ let IncyclistPageService = (() => {
|
|
|
50
50
|
name = __runInitializers(this, _instanceExtraInitializers);
|
|
51
51
|
pageObserver;
|
|
52
52
|
static currentPage;
|
|
53
|
+
static closePage() {
|
|
54
|
+
this.currentPage?.closePage();
|
|
55
|
+
}
|
|
53
56
|
static async pausePage() {
|
|
54
57
|
await this.currentPage?.pausePage();
|
|
55
58
|
}
|
|
@@ -86,6 +86,10 @@ let DeviceAccessService = (() => {
|
|
|
86
86
|
this.logEvent({ message: 'Illegal State, enable Interface cannot be called during an ongoing scan', interface: ifaceName });
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
+
existing.interface.removeAllListeners('disconnect');
|
|
90
|
+
existing.interface.on('disconnect', () => {
|
|
91
|
+
this.emit('interface-changed', ifaceName, { ...existing, state: 'disconnected' });
|
|
92
|
+
});
|
|
89
93
|
if (existing.enabled && ((existing.state === 'connected' && existing?.interface?.isConnected()) || existing.state === 'connecting')) {
|
|
90
94
|
return;
|
|
91
95
|
}
|
|
@@ -261,6 +265,16 @@ let DeviceAccessService = (() => {
|
|
|
261
265
|
this.emit('interface-changed', ifaceName, { ...this.interfaces[ifaceName] });
|
|
262
266
|
return disconnected;
|
|
263
267
|
}
|
|
268
|
+
async terminate(ifaceName) {
|
|
269
|
+
await this.disconnect(ifaceName);
|
|
270
|
+
if (!ifaceName) {
|
|
271
|
+
const promises = Object.keys(this.interfaces).map(i => this.terminate(i));
|
|
272
|
+
await Promise.allSettled(promises);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const impl = this.getInterface(ifaceName);
|
|
276
|
+
await impl.terminate();
|
|
277
|
+
}
|
|
264
278
|
async scan(filter = {}, props = {}) {
|
|
265
279
|
this.logEvent({ message: 'device scan start', filter, props });
|
|
266
280
|
const detected = [];
|
|
@@ -42,6 +42,7 @@ import { useDeviceAccess } from '../access';
|
|
|
42
42
|
import { useDeviceConfiguration } from '../configuration';
|
|
43
43
|
import { getBindings } from '../../api';
|
|
44
44
|
import { useIncyclist } from '../../ui';
|
|
45
|
+
import { Observer } from '../../base/types';
|
|
45
46
|
let DevicesPageService = (() => {
|
|
46
47
|
let _classDecorators = [Singleton];
|
|
47
48
|
let _classDescriptor;
|
|
@@ -74,6 +75,8 @@ let DevicesPageService = (() => {
|
|
|
74
75
|
stateMachine;
|
|
75
76
|
logObserver;
|
|
76
77
|
openedCapability;
|
|
78
|
+
openedInterfaceSettings;
|
|
79
|
+
interfaceSettingsObserver;
|
|
77
80
|
constructor() {
|
|
78
81
|
super('Pairing');
|
|
79
82
|
this.stateMachine = new PairingPageStateMachine();
|
|
@@ -160,7 +163,7 @@ let DevicesPageService = (() => {
|
|
|
160
163
|
const caps = this.state.capabilities ?? [];
|
|
161
164
|
const ifs = this.state.interfaces ?? [];
|
|
162
165
|
useDeviceAccess().enrichWithAccessState(ifs);
|
|
163
|
-
const interfaces = ifs.map(i => this.getInterfaceDisplayProps(i));
|
|
166
|
+
const interfaces = ifs.map(i => { return this.getInterfaceDisplayProps(i); });
|
|
164
167
|
const capProps = caps.map(c => this.getCapabilityDisplayProps(c));
|
|
165
168
|
const loading = this.promiseOpen != undefined;
|
|
166
169
|
const CP = (cap) => capProps.find(c => c.capability === cap);
|
|
@@ -180,6 +183,7 @@ let DevicesPageService = (() => {
|
|
|
180
183
|
capabilities: { top, bottom },
|
|
181
184
|
interfaces,
|
|
182
185
|
deviceSelection: this.getDeviceListDisplayProps(),
|
|
186
|
+
showInterfaceSettings: this.openedInterfaceSettings,
|
|
183
187
|
buttons,
|
|
184
188
|
onExit
|
|
185
189
|
};
|
|
@@ -190,10 +194,34 @@ let DevicesPageService = (() => {
|
|
|
190
194
|
capabilities: { top: [], bottom: [] },
|
|
191
195
|
interfaces: [],
|
|
192
196
|
buttons: [{ label: 'Skip', primary: true, onClick: this.onSkip.bind(this) }],
|
|
197
|
+
showInterfaceSettings: this.openedInterfaceSettings,
|
|
193
198
|
onExit
|
|
194
199
|
};
|
|
195
200
|
}
|
|
196
201
|
}
|
|
202
|
+
getInterfaceSettingsObserver() {
|
|
203
|
+
this.interfaceSettingsObserver = this.interfaceSettingsObserver ?? new Observer();
|
|
204
|
+
return this.interfaceSettingsObserver;
|
|
205
|
+
}
|
|
206
|
+
getInterfaceSettingsDisplayProps() {
|
|
207
|
+
if (!this.openedInterfaceSettings)
|
|
208
|
+
return;
|
|
209
|
+
const ifs = this.state.interfaces ?? [];
|
|
210
|
+
const info = ifs.find(isd => isd.name == this.openedInterfaceSettings);
|
|
211
|
+
return {
|
|
212
|
+
state: this.mapInterfaceState(info.state),
|
|
213
|
+
enabled: info.enabled,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
enableInterface(i) { }
|
|
217
|
+
disableInterface(i) { }
|
|
218
|
+
reconnectInterface(i) { }
|
|
219
|
+
refreshInterface(i) { }
|
|
220
|
+
closeInterfaceSettings() {
|
|
221
|
+
this.openedInterfaceSettings = undefined;
|
|
222
|
+
this.interfaceSettingsObserver?.stop();
|
|
223
|
+
this.updatePage();
|
|
224
|
+
}
|
|
197
225
|
getCapabilityDisplayProps(data) {
|
|
198
226
|
const { capability: cap, deviceName, connectState, value, unit, disabled } = data;
|
|
199
227
|
const capability = this.getTCapability(cap);
|
|
@@ -207,8 +235,7 @@ let DevicesPageService = (() => {
|
|
|
207
235
|
onClick
|
|
208
236
|
};
|
|
209
237
|
}
|
|
210
|
-
|
|
211
|
-
const { name, state } = info;
|
|
238
|
+
mapInterfaceState(state) {
|
|
212
239
|
const mapping = {
|
|
213
240
|
connected: 'scanning',
|
|
214
241
|
connecting: "idle",
|
|
@@ -217,9 +244,14 @@ let DevicesPageService = (() => {
|
|
|
217
244
|
unavailable: 'error',
|
|
218
245
|
unknown: 'idle'
|
|
219
246
|
};
|
|
247
|
+
return mapping[state];
|
|
248
|
+
}
|
|
249
|
+
getInterfaceDisplayProps(info) {
|
|
250
|
+
const { name, state } = info;
|
|
220
251
|
return {
|
|
221
252
|
name,
|
|
222
|
-
state:
|
|
253
|
+
state: this.mapInterfaceState(state),
|
|
254
|
+
onClick: () => { this.openInterfaceSettings(name); }
|
|
223
255
|
};
|
|
224
256
|
}
|
|
225
257
|
getDeviceListDisplayProps() {
|
|
@@ -250,6 +282,11 @@ let DevicesPageService = (() => {
|
|
|
250
282
|
updatePage() {
|
|
251
283
|
this.getPageObserver().emit('page-update');
|
|
252
284
|
}
|
|
285
|
+
openInterfaceSettings(i) {
|
|
286
|
+
const info = this.state.interfaces.find(id => id.name === i);
|
|
287
|
+
this.openedInterfaceSettings = i;
|
|
288
|
+
this.updatePage();
|
|
289
|
+
}
|
|
253
290
|
onEnableCapability(enabled) {
|
|
254
291
|
const all = this.state.capabilities ?? [];
|
|
255
292
|
const requested = all.find(c => c.capability === this.openedCapability);
|
|
@@ -257,7 +294,7 @@ let DevicesPageService = (() => {
|
|
|
257
294
|
this.updatePage();
|
|
258
295
|
}
|
|
259
296
|
openDeviceSelection(cap) {
|
|
260
|
-
this.logEvent({ message: 'capability clicked', capability: cap });
|
|
297
|
+
this.logEvent({ message: 'capability clicked', capability: cap, eventSource: 'user' });
|
|
261
298
|
this.openedCapability = cap;
|
|
262
299
|
this.stateMachine.onDeviceSelectionOpened(() => { this.updatePage(); });
|
|
263
300
|
this.updatePage();
|
|
@@ -90,13 +90,14 @@ let PairingPageStateMachine = (() => {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
stop() {
|
|
93
|
+
console.log('# statemachin stop');
|
|
93
94
|
try {
|
|
94
95
|
const prev = this.state;
|
|
95
96
|
this.unregisterServiceEventHandlers();
|
|
96
97
|
delete this.stateChangeCallback;
|
|
97
98
|
this.resetTimeouts();
|
|
98
99
|
this.setState('Closed');
|
|
99
|
-
this.logIncomingEvent('stop', prev, '
|
|
100
|
+
this.logIncomingEvent('stop', prev, 'Closed');
|
|
100
101
|
}
|
|
101
102
|
catch (err) {
|
|
102
103
|
this.logError(err, 'stop');
|
|
@@ -177,7 +178,7 @@ let PairingPageStateMachine = (() => {
|
|
|
177
178
|
}
|
|
178
179
|
else {
|
|
179
180
|
if (this.selectStateChangeCallback)
|
|
180
|
-
this.selectStateChangeCallback;
|
|
181
|
+
this.selectStateChangeCallback();
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
performCheck(prevState) {
|
package/lib/esm/ui/service.js
CHANGED
|
@@ -46,6 +46,7 @@ import { useActiveRides, useActivityList } from "../activities";
|
|
|
46
46
|
import { useOnlineStatusMonitoring } from "../monitoring";
|
|
47
47
|
import { useAppState } from "../appstate";
|
|
48
48
|
import { IncyclistPageService } from "../base/pages";
|
|
49
|
+
import { waitNextTick } from "../utils";
|
|
49
50
|
let UserInterfaceServcie = (() => {
|
|
50
51
|
let _classDecorators = [Singleton];
|
|
51
52
|
let _classDescriptor;
|
|
@@ -81,6 +82,7 @@ let UserInterfaceServcie = (() => {
|
|
|
81
82
|
platform;
|
|
82
83
|
version;
|
|
83
84
|
isTerminating;
|
|
85
|
+
isTerminated;
|
|
84
86
|
queuedMessages = [];
|
|
85
87
|
iv;
|
|
86
88
|
heartbeatIv;
|
|
@@ -90,6 +92,7 @@ let UserInterfaceServcie = (() => {
|
|
|
90
92
|
super('Incyclist');
|
|
91
93
|
this.bindings = this.getBindings();
|
|
92
94
|
this.isTerminating = false;
|
|
95
|
+
this.isTerminated = false;
|
|
93
96
|
}
|
|
94
97
|
getBindings() {
|
|
95
98
|
return getBindings();
|
|
@@ -100,6 +103,8 @@ let UserInterfaceServcie = (() => {
|
|
|
100
103
|
};
|
|
101
104
|
}
|
|
102
105
|
async onAppLaunch(platform, version, appFeatures) {
|
|
106
|
+
this.isTerminated = false;
|
|
107
|
+
this.isTerminating = false;
|
|
103
108
|
try {
|
|
104
109
|
this.platform = platform;
|
|
105
110
|
this.version = version;
|
|
@@ -125,16 +130,21 @@ let UserInterfaceServcie = (() => {
|
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
async onAppExit() {
|
|
133
|
+
if (this.isTerminated)
|
|
134
|
+
return;
|
|
128
135
|
try {
|
|
129
136
|
if (!this.isTerminating) {
|
|
130
137
|
this.isTerminating = true;
|
|
131
138
|
this.logEvent({ message: 'onAppExit called' });
|
|
132
139
|
this.stopHeartbeatWorker();
|
|
133
140
|
this.sendAppExitMessage();
|
|
141
|
+
IncyclistPageService.closePage();
|
|
142
|
+
await waitNextTick();
|
|
134
143
|
await useDevicePairing().exit();
|
|
135
|
-
await useDeviceAccess().
|
|
144
|
+
await useDeviceAccess().terminate();
|
|
136
145
|
this.appState = 'Stopped';
|
|
137
146
|
this.logEvent({ message: 'onAppExit finished' });
|
|
147
|
+
this.isTerminated = true;
|
|
138
148
|
return true;
|
|
139
149
|
}
|
|
140
150
|
return false;
|
|
@@ -145,6 +155,8 @@ let UserInterfaceServcie = (() => {
|
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
157
|
async onAppPause() {
|
|
158
|
+
if (this.isTerminated || this.isTerminating)
|
|
159
|
+
return;
|
|
148
160
|
try {
|
|
149
161
|
this.appState = 'Background';
|
|
150
162
|
this.logEvent({ message: 'onAppPause called' });
|
|
@@ -158,6 +170,12 @@ let UserInterfaceServcie = (() => {
|
|
|
158
170
|
return true;
|
|
159
171
|
}
|
|
160
172
|
async onAppResume() {
|
|
173
|
+
if (this.isTerminated) {
|
|
174
|
+
await this.onAppLaunch(this.platform, this.version, this.appFeatures);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.isTerminated = false;
|
|
178
|
+
this.isTerminating = false;
|
|
161
179
|
try {
|
|
162
180
|
this.appState = 'Active';
|
|
163
181
|
this.logEvent({ message: 'onAppResume called' });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type SelectDirectoryResult = {
|
|
2
|
-
selected
|
|
2
|
+
selected?: string;
|
|
3
|
+
canceled?: boolean;
|
|
3
4
|
};
|
|
4
5
|
export type TakeScreenshotProps = {
|
|
5
6
|
fileName?: string;
|
|
@@ -12,7 +13,7 @@ export interface INativeUI {
|
|
|
12
13
|
takeScreenshot(props: TakeScreenshotProps): Promise<string>;
|
|
13
14
|
openBrowserWindow(url: string): void;
|
|
14
15
|
openAppWindow(url: string): void;
|
|
15
|
-
selectDirectory(): SelectDirectoryResult
|
|
16
|
+
selectDirectory(): Promise<SelectDirectoryResult>;
|
|
16
17
|
showItemInFolder(fileName: string): void;
|
|
17
18
|
getPathForFile(file: string): string;
|
|
18
19
|
detectLanguage(): Array<string> | string;
|
|
@@ -5,6 +5,7 @@ export declare class IncyclistPageService extends IncyclistService implements IP
|
|
|
5
5
|
protected name: string;
|
|
6
6
|
private pageObserver;
|
|
7
7
|
static currentPage: IPageService | undefined;
|
|
8
|
+
static closePage(): void;
|
|
8
9
|
static pausePage(): Promise<void>;
|
|
9
10
|
static resumePage(): Promise<void>;
|
|
10
11
|
constructor(name: string);
|
|
@@ -22,6 +22,7 @@ export declare class DeviceAccessService extends IncyclistService {
|
|
|
22
22
|
connect(ifaceName?: string): Promise<boolean>;
|
|
23
23
|
private getScanTimeout;
|
|
24
24
|
disconnect(ifaceName?: string): Promise<boolean>;
|
|
25
|
+
terminate(ifaceName?: string): Promise<void>;
|
|
25
26
|
scan(filter?: ScanFilter, props?: {
|
|
26
27
|
timeout?: number;
|
|
27
28
|
includeKnown?: boolean;
|
|
@@ -1,25 +1,37 @@
|
|
|
1
1
|
import { IncyclistPageService } from '../../base/pages';
|
|
2
|
-
import type { CapabilityDisplayProps, DeviceSelectionProps, InterfaceDisplayProps, IObserver, PairingButtonProps, PairingDisplayProps, TDisplayCapability, TIncyclistCapability } from '../../types';
|
|
2
|
+
import type { CapabilityDisplayProps, DeviceSelectionProps, InterfaceDisplayProps, InterfaceDisplayState, InterfaceSettingsDisplayProps, IObserver, PairingButtonProps, PairingDisplayProps, TDisplayCapability, TIncyclistCapability, TInterface } from '../../types';
|
|
3
3
|
import type { CapabilityData, DevicePairingData, InternalPairingState } from '../pairing';
|
|
4
4
|
import { PairingPageStateMachine } from './statemachine';
|
|
5
5
|
import { PageLogObserver } from './logobserver';
|
|
6
|
-
import { EnrichedInterfaceSetting } from '../access';
|
|
6
|
+
import { EnrichedInterfaceSetting, InterfaceState } from '../access';
|
|
7
7
|
import { IncyclistCapability } from 'incyclist-devices';
|
|
8
|
+
import { Observer } from '../../base/types';
|
|
8
9
|
export declare class DevicesPageService extends IncyclistPageService {
|
|
9
10
|
protected promiseOpen: Promise<void> | undefined;
|
|
10
11
|
protected stateMachine: PairingPageStateMachine;
|
|
11
12
|
protected logObserver: PageLogObserver;
|
|
12
13
|
protected openedCapability: IncyclistCapability | undefined;
|
|
14
|
+
protected openedInterfaceSettings: TInterface;
|
|
15
|
+
protected interfaceSettingsObserver: Observer | undefined;
|
|
13
16
|
constructor();
|
|
14
17
|
openPage(): IObserver;
|
|
15
18
|
closePage(): void;
|
|
16
19
|
pausePage(): Promise<void>;
|
|
17
20
|
resumePage(): Promise<void>;
|
|
18
21
|
getPageDisplayProperties(): PairingDisplayProps;
|
|
22
|
+
getInterfaceSettingsObserver(): Observer;
|
|
23
|
+
getInterfaceSettingsDisplayProps(): InterfaceSettingsDisplayProps;
|
|
24
|
+
enableInterface(i?: TInterface): void;
|
|
25
|
+
disableInterface(i?: TInterface): void;
|
|
26
|
+
reconnectInterface(i?: TInterface): void;
|
|
27
|
+
refreshInterface(i?: TInterface): void;
|
|
28
|
+
closeInterfaceSettings(): void;
|
|
19
29
|
protected getCapabilityDisplayProps(data: CapabilityData): CapabilityDisplayProps;
|
|
30
|
+
protected mapInterfaceState(state: InterfaceState): InterfaceDisplayState;
|
|
20
31
|
protected getInterfaceDisplayProps(info: EnrichedInterfaceSetting): InterfaceDisplayProps;
|
|
21
32
|
protected getDeviceListDisplayProps(): DeviceSelectionProps | undefined;
|
|
22
33
|
protected updatePage(): void;
|
|
34
|
+
protected openInterfaceSettings(i: TInterface): void;
|
|
23
35
|
protected onEnableCapability(enabled: boolean): void;
|
|
24
36
|
protected openDeviceSelection(cap: IncyclistCapability): void;
|
|
25
37
|
protected onDeviceSelected(d: DevicePairingData, addAll?: boolean): void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DevicePairingStatus } from "../pairing/model";
|
|
2
2
|
export type PageState = 'Idle' | 'Scanning' | 'Pairing' | 'Done' | 'Closed';
|
|
3
3
|
export type SelectState = 'Closed' | 'Waiting' | 'Active';
|
|
4
|
+
export type TInterface = 'ble' | 'wifi';
|
|
4
5
|
export type PairingDisplayProps = {
|
|
5
6
|
title: string | undefined;
|
|
6
7
|
capabilities?: {
|
|
@@ -10,6 +11,7 @@ export type PairingDisplayProps = {
|
|
|
10
11
|
interfaces?: Array<InterfaceDisplayProps>;
|
|
11
12
|
buttons?: PairingButtonProps;
|
|
12
13
|
deviceSelection?: DeviceSelectionProps;
|
|
14
|
+
showInterfaceSettings: TInterface | undefined;
|
|
13
15
|
showExit?: boolean;
|
|
14
16
|
onExit?: () => void;
|
|
15
17
|
};
|
|
@@ -49,6 +51,12 @@ export type InterfaceDisplayProps = {
|
|
|
49
51
|
name: string;
|
|
50
52
|
state: InterfaceDisplayState;
|
|
51
53
|
error?: string;
|
|
54
|
+
onClick: () => void;
|
|
55
|
+
};
|
|
56
|
+
export type InterfaceSettingsDisplayProps = {
|
|
57
|
+
state?: InterfaceDisplayState;
|
|
58
|
+
error?: string;
|
|
59
|
+
enabled: boolean;
|
|
52
60
|
};
|
|
53
61
|
export type NextPageAction = {
|
|
54
62
|
nextPage: string;
|
|
@@ -9,6 +9,7 @@ export declare class UserInterfaceServcie extends IncyclistService {
|
|
|
9
9
|
protected platform: IncyclistPlatform;
|
|
10
10
|
protected version: string;
|
|
11
11
|
protected isTerminating: boolean;
|
|
12
|
+
protected isTerminated: boolean;
|
|
12
13
|
protected queuedMessages: Array<{
|
|
13
14
|
topic: string;
|
|
14
15
|
payload: object;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "incyclist-services",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.18",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"gd-eventlog": "^0.1.27"
|
|
6
6
|
},
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"axios": "^1.13.5",
|
|
9
|
-
"incyclist-devices": "^3.0.
|
|
9
|
+
"incyclist-devices": "^3.0.9",
|
|
10
10
|
"promise.any": "^2.0.6",
|
|
11
11
|
"semver": "^7.7.4",
|
|
12
12
|
"tcx-builder": "^1.1.1",
|