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.
@@ -229,19 +229,24 @@ let ActivityListService = (() => {
229
229
  }
230
230
  const startStettings = this.selected.createStartSettings();
231
231
  const card = this.selected.getRouteCard();
232
- const routes = this.getRouteList();
233
- routes.selectCard(card);
234
- routes.setStartSettings(startStettings);
235
- const route = routes.getSelected();
236
- if (!route.details) {
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
- return { canStart: false };
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
- getInterfaceDisplayProps(info) {
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: mapping[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, 'Idle');
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) {
@@ -200,7 +200,7 @@ let DevicePairingService = (() => {
200
200
  }
201
201
  }
202
202
  async exit() {
203
- return this.stop([], true);
203
+ return await this.stop([], true);
204
204
  }
205
205
  async prepareStart(adapterFilter = []) {
206
206
  const stillPairing = this.isPairing();
@@ -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)().disconnect();
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
- const routes = this.getRouteList();
230
- routes.selectCard(card);
231
- routes.setStartSettings(startStettings);
232
- const route = routes.getSelected();
233
- if (!route.details) {
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
- return { canStart: false };
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
- getInterfaceDisplayProps(info) {
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: mapping[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, 'Idle');
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) {
@@ -194,7 +194,7 @@ let DevicePairingService = (() => {
194
194
  }
195
195
  }
196
196
  async exit() {
197
- return this.stop([], true);
197
+ return await this.stop([], true);
198
198
  }
199
199
  async prepareStart(adapterFilter = []) {
200
200
  const stillPairing = this.isPairing();
@@ -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().disconnect();
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: string;
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.16",
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.7",
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",