@glassly/engine 0.1.0-dev.98 → 0.2.8-dev.445

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.
Files changed (501) hide show
  1. package/README.md +28 -0
  2. package/build/engine.d.ts +32 -10
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +24 -16
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +9 -0
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +9 -0
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/display.d.ts +10 -3
  11. package/build/facades/display.d.ts.map +1 -1
  12. package/build/facades/display.js +22 -8
  13. package/build/facades/display.js.map +1 -1
  14. package/build/facades/displayMirror.d.ts +11 -0
  15. package/build/facades/displayMirror.d.ts.map +1 -1
  16. package/build/facades/displayMirror.js +22 -0
  17. package/build/facades/displayMirror.js.map +1 -1
  18. package/build/facades/glasses.d.ts +31 -1
  19. package/build/facades/glasses.d.ts.map +1 -1
  20. package/build/facades/glasses.js +51 -0
  21. package/build/facades/glasses.js.map +1 -1
  22. package/build/facades/memory.d.ts +0 -6
  23. package/build/facades/memory.d.ts.map +1 -1
  24. package/build/facades/memory.js +1 -9
  25. package/build/facades/memory.js.map +1 -1
  26. package/build/facades/miniapps.d.ts +3 -1
  27. package/build/facades/miniapps.d.ts.map +1 -1
  28. package/build/facades/miniapps.js +3 -1
  29. package/build/facades/miniapps.js.map +1 -1
  30. package/build/facades/pairing.d.ts.map +1 -1
  31. package/build/facades/pairing.js +5 -4
  32. package/build/facades/pairing.js.map +1 -1
  33. package/build/facades/permissions.d.ts +2 -0
  34. package/build/facades/permissions.d.ts.map +1 -1
  35. package/build/facades/permissions.js +48 -0
  36. package/build/facades/permissions.js.map +1 -1
  37. package/build/facades/phoneNotifications.d.ts +20 -9
  38. package/build/facades/phoneNotifications.d.ts.map +1 -1
  39. package/build/facades/phoneNotifications.js +33 -26
  40. package/build/facades/phoneNotifications.js.map +1 -1
  41. package/build/facades/settings.d.ts.map +1 -1
  42. package/build/facades/settings.js +1 -2
  43. package/build/facades/settings.js.map +1 -1
  44. package/build/generated/releaseMetadata.js +4 -4
  45. package/build/generated/releaseMetadata.js.map +1 -1
  46. package/build/index.d.ts +6 -4
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +5 -4
  49. package/build/index.js.map +1 -1
  50. package/build/react/MentraLiveOtaFlow.js +2 -2
  51. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  52. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  53. package/build/react/useMentraLiveOta.js +8 -7
  54. package/build/react/useMentraLiveOta.js.map +1 -1
  55. package/build/runtime/config.d.ts +1 -1
  56. package/build/runtime/config.d.ts.map +1 -1
  57. package/build/runtime/config.js.map +1 -1
  58. package/build/services/AppRegistry.d.ts +4 -1
  59. package/build/services/AppRegistry.d.ts.map +1 -1
  60. package/build/services/AppRegistry.js +21 -1
  61. package/build/services/AppRegistry.js.map +1 -1
  62. package/build/services/BlobStore.d.ts +2 -2
  63. package/build/services/BlobStore.js +3 -3
  64. package/build/services/BlobStore.js.map +1 -1
  65. package/build/services/CloudClientService.d.ts +7 -3
  66. package/build/services/CloudClientService.d.ts.map +1 -1
  67. package/build/services/CloudClientService.js +34 -9
  68. package/build/services/CloudClientService.js.map +1 -1
  69. package/build/services/DevServerBridge.d.ts +1 -18
  70. package/build/services/DevServerBridge.d.ts.map +1 -1
  71. package/build/services/DevServerBridge.js +9 -8
  72. package/build/services/DevServerBridge.js.map +1 -1
  73. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  74. package/build/services/DeviceEventRouter.js +58 -71
  75. package/build/services/DeviceEventRouter.js.map +1 -1
  76. package/build/services/DisplayDiagnostics.d.ts +5 -0
  77. package/build/services/DisplayDiagnostics.d.ts.map +1 -0
  78. package/build/services/DisplayDiagnostics.js +105 -0
  79. package/build/services/DisplayDiagnostics.js.map +1 -0
  80. package/build/services/DisplayProcessor.d.ts +6 -7
  81. package/build/services/DisplayProcessor.d.ts.map +1 -1
  82. package/build/services/DisplayProcessor.js +17 -45
  83. package/build/services/DisplayProcessor.js.map +1 -1
  84. package/build/services/GestureDotsService.d.ts +10 -4
  85. package/build/services/GestureDotsService.d.ts.map +1 -1
  86. package/build/services/GestureDotsService.js +70 -16
  87. package/build/services/GestureDotsService.js.map +1 -1
  88. package/build/services/GlassesKeyboardInput.d.ts +77 -0
  89. package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
  90. package/build/services/GlassesKeyboardInput.js +261 -0
  91. package/build/services/GlassesKeyboardInput.js.map +1 -0
  92. package/build/services/GlassesSensorService.d.ts +47 -0
  93. package/build/services/GlassesSensorService.d.ts.map +1 -0
  94. package/build/services/GlassesSensorService.js +242 -0
  95. package/build/services/GlassesSensorService.js.map +1 -0
  96. package/build/services/GlassesTouchInput.d.ts +14 -0
  97. package/build/services/GlassesTouchInput.d.ts.map +1 -0
  98. package/build/services/GlassesTouchInput.js +107 -0
  99. package/build/services/GlassesTouchInput.js.map +1 -0
  100. package/build/services/HeadingService.d.ts +0 -6
  101. package/build/services/HeadingService.d.ts.map +1 -1
  102. package/build/services/HeadingService.js +0 -27
  103. package/build/services/HeadingService.js.map +1 -1
  104. package/build/services/HotspotShutdown.d.ts.map +1 -1
  105. package/build/services/HotspotShutdown.js +2 -1
  106. package/build/services/HotspotShutdown.js.map +1 -1
  107. package/build/services/JSCrashloopReportService.js +2 -2
  108. package/build/services/JSCrashloopReportService.js.map +1 -1
  109. package/build/services/JSRouter.d.ts +6 -4
  110. package/build/services/JSRouter.d.ts.map +1 -1
  111. package/build/services/JSRouter.js +15 -13
  112. package/build/services/JSRouter.js.map +1 -1
  113. package/build/services/LocalDisplayManager.d.ts +35 -7
  114. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  115. package/build/services/LocalDisplayManager.js +105 -27
  116. package/build/services/LocalDisplayManager.js.map +1 -1
  117. package/build/services/LocalMiniappDataMigration.d.ts +1 -1
  118. package/build/services/LocalMiniappDataMigration.js +1 -1
  119. package/build/services/LocalMiniappDataMigration.js.map +1 -1
  120. package/build/services/LocalMiniappRuntime.d.ts +64 -11
  121. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  122. package/build/services/LocalMiniappRuntime.js +441 -35
  123. package/build/services/LocalMiniappRuntime.js.map +1 -1
  124. package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
  125. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  126. package/build/services/LocalSttFallbackCoordinator.js +27 -8
  127. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  128. package/build/services/MemoryStore.d.ts +8 -33
  129. package/build/services/MemoryStore.d.ts.map +1 -1
  130. package/build/services/MemoryStore.js +30 -56
  131. package/build/services/MemoryStore.js.map +1 -1
  132. package/build/services/MiniappEngine.d.ts +3 -3
  133. package/build/services/MiniappEngine.js +7 -7
  134. package/build/services/MiniappEngine.js.map +1 -1
  135. package/build/services/MiniappLauncher.d.ts +8 -0
  136. package/build/services/MiniappLauncher.d.ts.map +1 -1
  137. package/build/services/MiniappLauncher.js +19 -1
  138. package/build/services/MiniappLauncher.js.map +1 -1
  139. package/build/services/MirrorService.d.ts +24 -0
  140. package/build/services/MirrorService.d.ts.map +1 -0
  141. package/build/services/MirrorService.js +132 -0
  142. package/build/services/MirrorService.js.map +1 -0
  143. package/build/services/NativeNavigationService.d.ts +2 -3
  144. package/build/services/NativeNavigationService.d.ts.map +1 -1
  145. package/build/services/NativeNavigationService.js +24 -21
  146. package/build/services/NativeNavigationService.js.map +1 -1
  147. package/build/services/NavigationHandlers.d.ts.map +1 -1
  148. package/build/services/NavigationHandlers.js +10 -5
  149. package/build/services/NavigationHandlers.js.map +1 -1
  150. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  151. package/build/services/OtaInstallCoordinator.js +24 -23
  152. package/build/services/OtaInstallCoordinator.js.map +1 -1
  153. package/build/services/PairedGlassesLatch.d.ts +7 -0
  154. package/build/services/PairedGlassesLatch.d.ts.map +1 -0
  155. package/build/services/PairedGlassesLatch.js +38 -0
  156. package/build/services/PairedGlassesLatch.js.map +1 -0
  157. package/build/services/PhoneActivity.d.ts +23 -0
  158. package/build/services/PhoneActivity.d.ts.map +1 -0
  159. package/build/services/PhoneActivity.js +111 -0
  160. package/build/services/PhoneActivity.js.map +1 -0
  161. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  162. package/build/services/PhoneCameraFovCoordinator.js +4 -3
  163. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  164. package/build/services/PhoneNotificationsSync.d.ts +40 -6
  165. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  166. package/build/services/PhoneNotificationsSync.js +160 -84
  167. package/build/services/PhoneNotificationsSync.js.map +1 -1
  168. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  169. package/build/services/PhonePhotoCoordinator.js +6 -5
  170. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  171. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  172. package/build/services/PhoneStreamCoordinator.js +8 -7
  173. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  174. package/build/services/STTModelManager.d.ts +3 -0
  175. package/build/services/STTModelManager.d.ts.map +1 -1
  176. package/build/services/STTModelManager.js +15 -1
  177. package/build/services/STTModelManager.js.map +1 -1
  178. package/build/services/SceneRenderer.d.ts +43 -2
  179. package/build/services/SceneRenderer.d.ts.map +1 -1
  180. package/build/services/SceneRenderer.js +123 -8
  181. package/build/services/SceneRenderer.js.map +1 -1
  182. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  183. package/build/services/StreamLifecycleController.js +6 -14
  184. package/build/services/StreamLifecycleController.js.map +1 -1
  185. package/build/services/TTSModelManager.js +1 -1
  186. package/build/services/TTSModelManager.js.map +1 -1
  187. package/build/services/UIRouter.d.ts +2 -2
  188. package/build/services/UIRouter.js +5 -5
  189. package/build/services/UIRouter.js.map +1 -1
  190. package/build/services/asg/galleryPathMigration.js +1 -1
  191. package/build/services/asg/galleryPathMigration.js.map +1 -1
  192. package/build/services/asg/gallerySyncService.js +2 -2
  193. package/build/services/asg/gallerySyncService.js.map +1 -1
  194. package/build/services/asg/localStorageService.d.ts.map +1 -1
  195. package/build/services/asg/localStorageService.js +3 -3
  196. package/build/services/asg/localStorageService.js.map +1 -1
  197. package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
  198. package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
  199. package/build/services/debug/DashboardOpenTrace.js +128 -0
  200. package/build/services/debug/DashboardOpenTrace.js.map +1 -0
  201. package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
  202. package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
  203. package/build/services/debug/dashboardOpenTimeline.js +195 -0
  204. package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
  205. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  206. package/build/services/effectiveCapabilities.js +25 -13
  207. package/build/services/effectiveCapabilities.js.map +1 -1
  208. package/build/services/gestureClaims.d.ts +34 -15
  209. package/build/services/gestureClaims.d.ts.map +1 -1
  210. package/build/services/gestureClaims.js +42 -21
  211. package/build/services/gestureClaims.js.map +1 -1
  212. package/build/services/manifestFields.d.ts +9 -0
  213. package/build/services/manifestFields.d.ts.map +1 -0
  214. package/build/services/manifestFields.js +26 -0
  215. package/build/services/manifestFields.js.map +1 -0
  216. package/build/services/memoryStoreInstance.d.ts +0 -10
  217. package/build/services/memoryStoreInstance.d.ts.map +1 -1
  218. package/build/services/memoryStoreInstance.js +2 -31
  219. package/build/services/memoryStoreInstance.js.map +1 -1
  220. package/build/services/mirrorSnapshot.d.ts +16 -0
  221. package/build/services/mirrorSnapshot.d.ts.map +1 -0
  222. package/build/services/mirrorSnapshot.js +102 -0
  223. package/build/services/mirrorSnapshot.js.map +1 -0
  224. package/build/services/nativeNavigationGate.d.ts +8 -0
  225. package/build/services/nativeNavigationGate.d.ts.map +1 -0
  226. package/build/services/nativeNavigationGate.js +12 -0
  227. package/build/services/nativeNavigationGate.js.map +1 -0
  228. package/build/services/notificationAppCatalog.d.ts +7 -0
  229. package/build/services/notificationAppCatalog.d.ts.map +1 -0
  230. package/build/services/notificationAppCatalog.js +16 -0
  231. package/build/services/notificationAppCatalog.js.map +1 -0
  232. package/build/services/notifications/notificationPolicy.d.ts +55 -0
  233. package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
  234. package/build/services/notifications/notificationPolicy.js +41 -0
  235. package/build/services/notifications/notificationPolicy.js.map +1 -0
  236. package/build/services/pages/OverlayPages.d.ts +26 -0
  237. package/build/services/pages/OverlayPages.d.ts.map +1 -0
  238. package/build/services/pages/OverlayPages.js +80 -0
  239. package/build/services/pages/OverlayPages.js.map +1 -0
  240. package/build/services/pages/PageHost.d.ts +32 -0
  241. package/build/services/pages/PageHost.d.ts.map +1 -0
  242. package/build/services/pages/PageHost.js +99 -0
  243. package/build/services/pages/PageHost.js.map +1 -0
  244. package/build/services/pages/overlayApps.d.ts +25 -0
  245. package/build/services/pages/overlayApps.d.ts.map +1 -0
  246. package/build/services/pages/overlayApps.js +66 -0
  247. package/build/services/pages/overlayApps.js.map +1 -0
  248. package/build/services/pages/pageEligibility.d.ts +9 -0
  249. package/build/services/pages/pageEligibility.d.ts.map +1 -0
  250. package/build/services/pages/pageEligibility.js +27 -0
  251. package/build/services/pages/pageEligibility.js.map +1 -0
  252. package/build/services/settingsBridge.d.ts +58 -0
  253. package/build/services/settingsBridge.d.ts.map +1 -0
  254. package/build/services/settingsBridge.js +90 -0
  255. package/build/services/settingsBridge.js.map +1 -0
  256. package/build/services/speakerProfileStoreInstance.js +1 -1
  257. package/build/services/speakerProfileStoreInstance.js.map +1 -1
  258. package/build/services/uiShim.d.ts +1 -1
  259. package/build/services/uiShim.js +4 -4
  260. package/build/services/uiShim.js.map +1 -1
  261. package/build/stores/appVisibility.d.ts +28 -0
  262. package/build/stores/appVisibility.d.ts.map +1 -1
  263. package/build/stores/appVisibility.js +34 -0
  264. package/build/stores/appVisibility.js.map +1 -1
  265. package/build/stores/apps.d.ts +13 -0
  266. package/build/stores/apps.d.ts.map +1 -1
  267. package/build/stores/apps.js +66 -12
  268. package/build/stores/apps.js.map +1 -1
  269. package/build/stores/bluetoothSettingKeys.js +1 -1
  270. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  271. package/build/stores/display.d.ts +3 -3
  272. package/build/stores/display.d.ts.map +1 -1
  273. package/build/stores/display.js +16 -4
  274. package/build/stores/display.js.map +1 -1
  275. package/build/stores/glasses.d.ts.map +1 -1
  276. package/build/stores/glasses.js +14 -1
  277. package/build/stores/glasses.js.map +1 -1
  278. package/build/stores/settings.d.ts +1 -0
  279. package/build/stores/settings.d.ts.map +1 -1
  280. package/build/stores/settings.js +170 -44
  281. package/build/stores/settings.js.map +1 -1
  282. package/build/types/applet.d.ts +14 -1
  283. package/build/types/applet.d.ts.map +1 -1
  284. package/build/types/applet.js.map +1 -1
  285. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  286. package/build/types/capabilities/even-realities-g2.js +5 -0
  287. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  288. package/build/types/capabilities/simulated-glasses.d.ts +1 -1
  289. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
  290. package/build/types/capabilities/simulated-glasses.js +7 -4
  291. package/build/types/capabilities/simulated-glasses.js.map +1 -1
  292. package/build/types/hardware.d.ts +20 -1
  293. package/build/types/hardware.d.ts.map +1 -1
  294. package/build/types/hardware.js +2 -0
  295. package/build/types/hardware.js.map +1 -1
  296. package/build/types/index.d.ts +1 -0
  297. package/build/types/index.d.ts.map +1 -1
  298. package/build/types/index.js +1 -0
  299. package/build/types/index.js.map +1 -1
  300. package/build/utils/debouncedPatch.d.ts +3 -1
  301. package/build/utils/debouncedPatch.d.ts.map +1 -1
  302. package/build/utils/debouncedPatch.js +6 -3
  303. package/build/utils/debouncedPatch.js.map +1 -1
  304. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  305. package/build/utils/devMiniappLaunch.js +4 -3
  306. package/build/utils/devMiniappLaunch.js.map +1 -1
  307. package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
  308. package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
  309. package/build/utils/display/measurer/TextMeasurer.js +2 -272
  310. package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
  311. package/build/utils/display/measurer/script-detection.d.ts +1 -52
  312. package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
  313. package/build/utils/display/measurer/script-detection.js +2 -183
  314. package/build/utils/display/measurer/script-detection.js.map +1 -1
  315. package/build/utils/display/pixelArt.d.ts +3 -0
  316. package/build/utils/display/pixelArt.d.ts.map +1 -0
  317. package/build/utils/display/pixelArt.js +3 -0
  318. package/build/utils/display/pixelArt.js.map +1 -0
  319. package/build/utils/display/profiles/g1.d.ts +1 -32
  320. package/build/utils/display/profiles/g1.d.ts.map +1 -1
  321. package/build/utils/display/profiles/g1.js +2 -212
  322. package/build/utils/display/profiles/g1.js.map +1 -1
  323. package/build/utils/display/profiles/g2.d.ts +1 -12
  324. package/build/utils/display/profiles/g2.d.ts.map +1 -1
  325. package/build/utils/display/profiles/g2.js +2 -33
  326. package/build/utils/display/profiles/g2.js.map +1 -1
  327. package/build/utils/display/profiles/nex.d.ts +1 -9
  328. package/build/utils/display/profiles/nex.d.ts.map +1 -1
  329. package/build/utils/display/profiles/nex.js +2 -149
  330. package/build/utils/display/profiles/nex.js.map +1 -1
  331. package/build/utils/display/profiles/types.d.ts +1 -102
  332. package/build/utils/display/profiles/types.d.ts.map +1 -1
  333. package/build/utils/display/profiles/types.js.map +1 -1
  334. package/build/utils/display/profiles/z100.d.ts +1 -32
  335. package/build/utils/display/profiles/z100.d.ts.map +1 -1
  336. package/build/utils/display/profiles/z100.js +2 -181
  337. package/build/utils/display/profiles/z100.js.map +1 -1
  338. package/build/utils/display/scene/degrade.d.ts.map +1 -1
  339. package/build/utils/display/scene/degrade.js +4 -1
  340. package/build/utils/display/scene/degrade.js.map +1 -1
  341. package/build/utils/display/scene/differ.d.ts +13 -1
  342. package/build/utils/display/scene/differ.d.ts.map +1 -1
  343. package/build/utils/display/scene/differ.js +22 -0
  344. package/build/utils/display/scene/differ.js.map +1 -1
  345. package/build/utils/display/scene/index.d.ts +1 -1
  346. package/build/utils/display/scene/index.d.ts.map +1 -1
  347. package/build/utils/display/scene/index.js.map +1 -1
  348. package/build/utils/display/scene/process.d.ts.map +1 -1
  349. package/build/utils/display/scene/process.js +183 -11
  350. package/build/utils/display/scene/process.js.map +1 -1
  351. package/build/utils/display/scene/store.d.ts +1 -1
  352. package/build/utils/display/scene/store.d.ts.map +1 -1
  353. package/build/utils/display/scene/store.js +0 -0
  354. package/build/utils/display/scene/store.js.map +1 -1
  355. package/build/utils/display/scene/svgPath.d.ts +9 -0
  356. package/build/utils/display/scene/svgPath.d.ts.map +1 -0
  357. package/build/utils/display/scene/svgPath.js +167 -0
  358. package/build/utils/display/scene/svgPath.js.map +1 -0
  359. package/build/utils/display/scene/types.d.ts +2 -142
  360. package/build/utils/display/scene/types.d.ts.map +1 -1
  361. package/build/utils/display/scene/types.js +0 -0
  362. package/build/utils/display/scene/types.js.map +1 -1
  363. package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
  364. package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
  365. package/build/utils/display/wrapper/TextWrapper.js +2 -470
  366. package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
  367. package/build/utils/display/wrapper/types.d.ts +2 -74
  368. package/build/utils/display/wrapper/types.d.ts.map +1 -1
  369. package/build/utils/display/wrapper/types.js +2 -10
  370. package/build/utils/display/wrapper/types.js.map +1 -1
  371. package/build/utils/hardware/hardware.js +1 -1
  372. package/build/utils/hardware/hardware.js.map +1 -1
  373. package/build/utils/timers/timers.d.ts.map +1 -1
  374. package/build/utils/timers/timers.js +26 -4
  375. package/build/utils/timers/timers.js.map +1 -1
  376. package/package.json +8 -8
  377. package/src/engine.ts +24 -15
  378. package/src/facades/dev.ts +10 -0
  379. package/src/facades/display.ts +21 -8
  380. package/src/facades/displayMirror.ts +29 -0
  381. package/src/facades/glasses.ts +61 -1
  382. package/src/facades/memory.ts +1 -12
  383. package/src/facades/miniapps.ts +4 -1
  384. package/src/facades/pairing.ts +8 -6
  385. package/src/facades/permissions.ts +46 -0
  386. package/src/facades/phoneNotifications.ts +45 -26
  387. package/src/facades/settings.ts +1 -2
  388. package/src/generated/releaseMetadata.ts +4 -4
  389. package/src/index.ts +6 -9
  390. package/src/react/MentraLiveOtaFlow.tsx +2 -2
  391. package/src/react/useMentraLiveOta.ts +14 -8
  392. package/src/runtime/config.ts +1 -1
  393. package/src/services/AppRegistry.ts +43 -7
  394. package/src/services/BlobStore.ts +3 -3
  395. package/src/services/CloudClientService.ts +37 -10
  396. package/src/services/DevServerBridge.ts +12 -10
  397. package/src/services/DeviceEventRouter.ts +73 -74
  398. package/src/services/DisplayDiagnostics.ts +107 -0
  399. package/src/services/DisplayProcessor.ts +20 -55
  400. package/src/services/GestureDotsService.ts +77 -16
  401. package/src/services/GlassesKeyboardInput.ts +306 -0
  402. package/src/services/GlassesSensorService.ts +233 -0
  403. package/src/services/GlassesTouchInput.ts +128 -0
  404. package/src/services/HeadingService.ts +0 -24
  405. package/src/services/HotspotShutdown.ts +3 -1
  406. package/src/services/JSCrashloopReportService.ts +2 -2
  407. package/src/services/JSRouter.ts +29 -14
  408. package/src/services/LocalDisplayManager.ts +112 -26
  409. package/src/services/LocalMiniappDataMigration.ts +1 -1
  410. package/src/services/LocalMiniappRuntime.ts +500 -43
  411. package/src/services/LocalSttFallbackCoordinator.ts +28 -7
  412. package/src/services/MemoryStore.ts +32 -80
  413. package/src/services/MiniappEngine.ts +7 -7
  414. package/src/services/MiniappLauncher.ts +25 -1
  415. package/src/services/MirrorService.ts +139 -0
  416. package/src/services/NativeNavigationService.ts +29 -25
  417. package/src/services/NavigationHandlers.ts +10 -5
  418. package/src/services/OtaInstallCoordinator.ts +36 -34
  419. package/src/services/PairedGlassesLatch.ts +39 -0
  420. package/src/services/PhoneActivity.ts +116 -0
  421. package/src/services/PhoneCameraFovCoordinator.ts +6 -4
  422. package/src/services/PhoneNotificationsSync.ts +185 -103
  423. package/src/services/PhonePhotoCoordinator.ts +9 -10
  424. package/src/services/PhoneStreamCoordinator.ts +13 -11
  425. package/src/services/STTModelManager.ts +15 -1
  426. package/src/services/SceneRenderer.ts +148 -10
  427. package/src/services/StreamLifecycleController.ts +9 -7
  428. package/src/services/TTSModelManager.ts +1 -1
  429. package/src/services/UIRouter.ts +5 -5
  430. package/src/services/asg/galleryPathMigration.ts +1 -1
  431. package/src/services/asg/gallerySyncService.ts +2 -2
  432. package/src/services/asg/localStorageService.ts +3 -3
  433. package/src/services/debug/DashboardOpenTrace.ts +153 -0
  434. package/src/services/debug/dashboardOpenTimeline.ts +237 -0
  435. package/src/services/effectiveCapabilities.ts +32 -13
  436. package/src/services/gestureClaims.ts +72 -23
  437. package/src/services/manifestFields.ts +23 -0
  438. package/src/services/memoryStoreInstance.ts +2 -34
  439. package/src/services/mirrorSnapshot.ts +116 -0
  440. package/src/services/nativeNavigationGate.ts +14 -0
  441. package/src/services/notificationAppCatalog.ts +21 -0
  442. package/src/services/notifications/notificationPolicy.ts +87 -0
  443. package/src/services/pages/OverlayPages.ts +86 -0
  444. package/src/services/pages/PageHost.ts +116 -0
  445. package/src/services/pages/overlayApps.ts +72 -0
  446. package/src/services/pages/pageEligibility.ts +30 -0
  447. package/src/services/settingsBridge.ts +111 -0
  448. package/src/services/speakerProfileStoreInstance.ts +1 -1
  449. package/src/services/uiShim.ts +4 -4
  450. package/src/stores/appVisibility.ts +45 -0
  451. package/src/stores/apps.ts +110 -32
  452. package/src/stores/bluetoothSettingKeys.ts +1 -1
  453. package/src/stores/display.ts +18 -7
  454. package/src/stores/glasses.ts +15 -1
  455. package/src/stores/settings.ts +175 -51
  456. package/src/types/applet.ts +14 -1
  457. package/src/types/capabilities/even-realities-g2.ts +6 -0
  458. package/src/types/capabilities/simulated-glasses.ts +8 -4
  459. package/src/types/hardware.ts +34 -1
  460. package/src/types/index.ts +1 -0
  461. package/src/utils/debouncedPatch.ts +8 -4
  462. package/src/utils/devMiniappLaunch.ts +5 -3
  463. package/src/utils/display/measurer/TextMeasurer.ts +3 -346
  464. package/src/utils/display/measurer/script-detection.ts +10 -218
  465. package/src/utils/display/pixelArt.ts +3 -0
  466. package/src/utils/display/profiles/g1.ts +2 -236
  467. package/src/utils/display/profiles/g2.ts +2 -39
  468. package/src/utils/display/profiles/nex.ts +2 -166
  469. package/src/utils/display/profiles/types.ts +9 -132
  470. package/src/utils/display/profiles/z100.ts +2 -198
  471. package/src/utils/display/scene/degrade.ts +4 -1
  472. package/src/utils/display/scene/differ.ts +25 -1
  473. package/src/utils/display/scene/index.ts +5 -0
  474. package/src/utils/display/scene/process.ts +196 -13
  475. package/src/utils/display/scene/store.ts +0 -0
  476. package/src/utils/display/scene/svgPath.ts +163 -0
  477. package/src/utils/display/scene/types.ts +0 -0
  478. package/src/utils/display/wrapper/TextWrapper.ts +2 -546
  479. package/src/utils/display/wrapper/types.ts +3 -102
  480. package/src/utils/hardware/hardware.ts +1 -1
  481. package/src/utils/timers/timers.ts +32 -4
  482. package/build/services/CustomDashboardModel.d.ts +0 -48
  483. package/build/services/CustomDashboardModel.d.ts.map +0 -1
  484. package/build/services/CustomDashboardModel.js +0 -73
  485. package/build/services/CustomDashboardModel.js.map +0 -1
  486. package/build/services/CustomDashboardService.d.ts +0 -63
  487. package/build/services/CustomDashboardService.d.ts.map +0 -1
  488. package/build/services/CustomDashboardService.js +0 -576
  489. package/build/services/CustomDashboardService.js.map +0 -1
  490. package/build/services/DashboardCoordinator.d.ts +0 -26
  491. package/build/services/DashboardCoordinator.d.ts.map +0 -1
  492. package/build/services/DashboardCoordinator.js +0 -125
  493. package/build/services/DashboardCoordinator.js.map +0 -1
  494. package/build/services/iosNotificationAppCatalog.d.ts +0 -13
  495. package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
  496. package/build/services/iosNotificationAppCatalog.js +0 -28
  497. package/build/services/iosNotificationAppCatalog.js.map +0 -1
  498. package/src/services/CustomDashboardModel.ts +0 -83
  499. package/src/services/CustomDashboardService.ts +0 -598
  500. package/src/services/DashboardCoordinator.ts +0 -121
  501. package/src/services/iosNotificationAppCatalog.ts +0 -39
