@q9labsai/chalk-react-native 4.1.16 → 5.0.0

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 (541) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -29
  3. package/android/src/main/AndroidManifest.xml +2 -1
  4. package/android/src/main/java/ai/q9labs/chalk/reactnative/ChalkSpaceForegroundService.java +105 -31
  5. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAndroidConnectionServicePackage.kt +2 -0
  6. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAudioRouteModule.kt +138 -0
  7. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkCallServiceModule.kt +32 -0
  8. package/dist/android/call-service.d.ts +4 -0
  9. package/dist/android/call-service.d.ts.map +1 -0
  10. package/dist/avatar/FaceAvatar.d.ts +19 -0
  11. package/dist/avatar/FaceAvatar.d.ts.map +1 -0
  12. package/dist/avatar/tile-avatar-size.d.ts +3 -0
  13. package/dist/avatar/tile-avatar-size.d.ts.map +1 -0
  14. package/dist/chunk-GYVZSOGQ.js +30 -0
  15. package/dist/chunk-IHE6EA3T.js +25 -0
  16. package/dist/chunk-OIBT2FNM.js +1479 -0
  17. package/dist/client.d.ts +1 -5
  18. package/dist/client.d.ts.map +1 -1
  19. package/dist/client.js +185 -2
  20. package/dist/components/EmbeddedWhiteboard.d.ts.map +1 -1
  21. package/dist/components/native-media-visibility.d.ts +3 -2
  22. package/dist/components/native-media-visibility.d.ts.map +1 -1
  23. package/dist/components/useAndroidCallService.d.ts +8 -0
  24. package/dist/components/useAndroidCallService.d.ts.map +1 -0
  25. package/dist/dev.d.ts +10 -0
  26. package/dist/dev.d.ts.map +1 -0
  27. package/dist/dev.js +10 -0
  28. package/dist/dock/Dock.d.ts +23 -0
  29. package/dist/dock/Dock.d.ts.map +1 -0
  30. package/dist/dock/LeaveMenu.d.ts +12 -0
  31. package/dist/dock/LeaveMenu.d.ts.map +1 -0
  32. package/dist/dock/MoreSheet.d.ts +17 -0
  33. package/dist/dock/MoreSheet.d.ts.map +1 -0
  34. package/dist/dock/ReactionBurst.d.ts +8 -0
  35. package/dist/dock/ReactionBurst.d.ts.map +1 -0
  36. package/dist/dock/RoutePicker.d.ts +16 -0
  37. package/dist/dock/RoutePicker.d.ts.map +1 -0
  38. package/dist/dock/audio-route.d.ts +25 -0
  39. package/dist/dock/audio-route.d.ts.map +1 -0
  40. package/dist/error-YOPTEH5N.wav +0 -0
  41. package/dist/frame/CallFrame.d.ts +17 -0
  42. package/dist/frame/CallFrame.d.ts.map +1 -0
  43. package/dist/frame/Chalk.d.ts +40 -0
  44. package/dist/frame/Chalk.d.ts.map +1 -0
  45. package/dist/frame/back-handler.d.ts +6 -0
  46. package/dist/frame/back-handler.d.ts.map +1 -0
  47. package/dist/frame/dev-scenario.d.ts +28 -0
  48. package/dist/frame/dev-scenario.d.ts.map +1 -0
  49. package/dist/frame/device-layout.d.ts +16 -0
  50. package/dist/frame/device-layout.d.ts.map +1 -0
  51. package/dist/frame/measurement.d.ts +28 -0
  52. package/dist/frame/measurement.d.ts.map +1 -0
  53. package/dist/frame/portal.d.ts +24 -0
  54. package/dist/frame/portal.d.ts.map +1 -0
  55. package/dist/frame/preferences.d.ts +21 -0
  56. package/dist/frame/preferences.d.ts.map +1 -0
  57. package/dist/frame/regions.d.ts +25 -0
  58. package/dist/frame/regions.d.ts.map +1 -0
  59. package/dist/hand-DFWVXPH2.wav +0 -0
  60. package/dist/haptics/haptics.d.ts +12 -0
  61. package/dist/haptics/haptics.d.ts.map +1 -0
  62. package/dist/header/CallDetailsSheet.d.ts +18 -0
  63. package/dist/header/CallDetailsSheet.d.ts.map +1 -0
  64. package/dist/header/Header.d.ts +17 -0
  65. package/dist/header/Header.d.ts.map +1 -0
  66. package/dist/header/QrCode.d.ts +6 -0
  67. package/dist/header/QrCode.d.ts.map +1 -0
  68. package/dist/icons/Icon.d.ts +12 -0
  69. package/dist/icons/Icon.d.ts.map +1 -0
  70. package/dist/icons/icon-element.d.ts +24 -0
  71. package/dist/icons/icon-element.d.ts.map +1 -0
  72. package/dist/icons/icon-paths.d.ts +530 -0
  73. package/dist/icons/icon-paths.d.ts.map +1 -0
  74. package/dist/index.d.ts +6 -9
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2956 -38
  77. package/dist/join-Z6RL5AHE.wav +0 -0
  78. package/dist/knock-4VBQSHK4.wav +0 -0
  79. package/dist/leave-MQLZOWQD.wav +0 -0
  80. package/dist/limbo/Limbo.d.ts +25 -0
  81. package/dist/limbo/Limbo.d.ts.map +1 -0
  82. package/dist/limbo/Veil.d.ts +10 -0
  83. package/dist/limbo/Veil.d.ts.map +1 -0
  84. package/dist/media/native-capture-error.d.ts +7 -0
  85. package/dist/media/native-capture-error.d.ts.map +1 -0
  86. package/dist/message-6Y6WJGTB.wav +0 -0
  87. package/dist/motion/MovingFrame.d.ts +36 -0
  88. package/dist/motion/MovingFrame.d.ts.map +1 -0
  89. package/dist/motion/motion.d.ts +82 -0
  90. package/dist/motion/motion.d.ts.map +1 -0
  91. package/dist/motion/presence.d.ts +6 -0
  92. package/dist/motion/presence.d.ts.map +1 -0
  93. package/dist/motion/press.d.ts +15 -0
  94. package/dist/motion/press.d.ts.map +1 -0
  95. package/dist/mute-H5SJFXVI.wav +0 -0
  96. package/dist/primitives/BottomSheet.d.ts +36 -0
  97. package/dist/primitives/BottomSheet.d.ts.map +1 -0
  98. package/dist/primitives/ChalkText.d.ts +13 -0
  99. package/dist/primitives/ChalkText.d.ts.map +1 -0
  100. package/dist/primitives/CopyButton.d.ts +11 -0
  101. package/dist/primitives/CopyButton.d.ts.map +1 -0
  102. package/dist/primitives/IconButton.d.ts +26 -0
  103. package/dist/primitives/IconButton.d.ts.map +1 -0
  104. package/dist/primitives/Menu.d.ts +39 -0
  105. package/dist/primitives/Menu.d.ts.map +1 -0
  106. package/dist/primitives/NameTag.d.ts +19 -0
  107. package/dist/primitives/NameTag.d.ts.map +1 -0
  108. package/dist/primitives/PillButton.d.ts +19 -0
  109. package/dist/primitives/PillButton.d.ts.map +1 -0
  110. package/dist/primitives/SegmentedControl.d.ts +17 -0
  111. package/dist/primitives/SegmentedControl.d.ts.map +1 -0
  112. package/dist/primitives/SheetGroup.d.ts +24 -0
  113. package/dist/primitives/SheetGroup.d.ts.map +1 -0
  114. package/dist/primitives/Switch.d.ts +9 -0
  115. package/dist/primitives/Switch.d.ts.map +1 -0
  116. package/dist/primitives/TileShell.d.ts +18 -0
  117. package/dist/primitives/TileShell.d.ts.map +1 -0
  118. package/dist/primitives/announce.d.ts +3 -0
  119. package/dist/primitives/announce.d.ts.map +1 -0
  120. package/dist/primitives/menu-placement.d.ts +32 -0
  121. package/dist/primitives/menu-placement.d.ts.map +1 -0
  122. package/dist/primitives/toast/Toast.d.ts +8 -0
  123. package/dist/primitives/toast/Toast.d.ts.map +1 -0
  124. package/dist/primitives/toast/ToastStack.d.ts +18 -0
  125. package/dist/primitives/toast/ToastStack.d.ts.map +1 -0
  126. package/dist/primitives/toast/toast-store.d.ts +39 -0
  127. package/dist/primitives/toast/toast-store.d.ts.map +1 -0
  128. package/dist/recording-Q4GB77Y4.wav +0 -0
  129. package/dist/sheets/people-chat/ChatNotices.d.ts +14 -0
  130. package/dist/sheets/people-chat/ChatNotices.d.ts.map +1 -0
  131. package/dist/sheets/people-chat/ChatTab.d.ts +6 -0
  132. package/dist/sheets/people-chat/ChatTab.d.ts.map +1 -0
  133. package/dist/sheets/people-chat/Composer.d.ts +7 -0
  134. package/dist/sheets/people-chat/Composer.d.ts.map +1 -0
  135. package/dist/sheets/people-chat/PeopleChatSheet.d.ts +17 -0
  136. package/dist/sheets/people-chat/PeopleChatSheet.d.ts.map +1 -0
  137. package/dist/sheets/people-chat/PeopleTab.d.ts +3 -0
  138. package/dist/sheets/people-chat/PeopleTab.d.ts.map +1 -0
  139. package/dist/sheets/people-chat/PhotoViewer.d.ts +19 -0
  140. package/dist/sheets/people-chat/PhotoViewer.d.ts.map +1 -0
  141. package/dist/sheets/people-chat/TextField.d.ts +4 -0
  142. package/dist/sheets/people-chat/TextField.d.ts.map +1 -0
  143. package/dist/sheets/people-chat/attachments.d.ts +33 -0
  144. package/dist/sheets/people-chat/attachments.d.ts.map +1 -0
  145. package/dist/sheets/people-chat/chat-model.d.ts +64 -0
  146. package/dist/sheets/people-chat/chat-model.d.ts.map +1 -0
  147. package/dist/sheets/people-chat/people-model.d.ts +43 -0
  148. package/dist/sheets/people-chat/people-model.d.ts.map +1 -0
  149. package/dist/sounds/sounds.d.ts +33 -0
  150. package/dist/sounds/sounds.d.ts.map +1 -0
  151. package/dist/space-client/create-native-space-client.d.ts +0 -4
  152. package/dist/space-client/create-native-space-client.d.ts.map +1 -1
  153. package/dist/space-client/random-uuid.d.ts +7 -0
  154. package/dist/space-client/random-uuid.d.ts.map +1 -0
  155. package/dist/stage/ContentTile.d.ts +18 -0
  156. package/dist/stage/ContentTile.d.ts.map +1 -0
  157. package/dist/stage/ParticipantTile.d.ts +18 -0
  158. package/dist/stage/ParticipantTile.d.ts.map +1 -0
  159. package/dist/stage/Stage.d.ts +14 -0
  160. package/dist/stage/Stage.d.ts.map +1 -0
  161. package/dist/stage/TileSheet.d.ts +12 -0
  162. package/dist/stage/TileSheet.d.ts.map +1 -0
  163. package/dist/stage/camera.d.ts +7 -0
  164. package/dist/stage/camera.d.ts.map +1 -0
  165. package/dist/stage/layout.d.ts +57 -0
  166. package/dist/stage/layout.d.ts.map +1 -0
  167. package/dist/stage/space-selector.d.ts +10 -0
  168. package/dist/stage/space-selector.d.ts.map +1 -0
  169. package/dist/stage/stage-view.d.ts +23 -0
  170. package/dist/stage/stage-view.d.ts.map +1 -0
  171. package/dist/status/CallOverlays.d.ts +17 -0
  172. package/dist/status/CallOverlays.d.ts.map +1 -0
  173. package/dist/status/ChalkArrival.d.ts +24 -0
  174. package/dist/status/ChalkArrival.d.ts.map +1 -0
  175. package/dist/status/StatusPage.d.ts +14 -0
  176. package/dist/status/StatusPage.d.ts.map +1 -0
  177. package/dist/status/call-screen.d.ts +20 -0
  178. package/dist/status/call-screen.d.ts.map +1 -0
  179. package/dist/test-VD2KAM4D.wav +0 -0
  180. package/dist/theme/theme.d.ts +15 -0
  181. package/dist/theme/theme.d.ts.map +1 -0
  182. package/dist/theme/tokens.d.ts +248 -0
  183. package/dist/theme/tokens.d.ts.map +1 -0
  184. package/dist/toasts/CallEventToasts.d.ts +21 -0
  185. package/dist/toasts/CallEventToasts.d.ts.map +1 -0
  186. package/dist/toasts/notices.d.ts +34 -0
  187. package/dist/toasts/notices.d.ts.map +1 -0
  188. package/dist/ui/ChalkUI.d.ts +12 -0
  189. package/dist/ui/ChalkUI.d.ts.map +1 -0
  190. package/dist/ui.d.ts +25 -0
  191. package/dist/ui.d.ts.map +1 -0
  192. package/dist/ui.js +77 -0
  193. package/dist/unmute-2XR2LICU.wav +0 -0
  194. package/embedded/chalk-whiteboard/asset-manifest.json +2 -2
  195. package/embedded/chalk-whiteboard/renderer.js +510 -510
  196. package/ios/ChalkAudioRouteModule.swift +93 -0
  197. package/ios/ChalkAudioRouteModuleBridge.m +9 -0
  198. package/package.json +46 -76
  199. package/src/android/call-service.ts +19 -0
  200. package/src/avatar/FaceAvatar.tsx +145 -0
  201. package/src/avatar/tile-avatar-size.ts +4 -0
  202. package/src/client.ts +1 -5
  203. package/src/components/EmbeddedWhiteboard.tsx +14 -71
  204. package/src/components/native-media-visibility.ts +1 -2
  205. package/src/components/useAndroidCallService.ts +41 -0
  206. package/src/dev.ts +9 -0
  207. package/src/dock/Dock.tsx +95 -0
  208. package/src/dock/LeaveMenu.tsx +21 -0
  209. package/src/dock/MoreSheet.tsx +233 -0
  210. package/src/dock/ReactionBurst.tsx +55 -0
  211. package/src/dock/RoutePicker.tsx +42 -0
  212. package/src/dock/audio-route.ts +69 -0
  213. package/src/frame/CallFrame.tsx +209 -0
  214. package/src/frame/Chalk.tsx +83 -0
  215. package/src/frame/back-handler.ts +19 -0
  216. package/src/frame/dev-scenario.ts +48 -0
  217. package/src/frame/device-layout.tsx +31 -0
  218. package/src/frame/measurement.ts +44 -0
  219. package/src/frame/portal.tsx +107 -0
  220. package/src/frame/preferences.tsx +48 -0
  221. package/src/frame/regions.test.ts +38 -0
  222. package/src/frame/regions.ts +60 -0
  223. package/src/haptics/haptics.ts +19 -0
  224. package/src/header/CallDetailsSheet.tsx +139 -0
  225. package/src/header/Header.tsx +107 -0
  226. package/src/header/QrCode.tsx +34 -0
  227. package/src/icons/Icon.tsx +35 -0
  228. package/src/icons/icon-element.ts +11 -0
  229. package/src/icons/icon-paths.ts +199 -0
  230. package/src/index.ts +6 -9
  231. package/src/limbo/Limbo.tsx +159 -0
  232. package/src/limbo/Veil.tsx +36 -0
  233. package/src/media/native-capture-error.test.ts +19 -0
  234. package/src/media/native-capture-error.ts +13 -0
  235. package/src/motion/MovingFrame.tsx +101 -0
  236. package/src/motion/motion.ts +33 -0
  237. package/src/motion/presence.ts +20 -0
  238. package/src/motion/press.ts +35 -0
  239. package/src/primitives/BottomSheet.tsx +211 -0
  240. package/src/primitives/ChalkText.tsx +23 -0
  241. package/src/primitives/CopyButton.tsx +78 -0
  242. package/src/primitives/IconButton.tsx +90 -0
  243. package/src/primitives/Menu.tsx +212 -0
  244. package/src/primitives/NameTag.tsx +68 -0
  245. package/src/primitives/PillButton.tsx +56 -0
  246. package/src/primitives/SegmentedControl.tsx +55 -0
  247. package/src/primitives/SheetGroup.tsx +72 -0
  248. package/src/primitives/Switch.tsx +39 -0
  249. package/src/primitives/TileShell.tsx +53 -0
  250. package/src/primitives/announce.ts +7 -0
  251. package/src/primitives/menu-placement.test.ts +50 -0
  252. package/src/primitives/menu-placement.ts +43 -0
  253. package/src/primitives/toast/Toast.tsx +50 -0
  254. package/src/primitives/toast/ToastStack.tsx +89 -0
  255. package/src/primitives/toast/toast-store.ts +86 -0
  256. package/src/sheets/people-chat/ChatNotices.tsx +69 -0
  257. package/src/sheets/people-chat/ChatTab.tsx +186 -0
  258. package/src/sheets/people-chat/Composer.tsx +182 -0
  259. package/src/sheets/people-chat/PeopleChatSheet.tsx +100 -0
  260. package/src/sheets/people-chat/PeopleTab.tsx +326 -0
  261. package/src/sheets/people-chat/PhotoViewer.tsx +132 -0
  262. package/src/sheets/people-chat/TextField.tsx +14 -0
  263. package/src/sheets/people-chat/attachments.tsx +183 -0
  264. package/src/sheets/people-chat/chat-model.ts +157 -0
  265. package/src/sheets/people-chat/people-chat-model.test.ts +98 -0
  266. package/src/sheets/people-chat/people-model.ts +68 -0
  267. package/src/sounds/assets/error.wav +0 -0
  268. package/src/sounds/assets/hand.wav +0 -0
  269. package/src/sounds/assets/join.wav +0 -0
  270. package/src/sounds/assets/knock.wav +0 -0
  271. package/src/sounds/assets/leave.wav +0 -0
  272. package/src/sounds/assets/message.wav +0 -0
  273. package/src/sounds/assets/mute.wav +0 -0
  274. package/src/sounds/assets/recording.wav +0 -0
  275. package/src/sounds/assets/test.wav +0 -0
  276. package/src/sounds/assets/unmute.wav +0 -0
  277. package/src/sounds/assets.d.ts +5 -0
  278. package/src/sounds/sounds.ts +50 -0
  279. package/src/space-client/create-native-space-client.ts +20 -181
  280. package/src/space-client/random-uuid.ts +17 -0
  281. package/src/space-client/whiteboard-watchdog.test.ts +23 -0
  282. package/src/stage/ContentTile.tsx +100 -0
  283. package/src/stage/ParticipantTile.tsx +140 -0
  284. package/src/stage/Stage.tsx +152 -0
  285. package/src/stage/TileSheet.tsx +116 -0
  286. package/src/stage/camera.ts +20 -0
  287. package/src/stage/layout.test.ts +77 -0
  288. package/src/stage/layout.ts +226 -0
  289. package/src/stage/space-selector.ts +31 -0
  290. package/src/stage/stage-view.tsx +68 -0
  291. package/src/status/CallOverlays.tsx +47 -0
  292. package/src/status/ChalkArrival.tsx +53 -0
  293. package/src/status/StatusPage.tsx +123 -0
  294. package/src/status/call-screen.test.ts +42 -0
  295. package/src/status/call-screen.ts +29 -0
  296. package/src/theme/theme.tsx +28 -0
  297. package/src/theme/tokens.ts +247 -0
  298. package/src/toasts/CallEventToasts.tsx +192 -0
  299. package/src/toasts/notices.test.ts +92 -0
  300. package/src/toasts/notices.ts +62 -0
  301. package/src/ui/ChalkUI.tsx +49 -0
  302. package/src/ui.ts +24 -0
  303. package/dist/android.d.ts +0 -2
  304. package/dist/android.d.ts.map +0 -1
  305. package/dist/android.js +0 -62
  306. package/dist/chunk-2OS7SSXE.js +0 -552
  307. package/dist/chunk-5DQ4KBRH.js +0 -690
  308. package/dist/chunk-ITLUHTVS.js +0 -5271
  309. package/dist/chunk-JB4LNWVP.js +0 -247
  310. package/dist/components/Chalk.d.ts +0 -79
  311. package/dist/components/Chalk.d.ts.map +0 -1
  312. package/dist/components/ChatMessageList.d.ts +0 -11
  313. package/dist/components/ChatMessageList.d.ts.map +0 -1
  314. package/dist/components/Entrance.d.ts +0 -22
  315. package/dist/components/Entrance.d.ts.map +0 -1
  316. package/dist/components/EntranceView.android.d.ts +0 -4
  317. package/dist/components/EntranceView.android.d.ts.map +0 -1
  318. package/dist/components/EntranceView.d.ts +0 -18
  319. package/dist/components/EntranceView.d.ts.map +0 -1
  320. package/dist/components/EntranceView.ios-pad.d.ts +0 -3
  321. package/dist/components/EntranceView.ios-pad.d.ts.map +0 -1
  322. package/dist/components/EntranceView.ios-phone.d.ts +0 -3
  323. package/dist/components/EntranceView.ios-phone.d.ts.map +0 -1
  324. package/dist/components/EntranceView.macos.d.ts +0 -4
  325. package/dist/components/EntranceView.macos.d.ts.map +0 -1
  326. package/dist/components/FaceAvatar.d.ts +0 -16
  327. package/dist/components/FaceAvatar.d.ts.map +0 -1
  328. package/dist/components/GradientSurface.d.ts +0 -14
  329. package/dist/components/GradientSurface.d.ts.map +0 -1
  330. package/dist/components/MediaView.d.ts +0 -14
  331. package/dist/components/MediaView.d.ts.map +0 -1
  332. package/dist/components/ReactionPicker.d.ts +0 -10
  333. package/dist/components/ReactionPicker.d.ts.map +0 -1
  334. package/dist/components/SpaceView.android.d.ts +0 -2
  335. package/dist/components/SpaceView.android.d.ts.map +0 -1
  336. package/dist/components/SpaceView.d.ts +0 -33
  337. package/dist/components/SpaceView.d.ts.map +0 -1
  338. package/dist/components/SpaceView.ios-pad.d.ts +0 -2
  339. package/dist/components/SpaceView.ios-pad.d.ts.map +0 -1
  340. package/dist/components/SpaceView.ios-phone.d.ts +0 -2
  341. package/dist/components/SpaceView.ios-phone.d.ts.map +0 -1
  342. package/dist/components/SpaceView.macos.d.ts +0 -2
  343. package/dist/components/SpaceView.macos.d.ts.map +0 -1
  344. package/dist/components/SpaceView.shared.d.ts +0 -3
  345. package/dist/components/SpaceView.shared.d.ts.map +0 -1
  346. package/dist/components/episode-diagnostic-render-observer.d.ts +0 -2
  347. package/dist/components/episode-diagnostic-render-observer.d.ts.map +0 -1
  348. package/dist/components/logo/Logo.d.ts +0 -11
  349. package/dist/components/logo/Logo.d.ts.map +0 -1
  350. package/dist/components/native-animation-controller.d.ts +0 -7
  351. package/dist/components/native-animation-controller.d.ts.map +0 -1
  352. package/dist/components/native-chat.d.ts +0 -8
  353. package/dist/components/native-chat.d.ts.map +0 -1
  354. package/dist/components/native-entrance/entrance-controller-store.d.ts +0 -34
  355. package/dist/components/native-entrance/entrance-controller-store.d.ts.map +0 -1
  356. package/dist/components/native-entrance/useEntranceController.d.ts +0 -19
  357. package/dist/components/native-entrance/useEntranceController.d.ts.map +0 -1
  358. package/dist/components/native-joining-loading-animation.d.ts +0 -9
  359. package/dist/components/native-joining-loading-animation.d.ts.map +0 -1
  360. package/dist/components/native-space-view/AppearanceSettings.d.ts +0 -2
  361. package/dist/components/native-space-view/AppearanceSettings.d.ts.map +0 -1
  362. package/dist/components/native-space-view/FeedbackSheet.d.ts +0 -12
  363. package/dist/components/native-space-view/FeedbackSheet.d.ts.map +0 -1
  364. package/dist/components/native-space-view/ParticipantActionSheet.d.ts +0 -9
  365. package/dist/components/native-space-view/ParticipantActionSheet.d.ts.map +0 -1
  366. package/dist/components/native-space-view/SettingsSheet.d.ts +0 -7
  367. package/dist/components/native-space-view/SettingsSheet.d.ts.map +0 -1
  368. package/dist/components/native-space-view/SpaceActionMenu.d.ts +0 -10
  369. package/dist/components/native-space-view/SpaceActionMenu.d.ts.map +0 -1
  370. package/dist/components/native-space-view/SpaceBottomDock.android.d.ts +0 -4
  371. package/dist/components/native-space-view/SpaceBottomDock.android.d.ts.map +0 -1
  372. package/dist/components/native-space-view/SpaceChatAttachment.d.ts +0 -8
  373. package/dist/components/native-space-view/SpaceChatAttachment.d.ts.map +0 -1
  374. package/dist/components/native-space-view/SpaceChatSheet.d.ts +0 -5
  375. package/dist/components/native-space-view/SpaceChatSheet.d.ts.map +0 -1
  376. package/dist/components/native-space-view/SpaceGrid.android.d.ts +0 -8
  377. package/dist/components/native-space-view/SpaceGrid.android.d.ts.map +0 -1
  378. package/dist/components/native-space-view/SpaceMoreSheet.d.ts +0 -7
  379. package/dist/components/native-space-view/SpaceMoreSheet.d.ts.map +0 -1
  380. package/dist/components/native-space-view/SpacePanelSheet.d.ts +0 -5
  381. package/dist/components/native-space-view/SpacePanelSheet.d.ts.map +0 -1
  382. package/dist/components/native-space-view/SpacePeopleSheet.d.ts +0 -5
  383. package/dist/components/native-space-view/SpacePeopleSheet.d.ts.map +0 -1
  384. package/dist/components/native-space-view/SpaceStage.android.d.ts +0 -29
  385. package/dist/components/native-space-view/SpaceStage.android.d.ts.map +0 -1
  386. package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts +0 -30
  387. package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts.map +0 -1
  388. package/dist/components/native-space-view/SpaceTopBar.android.d.ts +0 -11
  389. package/dist/components/native-space-view/SpaceTopBar.android.d.ts.map +0 -1
  390. package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts +0 -15
  391. package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts.map +0 -1
  392. package/dist/components/native-space-view/diagnostics.d.ts +0 -48
  393. package/dist/components/native-space-view/diagnostics.d.ts.map +0 -1
  394. package/dist/components/native-space-view/format-space-duration.d.ts +0 -2
  395. package/dist/components/native-space-view/format-space-duration.d.ts.map +0 -1
  396. package/dist/components/native-space-view/native-space-grid-keys.d.ts +0 -3
  397. package/dist/components/native-space-view/native-space-grid-keys.d.ts.map +0 -1
  398. package/dist/components/native-space-view/native-space-page-store.d.ts +0 -8
  399. package/dist/components/native-space-view/native-space-page-store.d.ts.map +0 -1
  400. package/dist/components/native-space-view/space-chat-attachments.d.ts +0 -15
  401. package/dist/components/native-space-view/space-chat-attachments.d.ts.map +0 -1
  402. package/dist/components/native-space-view/space-panel-layout.d.ts +0 -10
  403. package/dist/components/native-space-view/space-panel-layout.d.ts.map +0 -1
  404. package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts +0 -16
  405. package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts.map +0 -1
  406. package/dist/components/native-space-view/space-progressive-surface-types.d.ts +0 -3
  407. package/dist/components/native-space-view/space-progressive-surface-types.d.ts.map +0 -1
  408. package/dist/components/native-space-view/types.d.ts +0 -24
  409. package/dist/components/native-space-view/types.d.ts.map +0 -1
  410. package/dist/components/native-space-view/useSpaceViewController.contract.d.ts +0 -41
  411. package/dist/components/native-space-view/useSpaceViewController.contract.d.ts.map +0 -1
  412. package/dist/components/native-space-view/useSpaceViewController.d.ts +0 -156
  413. package/dist/components/native-space-view/useSpaceViewController.d.ts.map +0 -1
  414. package/dist/components/native-space-view/useSpaceViewDerived.d.ts +0 -12
  415. package/dist/components/native-space-view/useSpaceViewDerived.d.ts.map +0 -1
  416. package/dist/components/native-space-view/useSpaceViewPanels.d.ts +0 -70
  417. package/dist/components/native-space-view/useSpaceViewPanels.d.ts.map +0 -1
  418. package/dist/feedback/native-capture.d.ts +0 -9
  419. package/dist/feedback/native-capture.d.ts.map +0 -1
  420. package/dist/feedback/native-evidence.d.ts +0 -3
  421. package/dist/feedback/native-evidence.d.ts.map +0 -1
  422. package/dist/hooks/entrance-preview-store.d.ts +0 -16
  423. package/dist/hooks/entrance-preview-store.d.ts.map +0 -1
  424. package/dist/hooks/useEntrancePreview.d.ts +0 -7
  425. package/dist/hooks/useEntrancePreview.d.ts.map +0 -1
  426. package/dist/hooks/useLayout.d.ts +0 -16
  427. package/dist/hooks/useLayout.d.ts.map +0 -1
  428. package/dist/hooks/usePanels.d.ts +0 -12
  429. package/dist/hooks/usePanels.d.ts.map +0 -1
  430. package/dist/ios-pad.d.ts +0 -2
  431. package/dist/ios-pad.d.ts.map +0 -1
  432. package/dist/ios-pad.js +0 -62
  433. package/dist/ios-phone.d.ts +0 -2
  434. package/dist/ios-phone.d.ts.map +0 -1
  435. package/dist/ios-phone.js +0 -62
  436. package/dist/ios.d.ts +0 -2
  437. package/dist/ios.d.ts.map +0 -1
  438. package/dist/ios.js +0 -62
  439. package/dist/macos.d.ts +0 -2
  440. package/dist/macos.d.ts.map +0 -1
  441. package/dist/macos.js +0 -62
  442. package/dist/space-client/cloudflare-rtk-native.d.ts +0 -3
  443. package/dist/space-client/cloudflare-rtk-native.d.ts.map +0 -1
  444. package/dist/telemetry.d.ts +0 -63
  445. package/dist/telemetry.d.ts.map +0 -1
  446. package/dist/ui/appearance.d.ts +0 -246
  447. package/dist/ui/appearance.d.ts.map +0 -1
  448. package/dist/ui/appearance.js +0 -14
  449. package/dist/ui/native-appearance-context.d.ts +0 -15
  450. package/dist/ui/native-appearance-context.d.ts.map +0 -1
  451. package/dist/ui/native-theme.d.ts +0 -17
  452. package/dist/ui/native-theme.d.ts.map +0 -1
  453. package/dist/ui/native-types.d.ts +0 -38
  454. package/dist/ui/native-types.d.ts.map +0 -1
  455. package/dist/ui/participant-avatar.d.ts +0 -21
  456. package/dist/ui/participant-avatar.d.ts.map +0 -1
  457. package/dist/ui/theme-tokens.d.ts +0 -25
  458. package/dist/ui/theme-tokens.d.ts.map +0 -1
  459. package/dist/ui/theme.d.ts +0 -404
  460. package/dist/ui/theme.d.ts.map +0 -1
  461. package/dist/ui/theme.js +0 -8
  462. package/dist/utils/native-space-layout.d.ts +0 -42
  463. package/dist/utils/native-space-layout.d.ts.map +0 -1
  464. package/src/android.ts +0 -1
  465. package/src/components/Chalk.tsx +0 -363
  466. package/src/components/ChatMessageList.tsx +0 -209
  467. package/src/components/Entrance.tsx +0 -42
  468. package/src/components/EntranceView.android.tsx +0 -274
  469. package/src/components/EntranceView.ios-pad.tsx +0 -326
  470. package/src/components/EntranceView.ios-phone.tsx +0 -271
  471. package/src/components/EntranceView.macos.tsx +0 -278
  472. package/src/components/EntranceView.tsx +0 -38
  473. package/src/components/FaceAvatar.tsx +0 -120
  474. package/src/components/GradientSurface.tsx +0 -23
  475. package/src/components/MediaView.tsx +0 -76
  476. package/src/components/ReactionPicker.tsx +0 -98
  477. package/src/components/SpaceView.android.tsx +0 -1
  478. package/src/components/SpaceView.ios-pad.tsx +0 -1
  479. package/src/components/SpaceView.ios-phone.tsx +0 -1
  480. package/src/components/SpaceView.macos.tsx +0 -1
  481. package/src/components/SpaceView.shared.tsx +0 -98
  482. package/src/components/SpaceView.tsx +0 -54
  483. package/src/components/episode-diagnostic-render-observer.ts +0 -12
  484. package/src/components/logo/Logo.tsx +0 -309
  485. package/src/components/native-animation-controller.ts +0 -36
  486. package/src/components/native-chat.ts +0 -23
  487. package/src/components/native-entrance/entrance-controller-store.ts +0 -112
  488. package/src/components/native-entrance/useEntranceController.ts +0 -60
  489. package/src/components/native-joining-loading-animation.ts +0 -26
  490. package/src/components/native-space-view/AppearanceSettings.tsx +0 -114
  491. package/src/components/native-space-view/FeedbackSheet.tsx +0 -296
  492. package/src/components/native-space-view/ParticipantActionSheet.tsx +0 -99
  493. package/src/components/native-space-view/SettingsSheet.tsx +0 -164
  494. package/src/components/native-space-view/SpaceActionMenu.tsx +0 -109
  495. package/src/components/native-space-view/SpaceBottomDock.android.tsx +0 -115
  496. package/src/components/native-space-view/SpaceChatAttachment.tsx +0 -105
  497. package/src/components/native-space-view/SpaceChatSheet.tsx +0 -184
  498. package/src/components/native-space-view/SpaceGrid.android.tsx +0 -323
  499. package/src/components/native-space-view/SpaceMoreSheet.tsx +0 -190
  500. package/src/components/native-space-view/SpacePanelSheet.tsx +0 -45
  501. package/src/components/native-space-view/SpacePeopleSheet.tsx +0 -116
  502. package/src/components/native-space-view/SpaceStage.android.tsx +0 -372
  503. package/src/components/native-space-view/SpaceSurfacePrimitives.tsx +0 -75
  504. package/src/components/native-space-view/SpaceTopBar.android.tsx +0 -113
  505. package/src/components/native-space-view/SpaceWhiteboardSurface.tsx +0 -69
  506. package/src/components/native-space-view/diagnostics.ts +0 -84
  507. package/src/components/native-space-view/format-space-duration.ts +0 -3
  508. package/src/components/native-space-view/native-space-grid-keys.ts +0 -6
  509. package/src/components/native-space-view/native-space-page-store.ts +0 -41
  510. package/src/components/native-space-view/space-chat-attachments.test.ts +0 -26
  511. package/src/components/native-space-view/space-chat-attachments.ts +0 -37
  512. package/src/components/native-space-view/space-panel-layout.ts +0 -10
  513. package/src/components/native-space-view/space-progressive-surface-helpers.ts +0 -33
  514. package/src/components/native-space-view/space-progressive-surface-types.ts +0 -3
  515. package/src/components/native-space-view/types.ts +0 -25
  516. package/src/components/native-space-view/useSpaceViewController.contract.ts +0 -34
  517. package/src/components/native-space-view/useSpaceViewController.ts +0 -416
  518. package/src/components/native-space-view/useSpaceViewDerived.ts +0 -29
  519. package/src/components/native-space-view/useSpaceViewPanels.ts +0 -170
  520. package/src/feedback/native-capture.ts +0 -62
  521. package/src/feedback/native-evidence.ts +0 -37
  522. package/src/hooks/entrance-preview-store.ts +0 -99
  523. package/src/hooks/useEntrancePreview.ts +0 -26
  524. package/src/hooks/useLayout.ts +0 -37
  525. package/src/hooks/usePanels.ts +0 -30
  526. package/src/ios-pad.ts +0 -1
  527. package/src/ios-phone.ts +0 -1
  528. package/src/ios.ts +0 -1
  529. package/src/macos.ts +0 -1
  530. package/src/space-client/cloudflare-rtk-native.ts +0 -104
  531. package/src/telemetry.ts +0 -234
  532. package/src/types/hugeicons-direct.d.ts +0 -4
  533. package/src/types/react-native-safe-area-context.d.ts +0 -8
  534. package/src/ui/appearance.ts +0 -808
  535. package/src/ui/native-appearance-context.tsx +0 -74
  536. package/src/ui/native-theme.tsx +0 -54
  537. package/src/ui/native-types.ts +0 -40
  538. package/src/ui/participant-avatar.ts +0 -47
  539. package/src/ui/theme-tokens.ts +0 -41
  540. package/src/ui/theme.ts +0 -214
  541. package/src/utils/native-space-layout.ts +0 -135
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Q9Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
20
+ OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,52 +1,157 @@
1
1
  # @q9labsai/chalk-react-native
