@mentra/engine 3.1.0-dev.17 → 3.1.0-dev.21
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/README.md +19 -5
- package/build/bluetooth-sdk/ota-transport.d.ts +2 -0
- package/build/bluetooth-sdk/ota-transport.d.ts.map +1 -0
- package/build/bluetooth-sdk/ota-transport.js +2 -0
- package/build/bluetooth-sdk/ota-transport.js.map +1 -0
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +1 -2
- package/build/facades/ota.js.map +1 -1
- package/build/generated/releaseMetadata.js +5 -5
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +3 -2
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -1
- package/build/react/MentraLiveOtaFlow.js +68 -345
- package/build/react/MentraLiveOtaFlow.js.map +1 -1
- package/build/react/index.d.ts +1 -0
- package/build/react/index.d.ts.map +1 -1
- package/build/react/index.js +1 -0
- package/build/react/index.js.map +1 -1
- package/build/react/useMentraLiveOta.d.ts +69 -0
- package/build/react/useMentraLiveOta.d.ts.map +1 -0
- package/build/react/useMentraLiveOta.js +485 -0
- package/build/react/useMentraLiveOta.js.map +1 -0
- package/build/services/GlassesStatusProjection.d.ts +15 -2
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +3 -3
- package/build/services/GlassesStatusProjection.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts.map +1 -1
- package/build/services/HotspotOtaTransport.js +8 -7
- package/build/services/HotspotOtaTransport.js.map +1 -1
- package/build/services/OtaInstallCoordinator.d.ts +22 -1
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +8 -8
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +1 -1
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +1 -1
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +6 -2
- package/build/services/OtaUpdateCheckService.js.map +1 -1
- package/build/services/asg/localNetworkTransport.d.ts.map +1 -1
- package/build/services/asg/localNetworkTransport.js +13 -12
- package/build/services/asg/localNetworkTransport.js.map +1 -1
- package/build/services/glassesClockSync.js +1 -1
- package/build/services/glassesClockSync.js.map +1 -1
- package/build/stores/core.d.ts +3 -3
- package/build/stores/core.d.ts.map +1 -1
- package/build/stores/core.js.map +1 -1
- package/build/stores/glasses.d.ts +10 -4
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js.map +1 -1
- package/package.json +12 -6
- package/src/bluetooth-sdk/ota-transport.ts +1 -0
- package/src/facades/ota.ts +1 -2
- package/src/generated/releaseMetadata.ts +5 -5
- package/src/react/MentraLiveOtaFlow.tsx +116 -466
- package/src/react/index.ts +13 -0
- package/src/react/useMentraLiveOta.ts +619 -0
- package/src/services/GlassesStatusProjection.ts +7 -6
- package/src/services/HotspotOtaTransport.ts +8 -7
- package/src/services/OtaInstallCoordinator.ts +10 -9
- package/src/services/OtaService.ts +1 -2
- package/src/services/OtaUpdateCheckService.ts +8 -5
- package/src/services/asg/localNetworkTransport.ts +20 -19
- package/src/services/glassesClockSync.ts +1 -1
- package/src/stores/core.ts +4 -4
- package/src/stores/glasses.ts +13 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import BluetoothSdk, {isEnabledHotspotStatus
|
|
1
|
+
import BluetoothSdk, {isEnabledHotspotStatus} from "@mentra/bluetooth-sdk"
|
|
2
|
+
import {otaServer} from "@mentra/bluetooth-sdk/ota-transport"
|
|
2
3
|
// One coordinator selects the native Android or iOS staging implementation at runtime.
|
|
3
4
|
// eslint-disable-next-line react-native/split-platform-components
|
|
4
5
|
import {PermissionsAndroid, Platform} from "react-native"
|
|
@@ -83,7 +84,7 @@ class HotspotOtaTransport {
|
|
|
83
84
|
let localAddress = scopedAddress
|
|
84
85
|
if (Platform.OS === "ios") {
|
|
85
86
|
try {
|
|
86
|
-
localAddress = await
|
|
87
|
+
localAddress = await otaServer.waitForWifiAddress(hotspot.localIp, 15_000)
|
|
87
88
|
} catch (error) {
|
|
88
89
|
throw new HotspotOtaTransportError(
|
|
89
90
|
"hotspot_join_failed",
|
|
@@ -94,10 +95,10 @@ class HotspotOtaTransport {
|
|
|
94
95
|
const artifactPaths = Object.fromEntries(this.prepared.map((artifact) => [artifact.sha256, artifact.filePath]))
|
|
95
96
|
// Start exactly one native listener to learn its selected port, then atomically replace
|
|
96
97
|
// the placeholder with the immutable rewritten manifest before ota_start is sent.
|
|
97
|
-
const server = await
|
|
98
|
+
const server = await otaServer.start("{}", artifactPaths, localAddress)
|
|
98
99
|
this.serverStarted = true
|
|
99
100
|
const manifest = rewriteManifestForLocalServer(checkResult.manifestBody, this.prepared, server.baseUrl)
|
|
100
|
-
const published = await
|
|
101
|
+
const published = await otaServer.start(manifest, artifactPaths, server.host)
|
|
101
102
|
if (published.manifestUrl !== server.manifestUrl) {
|
|
102
103
|
throw new Error("Local OTA server endpoint changed while publishing the manifest")
|
|
103
104
|
}
|
|
@@ -141,11 +142,11 @@ class HotspotOtaTransport {
|
|
|
141
142
|
destination: string,
|
|
142
143
|
onProgress?: (bytesWritten: number, contentLength: number) => void,
|
|
143
144
|
): Promise<{statusCode: number}> => {
|
|
144
|
-
const subscription =
|
|
145
|
+
const subscription = otaServer.onArtifactDownloadProgress((event) => {
|
|
145
146
|
if (event.destination === destination) onProgress?.(event.bytesWritten, event.contentLength)
|
|
146
147
|
})
|
|
147
148
|
try {
|
|
148
|
-
return await
|
|
149
|
+
return await otaServer.downloadArtifact(entry.url, destination)
|
|
149
150
|
} finally {
|
|
150
151
|
subscription.remove()
|
|
151
152
|
}
|
|
@@ -164,7 +165,7 @@ class HotspotOtaTransport {
|
|
|
164
165
|
console.warn("[OTA_PROGRESS] glasses hotspot shutdown was not confirmed after bounded retries")
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
|
-
if (this.serverStarted) await
|
|
168
|
+
if (this.serverStarted) await otaServer.stop().catch(() => {})
|
|
168
169
|
if (this.localNetworkConnected) await localNetworkTransport.disconnect().catch(() => {})
|
|
169
170
|
await cleanupArtifacts().catch(() => {})
|
|
170
171
|
this.prepared = []
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
* state written mid-pass queues a follow-up pass — the same way a setState
|
|
18
18
|
* during React effects scheduled a re-render after the current effect batch.
|
|
19
19
|
*/
|
|
20
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
21
|
-
import type {OtaProgress, OtaStatus} from "@mentra/bluetooth-sdk"
|
|
20
|
+
import BluetoothSdk, {type OtaProgress, type OtaStatus} from "@mentra/bluetooth-sdk"
|
|
22
21
|
import GlobalEventEmitter from "../utils/GlobalEventEmitter"
|
|
23
22
|
import {isGlassesConnected, useGlassesStore} from "../stores/glasses"
|
|
24
23
|
import {resolveOtaManifestUrl} from "./otaManifestUrl"
|
|
@@ -170,6 +169,8 @@ export interface OtaInstallSnapshot {
|
|
|
170
169
|
/** Pre-ota_start phone staging/join state for a hotspot attempt. */
|
|
171
170
|
hotspotPhase: HotspotOtaPhase
|
|
172
171
|
hotspotArtifactPercent: number | null
|
|
172
|
+
/** Transport selected from the checked glasses capabilities and Wi-Fi state. */
|
|
173
|
+
transport: "wifi" | "hotspot"
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
type OtaStartOutcome = "pending" | "acknowledged" | "rejected"
|
|
@@ -407,7 +408,7 @@ class OtaInstallCoordinator {
|
|
|
407
408
|
if (this.otaStartOwnership?.outcome === "pending") {
|
|
408
409
|
void this.sendOtaStartWithWatchdogs()
|
|
409
410
|
} else {
|
|
410
|
-
void BluetoothSdk.
|
|
411
|
+
void BluetoothSdk.queryOtaStatus().catch(() => {})
|
|
411
412
|
this.armQueryReplyFallback("retry")
|
|
412
413
|
}
|
|
413
414
|
}
|
|
@@ -455,7 +456,6 @@ class OtaInstallCoordinator {
|
|
|
455
456
|
}
|
|
456
457
|
useGlassesStore.getState().setOtaUpdateAvailable(null)
|
|
457
458
|
if (this.apkStepSeen) {
|
|
458
|
-
BluetoothSdk.updateGlasses({buildNumber: ""})
|
|
459
459
|
useGlassesStore.getState().setGlassesInfo({buildNumber: ""})
|
|
460
460
|
}
|
|
461
461
|
void this.teardownHotspotTransport()
|
|
@@ -505,6 +505,7 @@ class OtaInstallCoordinator {
|
|
|
505
505
|
versionChangePhase: this.deriveVersionChangePhase(connected),
|
|
506
506
|
hotspotPhase: this.hotspotPhase,
|
|
507
507
|
hotspotArtifactPercent: this.hotspotArtifactPercent,
|
|
508
|
+
transport: this.selectedTransport,
|
|
508
509
|
}
|
|
509
510
|
}
|
|
510
511
|
|
|
@@ -1065,7 +1066,7 @@ class OtaInstallCoordinator {
|
|
|
1065
1066
|
if (this.otaStartOwnership?.outcome === "pending") {
|
|
1066
1067
|
void this.sendOtaStartWithWatchdogs()
|
|
1067
1068
|
}
|
|
1068
|
-
void BluetoothSdk.
|
|
1069
|
+
void BluetoothSdk.queryOtaStatus()
|
|
1069
1070
|
this.armQueryReplyFallback("reconnect")
|
|
1070
1071
|
return true
|
|
1071
1072
|
}
|
|
@@ -1109,7 +1110,7 @@ class OtaInstallCoordinator {
|
|
|
1109
1110
|
if (noSessionYet) {
|
|
1110
1111
|
if (!isIdleStatus && this.otaStartOwnership?.outcome === "acknowledged") {
|
|
1111
1112
|
console.log("[OTA_PROGRESS] initial mount, acknowledged session has no cached status — reconciling")
|
|
1112
|
-
void BluetoothSdk.
|
|
1113
|
+
void BluetoothSdk.queryOtaStatus().catch(() => {})
|
|
1113
1114
|
this.armQueryReplyFallback("initial-mount")
|
|
1114
1115
|
return
|
|
1115
1116
|
}
|
|
@@ -1125,7 +1126,7 @@ class OtaInstallCoordinator {
|
|
|
1125
1126
|
void this.sendOtaStartWithWatchdogs()
|
|
1126
1127
|
} else {
|
|
1127
1128
|
console.log("[OTA_PROGRESS] initial mount, session exists, sending ota_query_status")
|
|
1128
|
-
void BluetoothSdk.
|
|
1129
|
+
void BluetoothSdk.queryOtaStatus()
|
|
1129
1130
|
this.armQueryReplyFallback("initial-mount")
|
|
1130
1131
|
}
|
|
1131
1132
|
}
|
|
@@ -1154,7 +1155,7 @@ class OtaInstallCoordinator {
|
|
|
1154
1155
|
this.clearProgressTimeout()
|
|
1155
1156
|
this.onFirstActivity()
|
|
1156
1157
|
this.onFirstNonZeroProgress()
|
|
1157
|
-
void BluetoothSdk.
|
|
1158
|
+
void BluetoothSdk.queryOtaStatus()
|
|
1158
1159
|
useGlassesStore.getState().setMtkUpdatedThisSession(true)
|
|
1159
1160
|
}
|
|
1160
1161
|
|
|
@@ -1345,7 +1346,7 @@ class OtaInstallCoordinator {
|
|
|
1345
1346
|
const s = useGlassesStore.getState().otaStatus
|
|
1346
1347
|
if (s?.stepType === "apk" && s.phase === "install" && s.status === "in_progress") {
|
|
1347
1348
|
this.apkInstallPollInFlight = true
|
|
1348
|
-
void BluetoothSdk.
|
|
1349
|
+
void BluetoothSdk.queryOtaStatus()
|
|
1349
1350
|
.catch(() => {})
|
|
1350
1351
|
.finally(() => {
|
|
1351
1352
|
this.apkInstallPollInFlight = false
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Started by `engine.start()`. Idempotent.
|
|
12
12
|
*/
|
|
13
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
14
|
-
import type {OtaStatus} from "@mentra/bluetooth-sdk/internal"
|
|
13
|
+
import BluetoothSdk, {type OtaStatus} from "@mentra/bluetooth-sdk"
|
|
15
14
|
import GlobalEventEmitter from "../utils/GlobalEventEmitter"
|
|
16
15
|
import {useGlassesStore} from "../stores/glasses"
|
|
17
16
|
import {handleOtaClockSkewFromGlasses} from "./glassesClockSync"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
2
|
-
import type {OtaUpdateInfo} from "@mentra/bluetooth-sdk"
|
|
1
|
+
import BluetoothSdk, {type OtaUpdateInfo} from "@mentra/bluetooth-sdk"
|
|
3
2
|
import {getGlassesSystemTimeMs, isGlassesConnected, useGlassesStore, waitForGlassesState} from "../stores/glasses"
|
|
4
3
|
import {maybeFixGlassesClockFromVersionInfo} from "./glassesClockSync"
|
|
5
4
|
import {hasConfiguredModernOtaManifestPin, resolveOtaManifestUrl} from "./otaManifestUrl"
|
|
@@ -406,9 +405,13 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
406
405
|
}
|
|
407
406
|
|
|
408
407
|
if (refreshVersionInfo) {
|
|
409
|
-
void BluetoothSdk.requestVersionInfo()
|
|
410
|
-
|
|
411
|
-
|
|
408
|
+
void BluetoothSdk.requestVersionInfo()
|
|
409
|
+
.then((versionInfo) => {
|
|
410
|
+
useGlassesStore.getState().setGlassesInfo(versionInfo)
|
|
411
|
+
})
|
|
412
|
+
.catch((error) => {
|
|
413
|
+
console.warn("OTA: Failed to request version_info from glasses:", error)
|
|
414
|
+
})
|
|
412
415
|
}
|
|
413
416
|
|
|
414
417
|
let buildNumber = useGlassesStore.getState().buildNumber
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as RNFS from "@dr.pogodin/react-native-fs"
|
|
2
|
-
import {
|
|
2
|
+
import {otaLocalNetwork, type OtaLocalNetworkDownloadProgress} from "@mentra/bluetooth-sdk/ota-transport"
|
|
3
3
|
import {Buffer} from "buffer"
|
|
4
4
|
import {Platform} from "react-native"
|
|
5
5
|
import WifiManager from "react-native-wifi-reborn"
|
|
@@ -17,7 +17,7 @@ export function shouldUseScopedLocalNetwork(os: string, moduleAvailable: boolean
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function supportsScopedConnection(): boolean {
|
|
20
|
-
return shouldUseScopedLocalNetwork(Platform.OS,
|
|
20
|
+
return shouldUseScopedLocalNetwork(Platform.OS, otaLocalNetwork.isAvailable())
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function normalizeHeaders(headers?: HeadersInit): Record<string, string> {
|
|
@@ -48,25 +48,25 @@ export const localNetworkTransport = {
|
|
|
48
48
|
await WifiManager.connectToProtectedSSID(ssid, password, false, false)
|
|
49
49
|
return undefined
|
|
50
50
|
}
|
|
51
|
-
const result = await
|
|
51
|
+
const result = await otaLocalNetwork.connect(ssid, password)
|
|
52
52
|
scopedConnectionActive = true
|
|
53
53
|
return result.localAddress
|
|
54
54
|
},
|
|
55
55
|
|
|
56
56
|
async disconnect(): Promise<void> {
|
|
57
57
|
if (supportsScopedConnection()) {
|
|
58
|
-
await
|
|
58
|
+
await otaLocalNetwork.disconnect().catch(() => {})
|
|
59
59
|
}
|
|
60
60
|
scopedConnectionActive = false
|
|
61
61
|
nativeJobs.clear()
|
|
62
62
|
},
|
|
63
63
|
|
|
64
64
|
async fetch(url: string | URL | Request, init?: RequestInit, timeoutMs = 30_000): Promise<Response> {
|
|
65
|
-
if (!scopedConnectionActive || !
|
|
65
|
+
if (!scopedConnectionActive || !otaLocalNetwork.isAvailable() || typeof url !== "string") {
|
|
66
66
|
return globalThis.fetch(url, init)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const nativeModule =
|
|
69
|
+
const nativeModule = otaLocalNetwork
|
|
70
70
|
const id = requestId("request")
|
|
71
71
|
const signal = init?.signal
|
|
72
72
|
const cancel = () => void nativeModule.cancel(id)
|
|
@@ -92,13 +92,13 @@ export const localNetworkTransport = {
|
|
|
92
92
|
},
|
|
93
93
|
|
|
94
94
|
downloadFile(options: DownloadOptions): DownloadHandle {
|
|
95
|
-
if (!scopedConnectionActive || !
|
|
95
|
+
if (!scopedConnectionActive || !otaLocalNetwork.isAvailable()) return RNFS.downloadFile(options)
|
|
96
96
|
|
|
97
97
|
const jobId = nextJobId++
|
|
98
98
|
const id = requestId("download")
|
|
99
99
|
let began = false
|
|
100
100
|
nativeJobs.set(jobId, id)
|
|
101
|
-
const subscription =
|
|
101
|
+
const subscription = otaLocalNetwork.onDownloadProgress((event: OtaLocalNetworkDownloadProgress) => {
|
|
102
102
|
if (event.requestId !== id) return
|
|
103
103
|
if (!began) {
|
|
104
104
|
began = true
|
|
@@ -116,14 +116,15 @@ export const localNetworkTransport = {
|
|
|
116
116
|
})
|
|
117
117
|
})
|
|
118
118
|
|
|
119
|
-
const promise =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
const promise = otaLocalNetwork
|
|
120
|
+
.download(
|
|
121
|
+
id,
|
|
122
|
+
options.fromUrl,
|
|
123
|
+
options.toFile,
|
|
124
|
+
options.headers || {},
|
|
125
|
+
options.connectionTimeout || 30_000,
|
|
126
|
+
options.readTimeout || 30_000,
|
|
127
|
+
)
|
|
127
128
|
.then((result) => {
|
|
128
129
|
if (!began) {
|
|
129
130
|
options.begin?.({
|
|
@@ -154,16 +155,16 @@ export const localNetworkTransport = {
|
|
|
154
155
|
|
|
155
156
|
stopDownload(jobId: number): void {
|
|
156
157
|
const nativeId = nativeJobs.get(jobId)
|
|
157
|
-
if (nativeId &&
|
|
158
|
+
if (nativeId && otaLocalNetwork.isAvailable()) {
|
|
158
159
|
cancelledNativeJobs.add(jobId)
|
|
159
|
-
void
|
|
160
|
+
void otaLocalNetwork.cancel(nativeId)
|
|
160
161
|
return
|
|
161
162
|
}
|
|
162
163
|
RNFS.stopDownload(jobId)
|
|
163
164
|
},
|
|
164
165
|
}
|
|
165
166
|
|
|
166
|
-
|
|
167
|
+
otaLocalNetwork.onNetworkLost(() => {
|
|
167
168
|
scopedConnectionActive = false
|
|
168
169
|
nativeJobs.clear()
|
|
169
170
|
})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Push phone time to glasses only when clock skew is detected (gallery sync, OTA, etc.).
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
5
|
+
import BluetoothSdk from "@mentra/bluetooth-sdk"
|
|
6
6
|
import {BgTimer} from "../utils/timers"
|
|
7
7
|
import {useGlassesStore} from "../stores/glasses"
|
|
8
8
|
|
package/src/stores/core.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {create} from "zustand"
|
|
2
2
|
import {subscribeWithSelector} from "zustand/middleware"
|
|
3
|
-
import type {
|
|
3
|
+
import type {PublicBluetoothStatus} from "@mentra/bluetooth-sdk"
|
|
4
4
|
|
|
5
|
-
export interface CoreState extends
|
|
6
|
-
setCoreInfo: (info: Partial<
|
|
5
|
+
export interface CoreState extends PublicBluetoothStatus {
|
|
6
|
+
setCoreInfo: (info: Partial<PublicBluetoothStatus>) => void
|
|
7
7
|
reset: () => void
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const initialState:
|
|
10
|
+
const initialState: PublicBluetoothStatus = {
|
|
11
11
|
// state:
|
|
12
12
|
searching: false,
|
|
13
13
|
searchingController: false,
|
package/src/stores/glasses.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
GlassesConnectionStatus,
|
|
3
|
-
GlassesStatus,
|
|
4
3
|
HotspotStatus,
|
|
5
4
|
OtaProgress,
|
|
6
5
|
OtaStatus,
|
|
7
6
|
OtaUpdateInfo,
|
|
7
|
+
PublicGlassesStatus,
|
|
8
8
|
WifiStatus,
|
|
9
|
-
} from "@mentra/bluetooth-sdk
|
|
9
|
+
} from "@mentra/bluetooth-sdk"
|
|
10
10
|
import {isGlassesConnected, isGlassesLinkLayerBusy, isGlassesReady} from "../services/GlassesReadiness"
|
|
11
11
|
import {create} from "zustand"
|
|
12
12
|
import {subscribeWithSelector} from "zustand/middleware"
|
|
@@ -20,7 +20,14 @@ export const selectGlassesConnected = (state: {connection: GlassesConnectionStat
|
|
|
20
20
|
|
|
21
21
|
export const selectGlassesReady = (state: {connection: GlassesConnectionStatus}) => isGlassesReady(state.connection)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
type EngineGlassesStatus = PublicGlassesStatus & {
|
|
24
|
+
otaUpdateAvailable: OtaUpdateInfo | null
|
|
25
|
+
otaProgress: OtaProgress | null
|
|
26
|
+
otaInProgress: boolean
|
|
27
|
+
otaVersionUrl: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface GlassesState extends EngineGlassesStatus {
|
|
24
31
|
systemTimeMs: number
|
|
25
32
|
wifiStatusKnown: boolean
|
|
26
33
|
setGlassesInfo: (info: GlassesInfoUpdate) => void
|
|
@@ -53,7 +60,7 @@ type LegacyHotspotFields = {
|
|
|
53
60
|
hotspotLocalIp?: string
|
|
54
61
|
}
|
|
55
62
|
|
|
56
|
-
type GlassesInfoUpdate = Partial<
|
|
63
|
+
type GlassesInfoUpdate = Partial<EngineGlassesStatus> & LegacyWifiFields & LegacyHotspotFields
|
|
57
64
|
|
|
58
65
|
function wifiFromLegacyFields(info: LegacyWifiFields): WifiStatus | null {
|
|
59
66
|
if (info.wifiConnected === true) {
|
|
@@ -80,7 +87,7 @@ function hotspotFromLegacyFields(info: LegacyHotspotFields): HotspotStatus | nul
|
|
|
80
87
|
return null
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
export const getGlasesInfoPartial = (state:
|
|
90
|
+
export const getGlasesInfoPartial = (state: EngineGlassesStatus) => {
|
|
84
91
|
const wifi = state.wifi
|
|
85
92
|
const connected = isGlassesConnected(state.connection)
|
|
86
93
|
return {
|
|
@@ -98,7 +105,7 @@ export const getGlasesInfoPartial = (state: GlassesStatus) => {
|
|
|
98
105
|
}
|
|
99
106
|
}
|
|
100
107
|
|
|
101
|
-
interface GlassesStore extends
|
|
108
|
+
interface GlassesStore extends EngineGlassesStatus {
|
|
102
109
|
systemTimeMs: number
|
|
103
110
|
mtkUpdatedThisSession: boolean
|
|
104
111
|
wifiStatusKnown: boolean
|