@@ -1,576 +0,0 @@
1
- /**
2
- * Scene API dashboard for G2 custom firmware.
3
- *
4
- * G2.swift marks the published firmware version after it detects the CFW
5
- * capability advertisement. DashboardCoordinator owns open/close and display
6
- * switching; this service renders the widgets and handles gestures while open.
7
- *
8
- * The dashboard is composed of user-orderable widgets (clock, calendar, apps
9
- * button, notifications button) stacked vertically on the CFW scene canvas.
10
- * The apps button switches to a second, dashboard-rendered app menu view.
11
- */
12
- import { File } from "expo-file-system";
13
- import { BluetoothSdk } from "@glassly/bluetooth-sdk";
14
- import { MiniappErrorCode } from "@glassly/miniapp";
15
- import { useAppStatusStore } from "../stores/apps";
16
- import { useGlassesStore } from "../stores/glasses";
17
- import { SETTINGS, useSettingsStore } from "../stores/settings";
18
- import { TextMeasurer } from "../utils/display/measurer";
19
- import { BgTimer } from "../utils/timers";
20
- import { appMenuActions, dashboardActions, formatDashboardClock, isCustomDashboardEligible, normalizeDashboardWidgets, orderedDashboardApps, } from "./CustomDashboardModel";
21
- import displayProcessor from "./DisplayProcessor";
22
- import { isGlassesConnected } from "./GlassesReadiness";
23
- import localDisplayManager from "./LocalDisplayManager";
24
- import { listPhoneCalendarEvents, PhoneCalendarError } from "./PhoneCalendarService";
25
- import sceneRenderer from "./SceneRenderer";
26
- const DASHBOARD_APP_ID = "system.custom-dashboard";
27
- const CLOCK_REFRESH_MS = 30_000;
28
- const CALENDAR_REFRESH_MS = 5 * 60_000;
29
- /** Matches the boot message's window; stops have no unmount-driven end signal. */
30
- const STOP_NOTICE_MS = 1500;
31
- // CFW blits the stock compositor's 576×288 canvas; used when the firmware has
32
- // not reported scene capabilities yet.
33
- const FALLBACK_CANVAS = { width: 576, height: 288 };
34
- const MARGIN_X = 16;
35
- const MARGIN_TOP = 10;
36
- const WIDGET_GAP = 10;
37
- /** Row height for the glasses' builtin 20px font engine. */
38
- const LINE_H = 24;
39
- const BUTTON_H = 34;
40
- /**
41
- * Selection marker: a text-hugging bar under the focused label instead of a
42
- * boxed border. Drawn as a rect (h 3, border 2 — the strokes overlap into a
43
- * solid bar) because mode 15 renders only glyphs; the bar must be in the
44
- * raster or the firmware never shows it.
45
- */
46
- const UNDERLINE_H = 3;
47
- /** Row-top → underline-top: just under the builtin font's 27px line. */
48
- const UNDERLINE_OFFSET_Y = BUTTON_H - 4;
49
- /**
50
- * App-menu icon grid: 2 rows × 4 columns per page. CFW rasterizes scenes
51
- * phone-side, so the stock firmware's 4-image container pool does not bound
52
- * the page (getEffectiveCapabilities lifts the element caps while the CFW
53
- * canvas is active).
54
- */
55
- const APP_GRID_COLS = 4;
56
- const APP_GRID_ROWS = 2;
57
- const APPS_PER_PAGE = APP_GRID_COLS * APP_GRID_ROWS;
58
- const APP_CELL = 36;
59
- const APP_CELL_GAP = 12;
60
- const APP_ICON_INSET = 2;
61
- const APP_ICON = APP_CELL - APP_ICON_INSET * 2;
62
- function eventLine(event) {
63
- const when = event.allDay
64
- ? "All day"
65
- : new Intl.DateTimeFormat(undefined, { hour: "numeric", minute: "2-digit" }).format(new Date(event.startsAt));
66
- return `${when} ${event.title}`;
67
- }
68
- class CustomDashboardService {
69
- started = false;
70
- open = false;
71
- /** Set by DashboardCoordinator; asks it to close (and restore main content). */
72
- onRequestClose = null;
73
- view = "main";
74
- mainIndex = 0;
75
- appsIndex = 0;
76
- /** "loading" until the first fetch resolves; "no-access" only for a real permission denial. */
77
- calendarStatus = "loading";
78
- /** packageName → base64 icon bytes, or null when the icon can't be loaded (monogram fallback). */
79
- iconCache = new Map();
80
- iconLoads = new Set();
81
- calendarEvents = [];
82
- unsubs = [];
83
- clockTimer = null;
84
- calendarTimer = null;
85
- /** Last observed eligibility, for transition detection. */
86
- eligible = false;
87
- start() {
88
- if (this.started)
89
- return;
90
- this.started = true;
91
- this.unsubs.push(useGlassesStore.subscribe((state) => `${state.connection.state}:${state.deviceModel}:${state.firmwareVersion}`, () => {
92
- if (!this.syncEligibility())
93
- return;
94
- void this.refreshCalendarAndRender();
95
- }),
96
- // Selector: only dashboard-relevant settings retrigger a refresh. The
97
- // whole-store form fired a calendar query on every settings write.
98
- useSettingsStore.subscribe((state) => JSON.stringify([
99
- state.getSetting(SETTINGS.custom_dashboard_enabled.key),
100
- state.getSetting(SETTINGS.custom_dashboard_widgets.key),
101
- state.getSetting(SETTINGS.custom_dashboard_clock_style.key),
102
- state.getSetting(SETTINGS.custom_dashboard_clock_show_date.key),
103
- state.getSetting(SETTINGS.twelve_hour_time.key),
104
- state.getSetting(SETTINGS.custom_dashboard_calendar_event_count.key),
105
- state.getSetting(SETTINGS.custom_dashboard_calendar_days_ahead.key),
106
- state.getSetting(SETTINGS.menu_apps.key),
107
- ]), () => {
108
- if (!this.syncEligibility())
109
- return;
110
- void this.refreshCalendarAndRender();
111
- }), useAppStatusStore.subscribe(() => {
112
- if (this.isEligible())
113
- this.render();
114
- }));
115
- this.clockTimer = BgTimer.setInterval(() => {
116
- if (this.isEligible())
117
- this.render();
118
- }, CLOCK_REFRESH_MS);
119
- this.calendarTimer = BgTimer.setInterval(() => {
120
- if (this.isEligible())
121
- void this.refreshCalendarAndRender();
122
- }, CALENDAR_REFRESH_MS);
123
- this.eligible = this.isEligible();
124
- }
125
- /**
126
- * Track eligible⇄ineligible transitions from any trigger (setting toggle,
127
- * connect/disconnect, firmware change). Leaving closes the dashboard via the
128
- * coordinator (which restores main content) and drops the retained scene so
129
- * a stale frame can't be replayed after the feature was turned off.
130
- */
131
- syncEligibility() {
132
- const eligible = this.isEligible();
133
- if (eligible === this.eligible)
134
- return eligible;
135
- this.eligible = eligible;
136
- if (!eligible) {
137
- if (this.open)
138
- this.onRequestClose?.();
139
- this.open = false;
140
- this.resetNavigation();
141
- sceneRenderer.clearApp(DASHBOARD_APP_ID);
142
- }
143
- return eligible;
144
- }
145
- stop() {
146
- for (const unsub of this.unsubs)
147
- unsub();
148
- this.unsubs = [];
149
- if (this.clockTimer !== null)
150
- BgTimer.clearInterval(this.clockTimer);
151
- if (this.calendarTimer !== null)
152
- BgTimer.clearInterval(this.calendarTimer);
153
- this.clockTimer = null;
154
- this.calendarTimer = null;
155
- if (this.open)
156
- this.onRequestClose?.();
157
- this.open = false;
158
- this.eligible = false;
159
- this.resetNavigation();
160
- this.started = false;
161
- sceneRenderer.clearApp(DASHBOARD_APP_ID);
162
- }
163
- isEligible() {
164
- if (useSettingsStore.getState().getSetting(SETTINGS.custom_dashboard_enabled.key) === false)
165
- return false;
166
- const state = useGlassesStore.getState();
167
- return (isGlassesConnected(state.connection) &&
168
- isCustomDashboardEligible({
169
- model: state.deviceModel,
170
- firmwareVersion: state.firmwareVersion,
171
- }));
172
- }
173
- get isOpen() {
174
- return this.open;
175
- }
176
- /** Coordinator opened the dashboard: render fresh from the top. */
177
- show() {
178
- this.open = true;
179
- this.resetNavigation();
180
- void this.refreshCalendarAndRender();
181
- }
182
- /** Coordinator closed the dashboard. */
183
- hide() {
184
- this.open = false;
185
- this.resetNavigation();
186
- }
187
- /** Returns true when an open custom dashboard consumed the gesture. */
188
- handleGesture(gestureName) {
189
- if (!this.open || !this.isEligible())
190
- return false;
191
- if (gestureName === "double_tap") {
192
- // In the app menu a double tap backs out to the top of the dashboard
193
- // (there is no Back row); on the main view it closes the dashboard.
194
- if (this.view === "apps") {
195
- this.resetNavigation();
196
- this.render();
197
- return true;
198
- }
199
- this.onRequestClose?.();
200
- return true;
201
- }
202
- if (this.view === "apps")
203
- return this.handleAppMenuGesture(gestureName);
204
- return this.handleMainGesture(gestureName);
205
- }
206
- resetNavigation() {
207
- this.view = "main";
208
- this.mainIndex = 0;
209
- this.appsIndex = 0;
210
- }
211
- handleMainGesture(gestureName) {
212
- const actions = dashboardActions(this.widgets());
213
- if (this.mainIndex >= actions.length)
214
- this.mainIndex = Math.max(0, actions.length - 1);
215
- if (gestureName === "swipe_down" || gestureName === "swipe_up") {
216
- if (actions.length === 0)
217
- return true;
218
- const delta = gestureName === "swipe_down" ? 1 : -1;
219
- this.mainIndex = (this.mainIndex + delta + actions.length) % actions.length;
220
- this.render();
221
- return true;
222
- }
223
- if (gestureName === "single_tap") {
224
- const action = actions[this.mainIndex];
225
- if (action?.kind === "apps-menu") {
226
- this.view = "apps";
227
- this.appsIndex = 0;
228
- this.render();
229
- }
230
- else if (action?.kind === "notifications") {
231
- void this.openNotificationsPanel();
232
- }
233
- return true;
234
- }
235
- return false;
236
- }
237
- handleAppMenuGesture(gestureName) {
238
- const rows = appMenuActions(this.menuApps());
239
- if (this.appsIndex >= rows.length)
240
- this.appsIndex = Math.max(0, rows.length - 1);
241
- if (gestureName === "swipe_down" || gestureName === "swipe_up") {
242
- const delta = gestureName === "swipe_down" ? 1 : -1;
243
- this.appsIndex = (this.appsIndex + delta + rows.length) % rows.length;
244
- this.render();
245
- return true;
246
- }
247
- if (gestureName === "single_tap") {
248
- const row = rows[this.appsIndex];
249
- if (row?.kind === "app") {
250
- void this.toggleApp(row.packageName);
251
- }
252
- return true;
253
- }
254
- return false;
255
- }
256
- menuApps() {
257
- const menu = useSettingsStore.getState().getSetting(SETTINGS.menu_apps.key);
258
- return orderedDashboardApps(menu, useAppStatusStore.getState().apps);
259
- }
260
- widgets() {
261
- return normalizeDashboardWidgets(useSettingsStore.getState().getSetting(SETTINGS.custom_dashboard_widgets.key));
262
- }
263
- async openNotificationsPanel() {
264
- this.onRequestClose?.();
265
- await BluetoothSdk.showNativeNotificationPanel().catch((error) => {
266
- console.error("CustomDashboard: notification panel failed", error);
267
- });
268
- }
269
- async toggleApp(packageName) {
270
- this.onRequestClose?.();
271
- const app = useAppStatusStore.getState().apps.find((candidate) => candidate.packageName === packageName);
272
- if (!app)
273
- return;
274
- if (app.running) {
275
- // Mirror the "Starting X…" boot message: without this the dashboard just
276
- // closes and the stop is invisible on the glasses.
277
- localDisplayManager.showSystemNotice(`Stopping ${app.name}…`, STOP_NOTICE_MS);
278
- await useAppStatusStore.getState().stop(app.packageName);
279
- }
280
- else {
281
- await useAppStatusStore.getState().start(app, { skipNavigation: true });
282
- }
283
- }
284
- calendarWidgetEnabled() {
285
- return this.widgets().some((widget) => widget.id === "calendar" && widget.enabled);
286
- }
287
- async refreshCalendarAndRender() {
288
- if (!this.open)
289
- return;
290
- if (!this.calendarWidgetEnabled()) {
291
- this.calendarStatus = "loading";
292
- this.calendarEvents = [];
293
- this.render();
294
- return;
295
- }
296
- const settings = useSettingsStore.getState();
297
- const count = Number(settings.getSetting(SETTINGS.custom_dashboard_calendar_event_count.key) ?? 2);
298
- const days = Number(settings.getSetting(SETTINGS.custom_dashboard_calendar_days_ahead.key) ?? 3);
299
- const startsAt = new Date();
300
- const endsAt = new Date(startsAt.getTime() + Math.max(1, days) * 24 * 60 * 60 * 1000);
301
- try {
302
- const result = await listPhoneCalendarEvents({
303
- startsAt: startsAt.toISOString(),
304
- endsAt: endsAt.toISOString(),
305
- limit: Math.max(1, Math.min(3, count)),
306
- });
307
- this.calendarStatus = "ok";
308
- this.calendarEvents = result.events;
309
- }
310
- catch (error) {
311
- // Permission is requested from the Custom Dashboard settings screen;
312
- // only a real denial should read as one — any other failure is
313
- // "Unavailable" (and logged) so it can't masquerade as a permission
314
- // problem.
315
- const denied = error instanceof PhoneCalendarError && error.code === MiniappErrorCode.PERMISSION_DENIED;
316
- this.calendarStatus = denied ? "no-access" : "unavailable";
317
- this.calendarEvents = [];
318
- if (!denied)
319
- console.warn("CustomDashboard: calendar fetch failed", error);
320
- }
321
- this.render();
322
- }
323
- /** Underline hugging a builtin-font label. x/rowY are the label box's origin. */
324
- labelUnderline(id, x, rowY, label) {
325
- // Same metrics processScene uses to ellipsize builtin text; the raster
326
- // insets text by 2px, so the bar starts under the first glyph.
327
- const textW = new TextMeasurer(displayProcessor.getProfile()).measureText(label);
328
- return {
329
- type: "rect",
330
- id,
331
- box: { x: x + 2, y: rowY + UNDERLINE_OFFSET_Y, w: textW + 4, h: UNDERLINE_H },
332
- style: { border: 2 },
333
- };
334
- }
335
- canvas() {
336
- const { sceneCanvasWidth, sceneCanvasHeight } = useGlassesStore.getState();
337
- if (sceneCanvasWidth && sceneCanvasWidth > 0 && sceneCanvasHeight && sceneCanvasHeight > 0) {
338
- return { width: sceneCanvasWidth, height: sceneCanvasHeight };
339
- }
340
- return FALLBACK_CANVAS;
341
- }
342
- render() {
343
- // Only while open: emitting into the single native view while closed
344
- // would clobber the main content.
345
- if (!this.open || !this.isEligible())
346
- return;
347
- const elements = this.view === "apps" ? this.appMenuElements() : this.mainElements();
348
- sceneRenderer.emitScene(DASHBOARD_APP_ID, "dashboard", elements);
349
- }
350
- mainElements() {
351
- const canvas = this.canvas();
352
- const settings = useSettingsStore.getState();
353
- const widgets = this.widgets().filter((widget) => widget.enabled);
354
- const actions = dashboardActions(widgets);
355
- if (this.mainIndex >= actions.length)
356
- this.mainIndex = Math.max(0, actions.length - 1);
357
- const selected = actions[this.mainIndex];
358
- const clockStyle = settings.getSetting(SETTINGS.custom_dashboard_clock_style.key) === "large"
359
- ? "large"
360
- : "compact";
361
- const calendarEnabled = widgets.some((widget) => widget.id === "calendar");
362
- // Calendar lives in the right half; everything else stacks in the left
363
- // half (full width when the calendar widget is off).
364
- const halfW = Math.floor(canvas.width / 2) - MARGIN_X - Math.floor(WIDGET_GAP / 2);
365
- const width = calendarEnabled ? halfW : canvas.width - MARGIN_X * 2;
366
- const rightX = Math.floor(canvas.width / 2) + Math.floor(WIDGET_GAP / 2);
367
- const elements = [];
368
- let y = MARGIN_TOP;
369
- for (const widget of widgets) {
370
- if (widget.id === "clock") {
371
- const fontSize = clockStyle === "large" ? 48 : 32;
372
- const clock = formatDashboardClock(new Date(), {
373
- twelveHour: settings.getSetting(SETTINGS.twelve_hour_time.key) === true,
374
- showDate: settings.getSetting(SETTINGS.custom_dashboard_clock_show_date.key) !== false,
375
- });
376
- elements.push({
377
- type: "text",
378
- id: "clock",
379
- box: { x: MARGIN_X, y, w: width, h: fontSize + 6 },
380
- text: clock.time,
381
- style: { font: "mono", fontSize, breakMode: "strict-word" },
382
- });
383
- y += fontSize + 6;
384
- if (clock.date) {
385
- elements.push({
386
- type: "text",
387
- id: "clock-date",
388
- box: { x: MARGIN_X, y, w: width, h: LINE_H },
389
- text: clock.date,
390
- style: { font: "builtin", breakMode: "strict-word" },
391
- });
392
- y += LINE_H;
393
- }
394
- y += WIDGET_GAP;
395
- }
396
- else if (widget.id === "calendar") {
397
- // Right half, top-aligned, independent of the left stack. A missing
398
- // calendar shows a hint instead of silently vanishing — "No access"
399
- // strictly for permission denial, "Unavailable" for any other failure.
400
- const lines = this.calendarStatus === "ok"
401
- ? [
402
- "Calendar",
403
- ...(this.calendarEvents.length
404
- ? this.calendarEvents.slice(0, 3).map(eventLine)
405
- : ["No upcoming events"]),
406
- ]
407
- : this.calendarStatus === "loading"
408
- ? ["Calendar"]
409
- : ["Calendar", this.calendarStatus === "no-access" ? "No access" : "Unavailable"];
410
- elements.push({
411
- type: "text",
412
- id: "calendar",
413
- box: { x: rightX, y: MARGIN_TOP, w: halfW, h: lines.length * LINE_H },
414
- text: lines.join("\n"),
415
- style: { font: "builtin", breakMode: "strict-word", overflow: "ellipsis" },
416
- });
417
- }
418
- else if (widget.id === "apps") {
419
- elements.push({
420
- type: "text",
421
- id: "apps-button",
422
- box: { x: MARGIN_X, y, w: width, h: BUTTON_H },
423
- text: "Apps",
424
- style: { font: "builtin" },
425
- });
426
- if (selected?.kind === "apps-menu")
427
- elements.push(this.labelUnderline("apps-underline", MARGIN_X, y, "Apps"));
428
- y += BUTTON_H + WIDGET_GAP;
429
- }
430
- else if (widget.id === "notifications") {
431
- elements.push({
432
- type: "text",
433
- id: "notifications",
434
- box: { x: MARGIN_X, y, w: width, h: BUTTON_H },
435
- text: "Notifications",
436
- style: { font: "builtin" },
437
- });
438
- if (selected?.kind === "notifications") {
439
- elements.push(this.labelUnderline("notifications-underline", MARGIN_X, y, "Notifications"));
440
- }
441
- y += BUTTON_H + WIDGET_GAP;
442
- }
443
- }
444
- return elements;
445
- }
446
- /**
447
- * Resolve a miniapp icon to base64 for the glasses. Local/bundled miniapps
448
- * carry a file:// icon.png; store apps an https URL; the offline system
449
- * tiles a bundler asset id (unsupported here — monogram fallback). Loads
450
- * are async and cached; a finished load repaints the open app menu.
451
- */
452
- loadIcon(app) {
453
- if (this.iconCache.has(app.packageName) || this.iconLoads.has(app.packageName))
454
- return;
455
- const url = typeof app.logoUrl === "string" ? app.logoUrl : "";
456
- if (!/^(file|https?):/.test(url)) {
457
- this.iconCache.set(app.packageName, null);
458
- return;
459
- }
460
- this.iconLoads.add(app.packageName);
461
- void (async () => {
462
- try {
463
- let base64;
464
- if (url.startsWith("file:")) {
465
- base64 = await new File(url).base64();
466
- }
467
- else {
468
- const response = await fetch(url);
469
- const blob = await response.blob();
470
- base64 = await new Promise((resolve, reject) => {
471
- const reader = new FileReader();
472
- reader.onload = () => resolve(String(reader.result).split(",")[1] ?? "");
473
- reader.onerror = () => reject(reader.error);
474
- reader.readAsDataURL(blob);
475
- });
476
- }
477
- this.iconCache.set(app.packageName, base64 || null);
478
- }
479
- catch {
480
- this.iconCache.set(app.packageName, null);
481
- }
482
- finally {
483
- this.iconLoads.delete(app.packageName);
484
- if (this.open && this.view === "apps")
485
- this.render();
486
- }
487
- })();
488
- }
489
- appMenuElements() {
490
- const canvas = this.canvas();
491
- const width = canvas.width - MARGIN_X * 2;
492
- const apps = this.menuApps();
493
- const rows = appMenuActions(apps);
494
- if (this.appsIndex >= rows.length)
495
- this.appsIndex = Math.max(0, rows.length - 1);
496
- const elements = [
497
- {
498
- type: "text",
499
- id: "apps-title",
500
- box: { x: MARGIN_X, y: MARGIN_TOP, w: width, h: LINE_H },
501
- text: "Apps",
502
- style: { font: "builtin" },
503
- },
504
- ];
505
- const listTop = MARGIN_TOP + LINE_H + 16;
506
- if (apps.length === 0) {
507
- elements.push({
508
- type: "text",
509
- id: "apps-empty",
510
- box: { x: MARGIN_X, y: listTop, w: width, h: LINE_H },
511
- text: "No apps in Glasses Menu",
512
- style: { font: "builtin" },
513
- });
514
- return elements;
515
- }
516
- // Icon grid, paged, row-major. Selection is the underlined cell.
517
- const perPage = APPS_PER_PAGE;
518
- const pageStart = Math.floor(this.appsIndex / perPage) * perPage;
519
- const page = apps.slice(pageStart, pageStart + perPage);
520
- const cols = Math.min(page.length, APP_GRID_COLS);
521
- const totalW = cols * APP_CELL + (cols - 1) * APP_CELL_GAP;
522
- const startX = Math.max(MARGIN_X, Math.round((canvas.width - totalW) / 2));
523
- page.forEach((app, cell) => {
524
- const x = startX + (cell % APP_GRID_COLS) * (APP_CELL + APP_CELL_GAP);
525
- const y = listTop + Math.floor(cell / APP_GRID_COLS) * (APP_CELL + APP_CELL_GAP);
526
- const selected = pageStart + cell === this.appsIndex;
527
- const icon = this.iconCache.get(app.packageName);
528
- if (icon === undefined)
529
- this.loadIcon(app);
530
- if (icon) {
531
- elements.push({
532
- type: "image",
533
- id: `app-icon:${app.packageName}`,
534
- box: { x: x + APP_ICON_INSET, y: y + APP_ICON_INSET, w: APP_ICON, h: APP_ICON },
535
- data: icon,
536
- });
537
- }
538
- else {
539
- // Monogram fallback for icons that can't load (bundler-asset tiles).
540
- elements.push({
541
- type: "text",
542
- id: `app-icon:${app.packageName}`,
543
- box: { x: x + APP_ICON_INSET, y: y + APP_ICON_INSET, w: APP_ICON, h: APP_ICON },
544
- text: (app.name.trim()[0] ?? "?").toUpperCase(),
545
- style: { font: "mono", fontSize: 20 },
546
- });
547
- }
548
- if (selected) {
549
- elements.push({
550
- type: "rect",
551
- id: "apps-selection",
552
- box: { x, y: y + APP_CELL + 2, w: APP_CELL, h: UNDERLINE_H },
553
- style: { border: 2 },
554
- });
555
- }
556
- });
557
- // Grayscale mini icons are ambiguous on their own: caption the selection.
558
- const gridRows = Math.ceil(page.length / APP_GRID_COLS);
559
- const gridH = gridRows * APP_CELL + (gridRows - 1) * APP_CELL_GAP;
560
- const selectedApp = apps[this.appsIndex];
561
- if (selectedApp) {
562
- elements.push({
563
- type: "text",
564
- id: "apps-selected-name",
565
- box: { x: MARGIN_X, y: listTop + gridH + 12, w: width, h: LINE_H },
566
- text: `${selectedApp.name}${selectedApp.running ? " (running)" : ""}`,
567
- style: { font: "builtin", breakMode: "strict-word", overflow: "ellipsis" },
568
- });
569
- }
570
- return elements;
571
- }
572
- }
573
- const customDashboardService = new CustomDashboardService();
574
- export default customDashboardService;
575
- export { CustomDashboardService };
576
- //# sourceMappingURL=CustomDashboardService.js.map