2
2
 
3
- React Native bindings and native platform adapters for Chalk.
3
+ React Native bindings, native platform adapters and the drop-in call view for Chalk.
4
4
 
5
- The root package exports exactly:
5
+ ## Install
6
6
 
7
- - Components: `Chalk`, `Entrance`.
8
- - Context: `ChalkProvider`, `useSpaceClient`.
9
- - Snapshot hooks: `useCan`, `useChat`, `useConnection`, `useMedia`,
10
- `useParticipants`, `useReactions`, `useSelf`, and `useWhiteboard`.
11
- - Types: `ChalkFeatures`, `ChalkProps`, `ChalkTheme`, `ChalkThemeTokens`,
12
- `SpaceLayout`, `EntranceProps`, `EntranceSettings`, and `ChalkProviderProps`.
7
+ Install the SDK with every native module it needs as a peer, at the versions your Expo SDK pins:
8
+
9
+ ```sh
10
+ npx expo install @q9labsai/chalk-client @q9labsai/chalk-react-native @cloudflare/react-native-webrtc react-native-webview react-native-reanimated react-native-worklets react-native-gesture-handler react-native-safe-area-context react-native-svg expo-audio expo-haptics expo-clipboard expo-document-picker expo-file-system
11
+ ```
12
+
13
+ The app must also embed the Figtree font (Regular, Medium, SemiBold and Bold) with the `expo-font` config plugin.
14
+
15
+ The root package exports:
16
+
17
+ - Call view: `Chalk`, `ChalkProps`, `Permission`, `ColorScheme`, and `Palette`.
18
+ - Before the call: `ChalkArrival`, `ChalkArrivalProps`, and `ArrivalState`.
19
+ - Context: `ChalkProvider`, `useSpaceClient`, and `ChalkProviderProps`.
20
+ - Snapshot hooks: `useCan`, `useChat`, `useConnection`, `useMedia`, `useParticipants`, `useReactions`, `useRecording`, `useSelf`, and `useWhiteboard`.
21
+ - Invite helpers: `extractSpaceInviteFromLink`, `getClipboardInviteSuggestion`, `parseSpaceInviteLink`, `buildChalkInviteLink`, and `SpaceInviteLink`.
22
+
23
+ Use `ChalkProvider` instead of `Chalk` to build your own call UI. It receives a `SpaceClient`. Components inside the provider can read snapshots with the hooks and access client actions through `useSpaceClient`. The application owns joining, leaving, disposing the client, and rendering its UI.
24
+
25
+ ## Call view
26
+
27
+ `Chalk` draws the whole call: header, stage, dock, sheets, menus and toasts. It fills the screen it's given, joins muted with the camera off, and keeps every control inside the safe area in portrait and landscape. It covers the call while it joins or reconnects, and shows a page when the call is over.
28
+
29
+ ```tsx
30
+ import type { SpaceClient } from "@q9labsai/chalk-client";
31
+ import { Chalk, type ColorScheme } from "@q9labsai/chalk-react-native";
32
+ import { useState } from "react";
33
+
34
+ export function DesignReview({ client, onLeave, onRejoin }: { readonly client: SpaceClient; readonly onLeave: () => void; readonly onRejoin: () => void }) {
35
+ const [colorScheme, setColorScheme] = useState<ColorScheme>("dark");
36
+ const [soundsEnabled, setSoundsEnabled] = useState(true);
37
+ return <Chalk callName="Design review" client={client} colorScheme={colorScheme} inviteLink="https://chalk.example/design-review" onColorSchemeChange={setColorScheme} onLeave={onLeave} onRejoin={onRejoin} onSoundsEnabledChange={setSoundsEnabled} soundsEnabled={soundsEnabled} />;
38
+ }
39
+ ```
40
+
41
+ `Chalk` lays out the call itself, so the stage needs no props. It switches between Spotlight and Grid, moves the active speaker into the spotlight, and sizes screen shares to their shape. iPad uses the phone layout in 5.0.0.
42
+
43
+ | Prop | Type | What it does |
44
+ | ----------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
45
+ | `client` | `SpaceClient` | The call's client. The app creates it with `createNativeSpaceClient` and disposes it. `Chalk` joins it. |
46
+ | `displayName` | `string` | The name others see. Without it, the server's stored name is used. |
47
+ | `callName` | `string` | The call's name in the header, such as "Q9 team". Tapping it opens the call details. |
48
+ | `inviteLink` | `string` | The call's link. More offers to copy and share it, and the call details show it with copy, share and a QR code. Without it, they leave those rows out. |
49
+ | `colorScheme` | `"dark" \| "light"` | The call's look. Dark by default. |
50
+ | `onColorSchemeChange` | `(colorScheme: ColorScheme) => void` | Called when the person changes the look in the call details. |
51
+ | `soundsEnabled` | `boolean` | Call sounds. On by default. |
52
+ | `onSoundsEnabledChange` | `(enabled: boolean) => void` | Called when the person turns call sounds on or off. |
53
+ | `onLeave` | `() => void` | Called when the person is done with the call: from Home on the page that shows after they leave, the call ends, it fails, or they were removed. |
54
+ | `onRejoin` | `() => void` | Called when the person chooses Rejoin or Try again on a page that shows after they leave, the call ends, or it fails. Give the arrival back and render `Chalk` again with a new client, since the old one can't join. |
55
+ | `onOpenSettings` | `(permission: Permission) => void` | Called just before Open Settings takes the person to the system settings to allow the microphone or camera. |
56
+ | `resumedAfterSettings` | `Permission` | Set when the app opens the call again after Open Settings. The call says "Rejoining" and then that it can use the device now. |
57
+
58
+ `Permission` is `"microphone" | "camera"`.
59
+
60
+ Leaving no longer calls `onLeave` straight away. The "You left" page shows first, with Rejoin and Home, and only Home calls `onLeave`. This is a breaking change from 4.x.
61
+
62
+ Rejoin and Try again call `onRejoin`, not `onLeave`. Give the arrival back there, then render `Chalk` again with a new client. The client that left or ended can't join the call a second time.
63
+
64
+ The person can switch the look and call sounds from the call details. The example keeps both in state. To keep the person's choice, store both through the change callbacks and pass them back on the next launch. Load them before you render `Chalk`, so the first frame already has the right theme.
65
+
66
+ ### After a permission change
67
+
68
+ When the microphone or camera isn't allowed, the call shows a notice with Open Settings. iOS restarts the app when a permission changes, so the call is gone when the person comes back. Store the call in `onOpenSettings`, and on the next launch open it again with `resumedAfterSettings`:
13
69
 
