@glassly/engine 0.4.0-dev.1029 → 0.4.0-dev.1031
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/build/engine.d.ts.map +1 -1
- package/build/engine.js +5 -3
- package/build/engine.js.map +1 -1
- package/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +11 -8
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/SupportProfileSync.d.ts.map +1 -1
- package/build/services/SupportProfileSync.js +3 -0
- package/build/services/SupportProfileSync.js.map +1 -1
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +3 -1
- package/build/stores/settings.js.map +1 -1
- package/package.json +7 -7
- package/src/engine.ts +8 -6
- package/src/generated/releaseMetadata.ts +3 -3
- package/src/services/CloudClientService.ts +10 -5
- package/src/services/SupportProfileSync.ts +2 -0
- package/src/stores/settings.ts +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupportProfileSync.js","sourceRoot":"","sources":["../../src/services/SupportProfileSync.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from \"expo-constants\"\nimport * as Device from \"expo-device\"\nimport {Platform} from \"react-native\"\nimport type {SupportStateInput} from \"@glassly/cloud-client\"\n\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport {cloudClientService} from \"./CloudClientService\"\n\nconst ENGINE_VERSION = (require(\"../../package.json\") as {version?: string}).version\nconst BLUETOOTH_SDK_VERSION = (require(\"@glassly/bluetooth-sdk/package.json\") as {version?: string}).version\nconst DEBOUNCE_MS = 2_000\nconst RETRY_MS = 30_000\nconst HEARTBEAT_MS = 6 * 60 * 60_000\n\nlet unsubscribe: (() => void) | null = null\nlet debounceTimer: number | null = null\nlet retryTimer: number | null = null\nlet heartbeatTimer: number | null = null\nlet lastSentFingerprint: string | null = null\nlet queuedFingerprint: string | null = null\nlet sendingGeneration: number | null = null\nlet syncGeneration = 0\nlet consecutiveSendFailures = 0\nlet lastFailure: {code: string; stage: string} | null = null\nlet lastConnectionState: string | null = null\n\n/**\n * Keep Cloud's canonical support snapshot current without creating an event\n * stream from noisy store updates. Only the explicitly selected fields below\n * leave the phone; Wi-Fi, Bluetooth addresses, location and diagnostics do not.\n */\nexport function startSupportProfileSync(): void {\n if (unsubscribe) return\n const generation = ++syncGeneration\n lastConnectionState = useGlassesStore.getState().connection.state\n unsubscribe = useGlassesStore.subscribe(() => handleGlassesStoreChange(generation))\n heartbeatTimer = BgTimer.setInterval(() => void sendCurrentSnapshot(true, generation), HEARTBEAT_MS)\n void sendCurrentSnapshot(true, generation)\n}\n\nexport function stopSupportProfileSync(): void {\n syncGeneration += 1\n unsubscribe?.()\n unsubscribe = null\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n if (heartbeatTimer !== null) BgTimer.clearInterval(heartbeatTimer)\n debounceTimer = null\n retryTimer = null\n heartbeatTimer = null\n lastSentFingerprint = null\n queuedFingerprint = null\n sendingGeneration = null\n consecutiveSendFailures = 0\n lastFailure = null\n lastConnectionState = null\n}\n\nfunction handleGlassesStoreChange(generation: number): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const connectionState = useGlassesStore.getState().connection.state\n if (connectionState === \"connected\" && lastConnectionState !== \"connected\") lastFailure = null\n lastConnectionState = connectionState\n scheduleMeaningfulUpdate(generation)\n}\n\nfunction scheduleMeaningfulUpdate(generation = syncGeneration): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint === lastSentFingerprint) return\n queuedFingerprint = fingerprint\n armDebounce(generation)\n}\n\nfunction armDebounce(generation: number): void {\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n debounceTimer = BgTimer.setTimeout(() => {\n debounceTimer = null\n void sendCurrentSnapshot(false, generation)\n }, DEBOUNCE_MS)\n}\n\nasync function sendCurrentSnapshot(force: boolean, generation = syncGeneration): Promise<void> {\n if (!unsubscribe || generation !== syncGeneration) return\n if (sendingGeneration === generation) {\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint !== lastSentFingerprint) queuedFingerprint = fingerprint\n return\n }\n const snapshot = buildSnapshot()\n const fingerprint = snapshotFingerprint(snapshot)\n if (!force && fingerprint === lastSentFingerprint) return\n\n sendingGeneration = generation\n let retryDelayMs: number | null = null\n try {\n const result = await cloudClientService.core.supportProfile.update(snapshot)\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures = 0\n retryDelayMs = retryDelayForSupportProfileResult(result)\n if (retryDelayMs === null) {\n lastSentFingerprint = fingerprint\n if (queuedFingerprint === fingerprint) queuedFingerprint = null\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = null\n }\n } catch (error) {\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures += 1\n retryDelayMs = retryDelayForSendFailure(consecutiveSendFailures)\n console.warn(\n `supportProfile: Cloud update failed (retry in ${Math.round(retryDelayMs / 1_000)}s):`,\n error instanceof Error ? error.message : error,\n )\n } finally {\n const generationIsActive = generation === syncGeneration && sendingGeneration === generation && Boolean(unsubscribe)\n if (generationIsActive) {\n sendingGeneration = null\n if (retryDelayMs !== null) {\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = BgTimer.setTimeout(() => {\n retryTimer = null\n void sendCurrentSnapshot(true, generation)\n }, retryDelayMs)\n } else {\n const currentFingerprint = snapshotFingerprint(buildSnapshot())\n if (currentFingerprint !== lastSentFingerprint) {\n queuedFingerprint = currentFingerprint\n if (retryTimer === null) armDebounce(generation)\n }\n }\n }\n }\n}\n\nexport function retryDelayForSupportProfileResult(result: {\n status: \"accepted\" | \"deduplicated\" | \"stale\"\n}): number | null {\n if (result.status === \"accepted\" || result.status === \"deduplicated\") return null\n return RETRY_MS\n}\n\n/**\n * Support freshness is not worth an aggressive retry loop. A snapshot the\n * server keeps rejecting (skewed clock, deleted account, signed-out host)\n * backs off exponentially until it converges on the heartbeat cadence.\n */\nexport function retryDelayForSendFailure(consecutiveFailures: number): number {\n return Math.min(HEARTBEAT_MS, RETRY_MS * 2 ** Math.min(Math.max(consecutiveFailures, 1) - 1, 10))\n}\n\nexport function buildSnapshot(observedAt = new Date()): SupportStateInput {\n const glasses = useGlassesStore.getState()\n const device = {\n hardwareId: optional(glasses.serialNumber),\n model: optional(glasses.deviceModel),\n androidVersion: optional(glasses.androidVersion),\n firmwareVersion: optional(glasses.firmwareVersion),\n mtkFirmwareVersion: optional(glasses.mtkFirmwareVersion),\n besFirmwareVersion: optional(glasses.besFirmwareVersion),\n appVersion: optional(glasses.appVersion),\n buildNumber: optional(glasses.buildNumber),\n }\n const hasDevice = Object.values(device).some(Boolean)\n const constants = Constants as typeof Constants & {\n nativeAppVersion?: string | null\n nativeBuildVersion?: string | null\n }\n return {\n observedAt: observedAt.toISOString(),\n host: {\n appVersion: optional(constants.nativeAppVersion ?? Constants.expoConfig?.version),\n appBuild: optional(constants.nativeBuildVersion),\n engineVersion: optional(ENGINE_VERSION),\n bluetoothSdkVersion: optional(BLUETOOTH_SDK_VERSION),\n phonePlatform: Platform.OS === \"ios\" || Platform.OS === \"android\" ? Platform.OS : \"unknown\",\n phoneModel: optional(Device.modelName),\n phoneOsVersion: optional(\n Platform.OS === \"android\"\n ? String((Platform.constants as {Release?: string} | undefined)?.Release ?? Platform.Version)\n : String(Platform.Version),\n ),\n connectionState: glasses.connection.state,\n ...(lastFailure ? {failureCode: lastFailure.code, failureStage: lastFailure.stage} : {}),\n },\n ...(hasDevice ? {device} : {}),\n }\n}\n\n/** Record only normalized connection failures; arbitrary exception messages never leave the phone. */\nexport function recordSupportProfileConnectionFailure(error: unknown, stage: string): void {\n const rawCode =\n typeof error === \"object\" && error && \"code\" in error ? String((error as {code?: unknown}).code ?? \"\") : \"\"\n const message = error instanceof Error ? `${error.name} ${error.message}`.toLowerCase() : \"\"\n const code = /^[a-zA-Z0-9_.-]{1,64}$/.test(rawCode)\n ? rawCode.toLowerCase()\n : message.includes(\"permission\")\n ? \"permission_denied\"\n : message.includes(\"bluetooth\") && (message.includes(\"off\") || message.includes(\"unavailable\"))\n ? \"bluetooth_unavailable\"\n : message.includes(\"not found\") || message.includes(\"no default\")\n ? \"device_not_found\"\n : message.includes(\"timeout\")\n ? \"connect_timeout\"\n : \"connect_failed\"\n lastFailure = {code, stage: stage.replace(/[^a-zA-Z0-9_.-]/g, \"_\").slice(0, 64)}\n scheduleMeaningfulUpdate()\n}\n\nexport function snapshotFingerprint(snapshot: SupportStateInput): string {\n return JSON.stringify({host: snapshot.host, device: snapshot.device})\n}\n\nfunction optional(value: string | null | undefined): string | undefined {\n const trimmed = value?.trim()\n return trimmed ? trimmed.slice(0, 128) : undefined\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SupportProfileSync.js","sourceRoot":"","sources":["../../src/services/SupportProfileSync.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from \"expo-constants\"\nimport * as Device from \"expo-device\"\nimport {Platform} from \"react-native\"\nimport type {SupportStateInput} from \"@glassly/cloud-client\"\n\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport {cloudClientService} from \"./CloudClientService\"\n\nconst ENGINE_VERSION = (require(\"../../package.json\") as {version?: string}).version\nconst BLUETOOTH_SDK_VERSION = (require(\"@glassly/bluetooth-sdk/package.json\") as {version?: string}).version\nconst DEBOUNCE_MS = 2_000\nconst RETRY_MS = 30_000\nconst HEARTBEAT_MS = 6 * 60 * 60_000\n\nlet unsubscribe: (() => void) | null = null\nlet debounceTimer: number | null = null\nlet retryTimer: number | null = null\nlet heartbeatTimer: number | null = null\nlet lastSentFingerprint: string | null = null\nlet queuedFingerprint: string | null = null\nlet sendingGeneration: number | null = null\nlet syncGeneration = 0\nlet consecutiveSendFailures = 0\nlet lastFailure: {code: string; stage: string} | null = null\nlet lastConnectionState: string | null = null\n\n/**\n * Keep Cloud's canonical support snapshot current without creating an event\n * stream from noisy store updates. Only the explicitly selected fields below\n * leave the phone; Wi-Fi, Bluetooth addresses, location and diagnostics do not.\n */\nexport function startSupportProfileSync(): void {\n if (unsubscribe) return\n const generation = ++syncGeneration\n lastConnectionState = useGlassesStore.getState().connection.state\n unsubscribe = useGlassesStore.subscribe(() => handleGlassesStoreChange(generation))\n heartbeatTimer = BgTimer.setInterval(() => void sendCurrentSnapshot(true, generation), HEARTBEAT_MS)\n void sendCurrentSnapshot(true, generation)\n}\n\nexport function stopSupportProfileSync(): void {\n syncGeneration += 1\n unsubscribe?.()\n unsubscribe = null\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n if (heartbeatTimer !== null) BgTimer.clearInterval(heartbeatTimer)\n debounceTimer = null\n retryTimer = null\n heartbeatTimer = null\n lastSentFingerprint = null\n queuedFingerprint = null\n sendingGeneration = null\n consecutiveSendFailures = 0\n lastFailure = null\n lastConnectionState = null\n}\n\nfunction handleGlassesStoreChange(generation: number): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const connectionState = useGlassesStore.getState().connection.state\n if (connectionState === \"connected\" && lastConnectionState !== \"connected\") lastFailure = null\n lastConnectionState = connectionState\n scheduleMeaningfulUpdate(generation)\n}\n\nfunction scheduleMeaningfulUpdate(generation = syncGeneration): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint === lastSentFingerprint) return\n queuedFingerprint = fingerprint\n armDebounce(generation)\n}\n\nfunction armDebounce(generation: number): void {\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n debounceTimer = BgTimer.setTimeout(() => {\n debounceTimer = null\n void sendCurrentSnapshot(false, generation)\n }, DEBOUNCE_MS)\n}\n\nasync function sendCurrentSnapshot(force: boolean, generation = syncGeneration): Promise<void> {\n if (!unsubscribe || generation !== syncGeneration) return\n // Every send would fail into the retry backoff with no client to send through.\n if (cloudClientService.isCloudDisabled()) return\n if (sendingGeneration === generation) {\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint !== lastSentFingerprint) queuedFingerprint = fingerprint\n return\n }\n const snapshot = buildSnapshot()\n const fingerprint = snapshotFingerprint(snapshot)\n if (!force && fingerprint === lastSentFingerprint) return\n\n sendingGeneration = generation\n let retryDelayMs: number | null = null\n try {\n const result = await cloudClientService.core.supportProfile.update(snapshot)\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures = 0\n retryDelayMs = retryDelayForSupportProfileResult(result)\n if (retryDelayMs === null) {\n lastSentFingerprint = fingerprint\n if (queuedFingerprint === fingerprint) queuedFingerprint = null\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = null\n }\n } catch (error) {\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures += 1\n retryDelayMs = retryDelayForSendFailure(consecutiveSendFailures)\n console.warn(\n `supportProfile: Cloud update failed (retry in ${Math.round(retryDelayMs / 1_000)}s):`,\n error instanceof Error ? error.message : error,\n )\n } finally {\n const generationIsActive = generation === syncGeneration && sendingGeneration === generation && Boolean(unsubscribe)\n if (generationIsActive) {\n sendingGeneration = null\n if (retryDelayMs !== null) {\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = BgTimer.setTimeout(() => {\n retryTimer = null\n void sendCurrentSnapshot(true, generation)\n }, retryDelayMs)\n } else {\n const currentFingerprint = snapshotFingerprint(buildSnapshot())\n if (currentFingerprint !== lastSentFingerprint) {\n queuedFingerprint = currentFingerprint\n if (retryTimer === null) armDebounce(generation)\n }\n }\n }\n }\n}\n\nexport function retryDelayForSupportProfileResult(result: {\n status: \"accepted\" | \"deduplicated\" | \"stale\"\n}): number | null {\n if (result.status === \"accepted\" || result.status === \"deduplicated\") return null\n return RETRY_MS\n}\n\n/**\n * Support freshness is not worth an aggressive retry loop. A snapshot the\n * server keeps rejecting (skewed clock, deleted account, signed-out host)\n * backs off exponentially until it converges on the heartbeat cadence.\n */\nexport function retryDelayForSendFailure(consecutiveFailures: number): number {\n return Math.min(HEARTBEAT_MS, RETRY_MS * 2 ** Math.min(Math.max(consecutiveFailures, 1) - 1, 10))\n}\n\nexport function buildSnapshot(observedAt = new Date()): SupportStateInput {\n const glasses = useGlassesStore.getState()\n const device = {\n hardwareId: optional(glasses.serialNumber),\n model: optional(glasses.deviceModel),\n androidVersion: optional(glasses.androidVersion),\n firmwareVersion: optional(glasses.firmwareVersion),\n mtkFirmwareVersion: optional(glasses.mtkFirmwareVersion),\n besFirmwareVersion: optional(glasses.besFirmwareVersion),\n appVersion: optional(glasses.appVersion),\n buildNumber: optional(glasses.buildNumber),\n }\n const hasDevice = Object.values(device).some(Boolean)\n const constants = Constants as typeof Constants & {\n nativeAppVersion?: string | null\n nativeBuildVersion?: string | null\n }\n return {\n observedAt: observedAt.toISOString(),\n host: {\n appVersion: optional(constants.nativeAppVersion ?? Constants.expoConfig?.version),\n appBuild: optional(constants.nativeBuildVersion),\n engineVersion: optional(ENGINE_VERSION),\n bluetoothSdkVersion: optional(BLUETOOTH_SDK_VERSION),\n phonePlatform: Platform.OS === \"ios\" || Platform.OS === \"android\" ? Platform.OS : \"unknown\",\n phoneModel: optional(Device.modelName),\n phoneOsVersion: optional(\n Platform.OS === \"android\"\n ? String((Platform.constants as {Release?: string} | undefined)?.Release ?? Platform.Version)\n : String(Platform.Version),\n ),\n connectionState: glasses.connection.state,\n ...(lastFailure ? {failureCode: lastFailure.code, failureStage: lastFailure.stage} : {}),\n },\n ...(hasDevice ? {device} : {}),\n }\n}\n\n/** Record only normalized connection failures; arbitrary exception messages never leave the phone. */\nexport function recordSupportProfileConnectionFailure(error: unknown, stage: string): void {\n const rawCode =\n typeof error === \"object\" && error && \"code\" in error ? String((error as {code?: unknown}).code ?? \"\") : \"\"\n const message = error instanceof Error ? `${error.name} ${error.message}`.toLowerCase() : \"\"\n const code = /^[a-zA-Z0-9_.-]{1,64}$/.test(rawCode)\n ? rawCode.toLowerCase()\n : message.includes(\"permission\")\n ? \"permission_denied\"\n : message.includes(\"bluetooth\") && (message.includes(\"off\") || message.includes(\"unavailable\"))\n ? \"bluetooth_unavailable\"\n : message.includes(\"not found\") || message.includes(\"no default\")\n ? \"device_not_found\"\n : message.includes(\"timeout\")\n ? \"connect_timeout\"\n : \"connect_failed\"\n lastFailure = {code, stage: stage.replace(/[^a-zA-Z0-9_.-]/g, \"_\").slice(0, 64)}\n scheduleMeaningfulUpdate()\n}\n\nexport function snapshotFingerprint(snapshot: SupportStateInput): string {\n return JSON.stringify({host: snapshot.host, device: snapshot.device})\n}\n\nfunction optional(value: string | null | undefined): string | undefined {\n const trimmed = value?.trim()\n return trimmed ? trimmed.slice(0, 128) : undefined\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/stores/settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAwB,MAAM,aAAa,CAAA;AAS9D,OAAO,EAAC,wBAAwB,EAAE,gCAAgC,EAAC,MAAM,wBAAwB,CAAA;AAEjG,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,GAAG,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,OAAO,CAAA;IAGrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IAEjC,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAA;IAEpB,OAAO,EAAE,OAAO,CAAA;IAQhB,mBAAmB,CAAC,EAAE,IAAI,CAAA;IAC1B;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,EAAE,IAAI,CAAA;CAC7B;AAKD,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/stores/settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAwB,MAAM,aAAa,CAAA;AAS9D,OAAO,EAAC,wBAAwB,EAAE,gCAAgC,EAAC,MAAM,wBAAwB,CAAA;AAEjG,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,GAAG,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,OAAO,CAAA;IAGrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IAEjC,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAA;IAEpB,OAAO,EAAE,OAAO,CAAA;IAQhB,mBAAmB,CAAC,EAAE,IAAI,CAAA;IAC1B;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,EAAE,IAAI,CAAA;CAC7B;AAKD,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAkqCnC,CAAA;AAEV,eAAO,MAAM,eAAe,EAAE,MAAM,EAAuD,CAAA;AAI3F,eAAO,MAAM,sBAAsB,EAAE,MAAM,EA6D1C,CAAA;AAeD,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAEV,CAAA;AAIhC,MAAM,WAAW,aAAa;IAE5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE7B,aAAa,EAAE,OAAO,CAAA;IAEtB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,OAAO,KAAK,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACzF,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC3E,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,CAAA;IAEhC,eAAe,EAAE,MAAM,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAE/C,oBAAoB,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC/C,uBAAuB,EAAE,MAAM,IAAI,CAAA;CACpC;AAuBD,eAAO,MAAM,gBAAgB;;;;;;;;EAsX5B,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,GAAG,GAAG,EAAE,KAAK,MAAM,KAAG,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAI3F,CAAA"}
|
package/build/stores/settings.js
CHANGED
|
@@ -718,12 +718,14 @@ export const SETTINGS = {
|
|
|
718
718
|
saveOnServer: true,
|
|
719
719
|
persist: true,
|
|
720
720
|
},
|
|
721
|
+
// Session-only: Position settings holds it on for stock G1, and a persisted
|
|
722
|
+
// true (app killed on that screen) blanks every glasses' display at boot.
|
|
721
723
|
screen_disabled: {
|
|
722
724
|
key: "screen_disabled",
|
|
723
725
|
defaultValue: () => false,
|
|
724
726
|
writable: true,
|
|
725
727
|
saveOnServer: false,
|
|
726
|
-
persist:
|
|
728
|
+
persist: false,
|
|
727
729
|
},
|
|
728
730
|
// glasses settings:
|
|
729
731
|
contextual_dashboard: {
|