14
70
  ```tsx
15
- import { Chalk } from "@q9labsai/chalk-react-native";
71
+ import type { SpaceClient } from "@q9labsai/chalk-client";
72
+ import { Chalk, type Permission } from "@q9labsai/chalk-react-native";
16
73
 
17
- export function SpaceScreen() {
18
- return <Chalk displayName="Taylor" getAccess={getAccess} logoUrl="https://example.com/logo.png" space="design-review" theme={{ colorScheme: "dark", accent: "#14b8a6" }} />;
74
+ type ResumableCallProps = {
75
+ readonly client: SpaceClient;
76
+ readonly resumed?: Permission;
77
+ readonly saveResume: (permission: Permission) => void;
78
+ readonly onLeave: () => void;
79
+ readonly onRejoin: () => void;
80
+ };
81
+
82
+ export function ResumableCall({ client, resumed, saveResume, onLeave, onRejoin }: ResumableCallProps) {
83
+ return <Chalk callName="Design review" client={client} onLeave={onLeave} onOpenSettings={saveResume} onRejoin={onRejoin} resumedAfterSettings={resumed} />;
19
84
  }
20
85
  ```
21
86
 
22
- `Chalk` can instead receive an existing `SpaceClient` through `client`. Set
23
- `entrance={false}` to join immediately; an absent display name is omitted from
24
- the join request. The native experience has focus, grid, and presentation
25
- layouts, and `features.settings` is enabled unless explicitly set to `false`.
87
+ Clear the stored call once you read it, so a later launch doesn't rejoin.
88
+
89
+ ## Before the call lets you in
90
+
91
+ `ChalkArrival` draws the screens before `Chalk` joins, for a call that asks the host first. Render it in place of `Chalk` while the arrival is pending (`state="knocking"`), after the host denies it (`"refused"`), or when the call is full (`"full"`). Render `Chalk` once the person is let in.
26
92
 
27
- ## Feedback
93
+ ```tsx
94
+ import { type ArrivalState, ChalkArrival } from "@q9labsai/chalk-react-native";
28
95
 
29
- The Space action menu includes Feedback. It captures only the Chalk-owned native
30
- view, shows a removable or refreshable preview, and sends bounded Journey,
31
- trace, runtime, and diagnostic context directly to Chalk. Capture failures and
32
- unsupported macOS native capture never block the message.
96
+ export function Arrival({ state, onCancel, onRetry }: { readonly state: ArrivalState; readonly onCancel: () => void; readonly onRetry: () => void }) {
97
+ return <ChalkArrival callName="Design review" onCancel={onCancel} onRetry={onRetry} state={state} />;
98
+ }
99
+ ```
33
100
 
34
- The host app must install the `react-native-view-shot` peer dependency.
35
- Embedded products use the default `embedded` source; Chalk's mobile app
36
- configures `chalk_mobile`.
101
+ | Prop | Type | What it does |
102
+ | ------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
103
+ | `state` | `"knocking" \| "refused" \| "full"` | Which screen to show: "Asking to join" with Cancel, "The host didn't let you in" with Ask again, or "This call is full" with Try again and Home. |
104
+ | `callName` | `string` | The call's name, such as "Q9 team". |
105
+ | `colorScheme` | `"dark" \| "light"` | Dark by default, like `Chalk`. |
106
+ | `onCancel` | `() => void` | Stops waiting: Cancel while knocking, Home when the call is full, and Android back. |
107
+ | `onRetry` | `() => void` | Knocks again after a refusal, or tries again once a full call has room. |
108
+ | `recording` | `boolean` | Shows recording consent while knocking on a recorded call. |
37
109
 
38
- The platform subpaths (`android`, `ios`, `ios-phone`, `ios-pad`, and `macos`)
39
- export the same public surface as the root package.
110
+ ## Your own screens
111
+
112
+ `@q9labsai/chalk-react-native/ui` gives an app's own screens, such as its Home or name step, the same look as the call. Wrap them in `ChalkUI`, which provides the theme, safe areas, sheets, menus and toasts, and build them from the call's primitives.
113
+
114
+ ```tsx
115
+ import { ChalkText, ChalkUI, PillButton } from "@q9labsai/chalk-react-native/ui";
116
+
117
+ export function Home({ onStart }: { readonly onStart: () => void }) {
118
+ return (
119
+ <ChalkUI colorScheme="dark">
120
+ <ChalkText>Start a call or join with a link.</ChalkText>
121
+ <PillButton label="Start a call" onPress={onStart} />
122
+ </ChalkUI>
123
+ );
124
+ }
125
+ ```
126
+
127
+ The entry exports:
128
+
129
+ - Frame: `ChalkUI` and `ChalkUIProps`.
130
+ - Theme: `useTheme`, `Theme`, `fixed`, `fontFamilies`, `radii`, `type`, `ColorScheme`, `Palette`, and `useDeviceLayout`.
131
+ - Icons: `Icon` and `IconName`.
132
+ - Primitives: `ChalkText`, `IconButton`, `PillButton`, `BottomSheet`, `SheetGroup`, `SheetRow`, `Menu`, `MenuItem`, `Switch`, `SegmentedControl`, `CopyButton`, `FaceAvatar`, `useToasts`, `announce`, `usePressAnimation`, and `Limbo`.
40
133
 
41
134
  ## Native client adapter
42
135
 
43
- For advanced lifecycle ownership, import the React Native implementation seam
44
- from `@q9labsai/chalk-react-native/client`. It exposes only
45
- `createNativeSpaceClient` and `NativeSpaceClientOptions`; it does not add a
46
- second root binding shape.
136
+ `@q9labsai/chalk-react-native/client` exports `createNativeSpaceClient` and `NativeSpaceClientOptions`. The native client connects Chalk to React Native media and application lifecycle APIs.
47
137
 
48
138
  ```tsx
49
139
  import { createNativeSpaceClient } from "@q9labsai/chalk-react-native/client";
50
140
 
51
141
  const client = createNativeSpaceClient({ space: "design-review", getAccess });
52
142
  ```
143
+
144
+ The `runtime`, `clipboard`, `diagnostics`, and `invites` subpaths expose native runtime information, clipboard access, diagnostics state, and invite parsing respectively.
145
+
146
+ ## Development entry
147
+
148
+ `@q9labsai/chalk-react-native/dev` is for development only. `setMeasurementRegistry` reports each call surface's frame and declared style by testID, and `setDevScenario` opens a sheet or menu and draws fake video in tiles. Require it behind `__DEV__`, so Metro leaves it out of release bundles:
149
+
150
+ ```js
151
+ if (__DEV__) {
152
+ const { setDevScenario } = require("@q9labsai/chalk-react-native/dev");
153
+ setDevScenario({ sheet: "more" });
154
+ }
155
+ ```
156
+
157
+ Don't import it at the top of a file. A static import puts it in every bundle.
@@ -19,6 +19,7 @@
19
19
  android:name=".ChalkSpaceForegroundService"
20
20
  android:enabled="true"
21
21
  android:exported="false"
22
- android:foregroundServiceType="camera|microphone" />
22
+ android:foregroundServiceType="camera|microphone"
23
+ android:stopWithTask="true" />
23
24
  </application>
24
25
  </manifest>
@@ -1,74 +1,140 @@
1
1
  package ai.q9labs.chalk.reactnative;
2
2
 
3
+ import android.Manifest;
3
4
  import android.app.Notification;
4
5
  import android.app.NotificationChannel;
5
6
  import android.app.NotificationManager;
7
+ import android.app.PendingIntent;
6
8
  import android.app.Service;
9
+ import android.content.ComponentName;
7
10
  import android.content.Context;
8
11
  import android.content.Intent;
12
+ import android.content.pm.PackageManager;
9
13
  import android.content.pm.ServiceInfo;
10
14
  import android.os.Build;
11
15
  import android.os.IBinder;
16
+ import android.util.Log;
12
17
 
13
18
  import androidx.core.app.NotificationCompat;
19
+ import androidx.core.content.ContextCompat;
14
20
 
21
+ /**
22
+ * Keeps a call's microphone and camera working in the background. Android 11 and later cut off a
23
+ * background app's audio and video input unless a foreground service of that type runs. Android 14
24
+ * throws when a type's permission is missing, so the service declares only the types granted.
25
+ */
15
26
  public class ChalkSpaceForegroundService extends Service {
16
- static final String ACTION_START = "ai.q9labs.chalk.reactnative.action.START_BACKGROUND_SPACE";
17
- static final String ACTION_STOP = "ai.q9labs.chalk.reactnative.action.STOP_BACKGROUND_SPACE";
18
- static final String EXTRA_SPACE_NAME = "spaceName";
19
- static final String EXTRA_PARTICIPANT_NAME = "participantName";
20
- static final String EXTRA_CAMERA_OFF = "cameraOff";
21
- private static final String CHANNEL_ID = "chalk_space_background";
27
+ private static final String TAG = "ChalkCallService";
28
+ private static final String CHANNEL_ID = "chalk_call_background";
22
29
  private static final int NOTIFICATION_ID = 19487;
23
30
 
31
+ // Main thread only, like the service's own callbacks. Android crashes the app when a service started
32
+ // with startForegroundService() stops before it calls startForeground(), so nothing outside the service
33
+ // stops it: a stop asks the live service to stop through stopSelfResult(), which does nothing while a
34
+ // newer start is still on its way, and every delivered start promotes first, then stops if the call is over.
35
+ private static boolean wanted;
36
+ private static ChalkSpaceForegroundService live;
37
+ private int lastStartId = NO_START;
38
+ private static final int NO_START = -1;
39
+
40
+ /** Asks for the service on the main thread. Returns false when nothing is granted or Android refuses the start. */
41
+ static boolean requestStart(Context context) {
42
+ if (grantedForegroundTypes(context) == 0) {
43
+ return false;
44
+ }
45
+ wanted = true;
46
+ Intent intent = new Intent(context, ChalkSpaceForegroundService.class);
47
+ try {
48
+ ComponentName started = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? context.startForegroundService(intent) : context.startService(intent);
49
+ return started != null;
50
+ } catch (RuntimeException error) {
51
+ Log.w(TAG, "Couldn't start the call's foreground service", error);
52
+ return false;
53
+ }
54
+ }
55
+
56
+ /** Stops the service on the main thread once its latest start has promoted it. */
57
+ static void requestStop() {
58
+ wanted = false;
59
+ if (live != null && live.lastStartId != NO_START) {
60
+ live.stopSelfResult(live.lastStartId);
61
+ }
62
+ }
63
+
64
+ /** The foreground types the person has granted: microphone and camera, or 0 when neither is granted. */
65
+ static int grantedForegroundTypes(Context context) {
66
+ int types = 0;
67
+ if (isGranted(context, Manifest.permission.RECORD_AUDIO)) {
68
+ types |= ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
69
+ }
70
+ if (isGranted(context, Manifest.permission.CAMERA)) {
71
+ types |= ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
72
+ }
73
+ return types;
74
+ }
75
+
76
+ private static boolean isGranted(Context context, String permission) {
77
+ return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
78
+ }
79
+
24
80
  @Override
25
81
  public IBinder onBind(Intent intent) {
26
82
  return null;
27
83
  }
28
84
 
85
+ @Override
86
+ public void onCreate() {
87
+ super.onCreate();
88
+ live = this;
89
+ }
90
+
29
91
  @Override
30
92
  public int onStartCommand(Intent intent, int flags, int startId) {
31
- String action = intent != null ? intent.getAction() : null;
32
- if (ACTION_STOP.equals(action)) {
33
- stopForeground(STOP_FOREGROUND_REMOVE);
34
- stopSelf();
93
+ lastStartId = startId;
94
+ int foregroundTypes = grantedForegroundTypes(this);
95
+ if (foregroundTypes == 0) {
96
+ stopSelfResult(startId);
35
97
  return START_NOT_STICKY;
36
98
  }
37
99
 
38
100
  ensureNotificationChannel();
39
-
40
- String spaceName = intent != null ? intent.getStringExtra(EXTRA_SPACE_NAME) : null;
41
- String participantName = intent != null ? intent.getStringExtra(EXTRA_PARTICIPANT_NAME) : null;
42
- boolean cameraOff = intent != null && intent.getBooleanExtra(EXTRA_CAMERA_OFF, false);
43
- Notification notification = buildNotification(spaceName, participantName, cameraOff);
101
+ Notification notification = buildNotification();
44
102
 
45
103
  try {
46
104
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
47
- int foregroundType = ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
48
- if (!cameraOff) {
49
- foregroundType |= ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
50
- }
51
- startForeground(NOTIFICATION_ID, notification, foregroundType);
105
+ startForeground(NOTIFICATION_ID, notification, foregroundTypes);
52
106
  } else {
53
107
  startForeground(NOTIFICATION_ID, notification);
54
108
  }
55
109
  } catch (RuntimeException error) {
56
- stopSelf();
110
+ Log.w(TAG, "Couldn't start the call's foreground service", error);
111
+ stopSelfResult(startId);
112
+ return START_NOT_STICKY;
113
+ }
114
+
115
+ if (!wanted) {
116
+ stopSelfResult(startId);
57
117
  }
58
118
 
59
- return START_STICKY;
119
+ // Not sticky: a call can't resume after the process is killed, so a restart would leave a notification with no call behind it.
120
+ return START_NOT_STICKY;
60
121
  }
61
122
 
62
- private Notification buildNotification(String spaceName, String participantName, boolean cameraOff) {
63
- String title = spaceName != null && !spaceName.trim().isEmpty() ? spaceName.trim() : "Chalk Space in progress";
64
- String subtitle = participantName != null && !participantName.trim().isEmpty() ? participantName.trim() : "Your Space stays live in the background";
65
- String detail = cameraOff ? "Audio stays live while you multitask." : "Video and audio stay live while you multitask.";
123
+ @Override
124
+ public void onDestroy() {
125
+ if (live == this) {
126
+ live = null;
127
+ }
128
+ stopForeground(STOP_FOREGROUND_REMOVE);
129
+ super.onDestroy();
130
+ }
66
131
 
132
+ private Notification buildNotification() {
67
133
  return new NotificationCompat.Builder(this, CHANNEL_ID)
68
134
  .setCategory(NotificationCompat.CATEGORY_CALL)
69
- .setContentTitle(title)
70
- .setContentText(subtitle)
71
- .setStyle(new NotificationCompat.BigTextStyle().bigText(detail))
135
+ .setContentTitle("Chalk call in progress")
136
+ .setContentText("Tap to return to the call")
137
+ .setContentIntent(openAppIntent())
72
138
  .setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
73
139
  .setOngoing(true)
74
140
  .setOnlyAlertOnce(true)
@@ -77,6 +143,14 @@ public class ChalkSpaceForegroundService extends Service {
77
143
  .build();
78
144
  }
79
145
 
146
+ private PendingIntent openAppIntent() {
147
+ Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName());
148
+ if (launch == null) {
149
+ return null;
150
+ }
151
+ return PendingIntent.getActivity(this, 0, launch, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
152
+ }
153
+
80
154
  private void ensureNotificationChannel() {
81
155
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
82
156
  return;
@@ -87,8 +161,8 @@ public class ChalkSpaceForegroundService extends Service {
87
161
  return;
88
162
  }
89
163
 
90
- NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Chalk background Space", NotificationManager.IMPORTANCE_LOW);
91
- channel.setDescription("Keeps Chalk Spaces active while the app is in the background");
164
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Chalk call", NotificationManager.IMPORTANCE_LOW);
165
+ channel.setDescription("Keeps the microphone and camera on while Chalk is in the background");
92
166
  manager.createNotificationChannel(channel);
93
167
  }
94
168
  }
@@ -9,6 +9,8 @@ class ChalkAndroidConnectionServicePackage : ReactPackage {
9
9
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
10
10
  return listOf(
11
11
  ChalkAndroidConnectionServiceModule(reactContext),
12
+ ChalkAudioRouteModule(reactContext),
13
+ ChalkCallServiceModule(reactContext),
12
14
  )
13
15
  }
14
16
 
@@ -0,0 +1,138 @@
1
+ package ai.q9labs.chalk.reactnative
2
+
3
+ import android.content.Context
4
+ import android.media.AudioDeviceCallback
5
+ import android.media.AudioDeviceInfo
6
+ import android.media.AudioManager
7
+ import android.os.Build
8
+ import android.os.Handler
9
+ import android.os.Looper
10
+ import com.facebook.react.bridge.Arguments
11
+ import com.facebook.react.bridge.Promise
12
+ import com.facebook.react.bridge.ReactApplicationContext
13
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
14
+ import com.facebook.react.bridge.ReactMethod
15
+ import com.facebook.react.bridge.WritableMap
16
+ import com.facebook.react.modules.core.DeviceEventManagerModule
17
+
18
+ /**
19
+ * Lists the call's audio outputs and switches between them. Android 12 and later pick any
20
+ * communication device (earpiece, speaker, wired or Bluetooth headset); older versions switch
21
+ * only between the earpiece and the speaker.
22
+ */
23
+ class ChalkAudioRouteModule(
24
+ private val reactContext: ReactApplicationContext,
25
+ ) : ReactContextBaseJavaModule(reactContext) {
26
+ private val audioManager = reactContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
27
+ private val handler = Handler(Looper.getMainLooper())
28
+ private var listening = false
29
+
30
+ private val deviceCallback = object : AudioDeviceCallback() {
31
+ override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>) = emit()
32
+ override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) = emit()
33
+ }
34
+ // Created only on Android 12 and later, where the listener type exists.
35
+ private val communicationListener by lazy { AudioManager.OnCommunicationDeviceChangedListener { emit() } }
36
+
37
+ override fun getName(): String = "ChalkAudioRouteModule"
38
+
39
+ override fun getConstants(): Map<String, Any> = mapOf("eventName" to EVENT_NAME)
40
+
41
+ @ReactMethod
42
+ fun addListener(eventName: String) {
43
+ if (listening) return
44
+ listening = true
45
+ audioManager.registerAudioDeviceCallback(deviceCallback, handler)
46
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
47
+ audioManager.addOnCommunicationDeviceChangedListener(reactContext.mainExecutor, communicationListener)
48
+ }
49
+ }
50
+
51
+ @ReactMethod
52
+ fun removeListeners(count: Int) {
53
+ // The listeners stay until the module goes away; NativeEventEmitter needs this method.
54
+ }
55
+
56
+ override fun invalidate() {
57
+ if (listening) {
58
+ audioManager.unregisterAudioDeviceCallback(deviceCallback)
59
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
60
+ audioManager.removeOnCommunicationDeviceChangedListener(communicationListener)
61
+ }
62
+ }
63
+ super.invalidate()
64
+ }
65
+
66
+ @ReactMethod
67
+ fun getRoutes(promise: Promise) {
68
+ promise.resolve(snapshot())
69
+ }
70
+
71
+ @ReactMethod
72
+ fun selectRoute(id: String, promise: Promise) {
73
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
74
+ val device = audioManager.availableCommunicationDevices.firstOrNull { routeId(it) == id }
75
+ if (device == null || !audioManager.setCommunicationDevice(device)) {
76
+ promise.reject("audio_route_failed", "Couldn't switch the audio output to $id.")
77
+ return
78
+ }
79
+ } else {
80
+ @Suppress("DEPRECATION")
81
+ audioManager.isSpeakerphoneOn = id == SPEAKER
82
+ }
83
+ promise.resolve(snapshot())
84
+ }
85
+
86
+ private fun emit() {
87
+ if (!reactContext.hasActiveReactInstance()) return
88
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java).emit(EVENT_NAME, snapshot())
89
+ }
90
+
91
+ private fun snapshot(): WritableMap {
92
+ val routes = Arguments.createArray()
93
+ val result = Arguments.createMap()
94
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
95
+ for (device in audioManager.availableCommunicationDevices) {
96
+ val kind = kindOf(device.type) ?: continue
97
+ routes.pushMap(route(routeId(device), kind, if (kind == "bluetooth" || kind == "wired") device.productName.toString() else ""))
98
+ }
99
+ result.putString("selected", audioManager.communicationDevice?.let { routeId(it) } ?: EARPIECE)
100
+ } else {
101
+ routes.pushMap(route(EARPIECE, EARPIECE, ""))
102
+ routes.pushMap(route(SPEAKER, SPEAKER, ""))
103
+ @Suppress("DEPRECATION")
104
+ result.putString("selected", if (audioManager.isSpeakerphoneOn) SPEAKER else EARPIECE)
105
+ }
106
+ result.putArray("routes", routes)
107
+ return result
108
+ }
109
+
110
+ private fun route(id: String, kind: String, name: String): WritableMap =
111
+ Arguments.createMap().apply {
112
+ putString("id", id)
113
+ putString("kind", kind)
114
+ putString("name", name)
115
+ }
116
+
117
+ private fun routeId(device: AudioDeviceInfo): String =
118
+ when (device.type) {
119
+ AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> EARPIECE
120
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> SPEAKER
121
+ else -> device.id.toString()
122
+ }
123
+
124
+ private fun kindOf(type: Int): String? =
125
+ when (type) {
126
+ AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> EARPIECE
127
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> SPEAKER
128
+ AudioDeviceInfo.TYPE_BLUETOOTH_SCO, AudioDeviceInfo.TYPE_BLE_HEADSET -> "bluetooth"
129
+ AudioDeviceInfo.TYPE_WIRED_HEADSET, AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_USB_HEADSET -> "wired"
130
+ else -> null
131
+ }
132
+
133
+ private companion object {
134
+ const val EVENT_NAME = "ChalkAudioRouteChanged"
135
+ const val EARPIECE = "earpiece"
136
+ const val SPEAKER = "speaker"
137
+ }
138
+ }
@@ -0,0 +1,32 @@
1
+ package ai.q9labs.chalk.reactnative
2
+
3
+ import android.os.Handler
4
+ import android.os.Looper
5
+ import com.facebook.react.bridge.Promise
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
8
+ import com.facebook.react.bridge.ReactMethod
9
+
10
+ /** Starts and stops the foreground service that keeps a call's microphone and camera working in the background. */
11
+ class ChalkCallServiceModule(
12
+ private val reactContext: ReactApplicationContext,
13
+ ) : ReactContextBaseJavaModule(reactContext) {
14
+ override fun getName(): String = "ChalkCallService"
15
+
16
+ /** Resolves false when the person hasn't granted the microphone or camera, or when Android refuses the start. The call continues either way. */
17
+ @ReactMethod
18
+ fun start(promise: Promise) {
19
+ // The service keeps its start and stop state on the main thread, where its own callbacks run.
20
+ mainThread.post { promise.resolve(ChalkSpaceForegroundService.requestStart(reactContext)) }
21
+ }
22
+
23
+ @ReactMethod
24
+ fun stop(promise: Promise) {
25
+ mainThread.post {
26
+ ChalkSpaceForegroundService.requestStop()
27
+ promise.resolve(null)
28
+ }
29
+ }
30
+
31
+ private val mainThread = Handler(Looper.getMainLooper())
32
+ }
@@ -0,0 +1,4 @@
1
+ /** Starts the Android foreground service for the call. Resolves false when there's nothing to keep running (no microphone or camera permission) or Android refused the start. */
2
+ export declare function startAndroidCallService(): Promise<boolean>;
3
+ export declare function stopAndroidCallService(): Promise<void>;
4
+ //# sourceMappingURL=call-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-service.d.ts","sourceRoot":"","sources":["../../src/android/call-service.ts"],"names":[],"mappings":"AASA,iLAAiL;AACjL,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC,CAGhE;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG5D"}
@@ -0,0 +1,19 @@
1
+ import { type SharedValue } from "react-native-reanimated";
2
+ export type FaceAvatarProps = {
3
+ readonly name: string;
4
+ readonly size: number;
5
+ /** `bold` is the 3D style for tiles; `subtle` is for rows, pills, chat and toasts. */
6
+ readonly style?: "bold" | "subtle";
7
+ /** Live speaking level from 0 to 1. While it moves, the face bobs and the mouth opens. */
8
+ readonly level?: SharedValue<number>;
9
+ /** Eyes drift on their own every 1.8 s, as on the mockup's touch devices. Off for small avatars. */
10
+ readonly lookAround?: boolean;
11
+ readonly testID?: string;
12
+ };
13
+ /**
14
+ * A Facehash avatar drawn natively. The face blinks on its own rhythm, reacts to the speaking
15
+ * level, and turns to the front for a moment when touched. All motion runs on the UI thread and
16
+ * stops with reduced motion. Decorative: the parent names the person.
17
+ */
18
+ export declare const FaceAvatar: import("react").MemoExoticComponent<({ name, size, style, level, lookAround, testID }: FaceAvatarProps) => React.JSX.Element>;
19
+ //# sourceMappingURL=FaceAvatar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FaceAvatar.d.ts","sourceRoot":"","sources":["../../src/avatar/FaceAvatar.tsx"],"names":[],"mappings":"AAGA,OAAiB,EAAwH,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAK3L,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,oGAAoG;IACpG,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAWF;;;;GAIG;AACH,eAAO,MAAM,UAAU,yFAAiG,eAAe,KAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAwGzJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** A camera-off tile's avatar is 42 % of the tile's shorter side, between 32 and 150 pt. */
2
+ export declare function tileAvatarSize(width: number, height: number): number;
3
+ //# sourceMappingURL=tile-avatar-size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-avatar-size.d.ts","sourceRoot":"","sources":["../../src/avatar/tile-avatar-size.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpE"}