@q9labsai/chalk-react-native 4.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 (654) hide show
  1. package/Q9ChalkReactNative.podspec +27 -0
  2. package/README.md +41 -0
  3. package/android/build.gradle +43 -0
  4. package/android/consumer-rules.pro +1 -0
  5. package/android/src/main/AndroidManifest.xml +24 -0
  6. package/android/src/main/java/ai/q9labs/chalk/reactnative/ChalkSpaceForegroundService.java +94 -0
  7. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAndroidConnectionServiceModule.kt +161 -0
  8. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAndroidConnectionServicePackage.kt +18 -0
  9. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkConnectionRegistry.kt +120 -0
  10. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkSelfManagedConnection.kt +64 -0
  11. package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkSelfManagedConnectionService.kt +35 -0
  12. package/dist/android/connection-service.d.ts +26 -0
  13. package/dist/android/connection-service.d.ts.map +1 -0
  14. package/dist/android.d.ts +2 -0
  15. package/dist/android.d.ts.map +1 -0
  16. package/dist/android.js +47 -0
  17. package/dist/callkit/callkit.d.ts +61 -0
  18. package/dist/callkit/callkit.d.ts.map +1 -0
  19. package/dist/callkit/resolve-space-callkit-options.d.ts +17 -0
  20. package/dist/callkit/resolve-space-callkit-options.d.ts.map +1 -0
  21. package/dist/chunk-BXIZIHIO.js +4501 -0
  22. package/dist/chunk-F3NPRVHO.js +121 -0
  23. package/dist/chunk-HXYIJ75K.js +394 -0
  24. package/dist/chunk-IMKSYT7R.js +653 -0
  25. package/dist/chunk-JB4LNWVP.js +247 -0
  26. package/dist/client.d.ts +8 -0
  27. package/dist/client.d.ts.map +1 -0
  28. package/dist/client.js +6 -0
  29. package/dist/clipboard-store.d.ts +17 -0
  30. package/dist/clipboard-store.d.ts.map +1 -0
  31. package/dist/clipboard.d.ts +10 -0
  32. package/dist/clipboard.d.ts.map +1 -0
  33. package/dist/clipboard.js +108 -0
  34. package/dist/components/Chalk.d.ts +77 -0
  35. package/dist/components/Chalk.d.ts.map +1 -0
  36. package/dist/components/ChatMessageList.d.ts +11 -0
  37. package/dist/components/ChatMessageList.d.ts.map +1 -0
  38. package/dist/components/EmbeddedWhiteboard.d.ts +46 -0
  39. package/dist/components/EmbeddedWhiteboard.d.ts.map +1 -0
  40. package/dist/components/Entrance.d.ts +22 -0
  41. package/dist/components/Entrance.d.ts.map +1 -0
  42. package/dist/components/EntranceView.android.d.ts +4 -0
  43. package/dist/components/EntranceView.android.d.ts.map +1 -0
  44. package/dist/components/EntranceView.d.ts +18 -0
  45. package/dist/components/EntranceView.d.ts.map +1 -0
  46. package/dist/components/EntranceView.ios-pad.d.ts +3 -0
  47. package/dist/components/EntranceView.ios-pad.d.ts.map +1 -0
  48. package/dist/components/EntranceView.ios-phone.d.ts +3 -0
  49. package/dist/components/EntranceView.ios-phone.d.ts.map +1 -0
  50. package/dist/components/EntranceView.macos.d.ts +4 -0
  51. package/dist/components/EntranceView.macos.d.ts.map +1 -0
  52. package/dist/components/FaceAvatar.d.ts +16 -0
  53. package/dist/components/FaceAvatar.d.ts.map +1 -0
  54. package/dist/components/GradientSurface.d.ts +14 -0
  55. package/dist/components/GradientSurface.d.ts.map +1 -0
  56. package/dist/components/LogoElements.d.ts +6 -0
  57. package/dist/components/LogoElements.d.ts.map +1 -0
  58. package/dist/components/MediaView.d.ts +14 -0
  59. package/dist/components/MediaView.d.ts.map +1 -0
  60. package/dist/components/ReactionPicker.d.ts +10 -0
  61. package/dist/components/ReactionPicker.d.ts.map +1 -0
  62. package/dist/components/RtcVideoView.d.ts +4 -0
  63. package/dist/components/RtcVideoView.d.ts.map +1 -0
  64. package/dist/components/SpaceView.android.d.ts +2 -0
  65. package/dist/components/SpaceView.android.d.ts.map +1 -0
  66. package/dist/components/SpaceView.d.ts +31 -0
  67. package/dist/components/SpaceView.d.ts.map +1 -0
  68. package/dist/components/SpaceView.ios-pad.d.ts +2 -0
  69. package/dist/components/SpaceView.ios-pad.d.ts.map +1 -0
  70. package/dist/components/SpaceView.ios-phone.d.ts +2 -0
  71. package/dist/components/SpaceView.ios-phone.d.ts.map +1 -0
  72. package/dist/components/SpaceView.macos.d.ts +2 -0
  73. package/dist/components/SpaceView.macos.d.ts.map +1 -0
  74. package/dist/components/SpaceView.shared.d.ts +3 -0
  75. package/dist/components/SpaceView.shared.d.ts.map +1 -0
  76. package/dist/components/android-connection-service-controller.d.ts +33 -0
  77. package/dist/components/android-connection-service-controller.d.ts.map +1 -0
  78. package/dist/components/episode-diagnostic-render-observer.d.ts +2 -0
  79. package/dist/components/episode-diagnostic-render-observer.d.ts.map +1 -0
  80. package/dist/components/native-animation-controller.d.ts +7 -0
  81. package/dist/components/native-animation-controller.d.ts.map +1 -0
  82. package/dist/components/native-chat.d.ts +8 -0
  83. package/dist/components/native-chat.d.ts.map +1 -0
  84. package/dist/components/native-entrance/entrance-controller-store.d.ts +34 -0
  85. package/dist/components/native-entrance/entrance-controller-store.d.ts.map +1 -0
  86. package/dist/components/native-entrance/useEntranceController.d.ts +19 -0
  87. package/dist/components/native-entrance/useEntranceController.d.ts.map +1 -0
  88. package/dist/components/native-joining-loading-animation.d.ts +9 -0
  89. package/dist/components/native-joining-loading-animation.d.ts.map +1 -0
  90. package/dist/components/native-media-visibility.d.ts +8 -0
  91. package/dist/components/native-media-visibility.d.ts.map +1 -0
  92. package/dist/components/native-space-callkit-controller.d.ts +39 -0
  93. package/dist/components/native-space-callkit-controller.d.ts.map +1 -0
  94. package/dist/components/native-space-view/AppearanceSettings.d.ts +2 -0
  95. package/dist/components/native-space-view/AppearanceSettings.d.ts.map +1 -0
  96. package/dist/components/native-space-view/ParticipantActionSheet.d.ts +9 -0
  97. package/dist/components/native-space-view/ParticipantActionSheet.d.ts.map +1 -0
  98. package/dist/components/native-space-view/SettingsSheet.d.ts +7 -0
  99. package/dist/components/native-space-view/SettingsSheet.d.ts.map +1 -0
  100. package/dist/components/native-space-view/SpaceActionMenu.d.ts +8 -0
  101. package/dist/components/native-space-view/SpaceActionMenu.d.ts.map +1 -0
  102. package/dist/components/native-space-view/SpaceBottomDock.android.d.ts +4 -0
  103. package/dist/components/native-space-view/SpaceBottomDock.android.d.ts.map +1 -0
  104. package/dist/components/native-space-view/SpaceChatSheet.d.ts +5 -0
  105. package/dist/components/native-space-view/SpaceChatSheet.d.ts.map +1 -0
  106. package/dist/components/native-space-view/SpaceGrid.android.d.ts +8 -0
  107. package/dist/components/native-space-view/SpaceGrid.android.d.ts.map +1 -0
  108. package/dist/components/native-space-view/SpaceMoreSheet.d.ts +6 -0
  109. package/dist/components/native-space-view/SpaceMoreSheet.d.ts.map +1 -0
  110. package/dist/components/native-space-view/SpacePanelSheet.d.ts +5 -0
  111. package/dist/components/native-space-view/SpacePanelSheet.d.ts.map +1 -0
  112. package/dist/components/native-space-view/SpacePeopleSheet.d.ts +5 -0
  113. package/dist/components/native-space-view/SpacePeopleSheet.d.ts.map +1 -0
  114. package/dist/components/native-space-view/SpaceStage.android.d.ts +29 -0
  115. package/dist/components/native-space-view/SpaceStage.android.d.ts.map +1 -0
  116. package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts +30 -0
  117. package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts.map +1 -0
  118. package/dist/components/native-space-view/SpaceTopBar.android.d.ts +9 -0
  119. package/dist/components/native-space-view/SpaceTopBar.android.d.ts.map +1 -0
  120. package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts +15 -0
  121. package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts.map +1 -0
  122. package/dist/components/native-space-view/diagnostics.d.ts +48 -0
  123. package/dist/components/native-space-view/diagnostics.d.ts.map +1 -0
  124. package/dist/components/native-space-view/format-space-duration.d.ts +2 -0
  125. package/dist/components/native-space-view/format-space-duration.d.ts.map +1 -0
  126. package/dist/components/native-space-view/native-space-grid-keys.d.ts +3 -0
  127. package/dist/components/native-space-view/native-space-grid-keys.d.ts.map +1 -0
  128. package/dist/components/native-space-view/native-space-page-store.d.ts +8 -0
  129. package/dist/components/native-space-view/native-space-page-store.d.ts.map +1 -0
  130. package/dist/components/native-space-view/screen-share-availability.d.ts +9 -0
  131. package/dist/components/native-space-view/screen-share-availability.d.ts.map +1 -0
  132. package/dist/components/native-space-view/space-chat-attachments.d.ts +15 -0
  133. package/dist/components/native-space-view/space-chat-attachments.d.ts.map +1 -0
  134. package/dist/components/native-space-view/space-panel-layout.d.ts +10 -0
  135. package/dist/components/native-space-view/space-panel-layout.d.ts.map +1 -0
  136. package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts +16 -0
  137. package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts.map +1 -0
  138. package/dist/components/native-space-view/space-progressive-surface-types.d.ts +3 -0
  139. package/dist/components/native-space-view/space-progressive-surface-types.d.ts.map +1 -0
  140. package/dist/components/native-space-view/types.d.ts +24 -0
  141. package/dist/components/native-space-view/types.d.ts.map +1 -0
  142. package/dist/components/native-space-view/useSpaceViewController.contract.d.ts +41 -0
  143. package/dist/components/native-space-view/useSpaceViewController.contract.d.ts.map +1 -0
  144. package/dist/components/native-space-view/useSpaceViewController.d.ts +150 -0
  145. package/dist/components/native-space-view/useSpaceViewController.d.ts.map +1 -0
  146. package/dist/components/native-space-view/useSpaceViewDerived.d.ts +12 -0
  147. package/dist/components/native-space-view/useSpaceViewDerived.d.ts.map +1 -0
  148. package/dist/components/native-space-view/useSpaceViewPanels.d.ts +70 -0
  149. package/dist/components/native-space-view/useSpaceViewPanels.d.ts.map +1 -0
  150. package/dist/components/rtc-video-view-availability.d.ts +13 -0
  151. package/dist/components/rtc-video-view-availability.d.ts.map +1 -0
  152. package/dist/components/space-lifecycle.d.ts +3 -0
  153. package/dist/components/space-lifecycle.d.ts.map +1 -0
  154. package/dist/components/useAndroidConnectionService.d.ts +14 -0
  155. package/dist/components/useAndroidConnectionService.d.ts.map +1 -0
  156. package/dist/context/space-client-context.d.ts +9 -0
  157. package/dist/context/space-client-context.d.ts.map +1 -0
  158. package/dist/diagnostics.d.ts +50 -0
  159. package/dist/diagnostics.d.ts.map +1 -0
  160. package/dist/diagnostics.js +143 -0
  161. package/dist/hooks/entrance-preview-store.d.ts +16 -0
  162. package/dist/hooks/entrance-preview-store.d.ts.map +1 -0
  163. package/dist/hooks/external-store.d.ts +10 -0
  164. package/dist/hooks/external-store.d.ts.map +1 -0
  165. package/dist/hooks/space-hooks.d.ts +10 -0
  166. package/dist/hooks/space-hooks.d.ts.map +1 -0
  167. package/dist/hooks/useEntrancePreview.d.ts +7 -0
  168. package/dist/hooks/useEntrancePreview.d.ts.map +1 -0
  169. package/dist/hooks/useLayout.d.ts +16 -0
  170. package/dist/hooks/useLayout.d.ts.map +1 -0
  171. package/dist/hooks/usePanels.d.ts +12 -0
  172. package/dist/hooks/usePanels.d.ts.map +1 -0
  173. package/dist/index.d.ts +11 -0
  174. package/dist/index.d.ts.map +1 -0
  175. package/dist/index.js +47 -0
  176. package/dist/invites.d.ts +3 -0
  177. package/dist/invites.d.ts.map +1 -0
  178. package/dist/invites.js +41 -0
  179. package/dist/ios-pad.d.ts +2 -0
  180. package/dist/ios-pad.d.ts.map +1 -0
  181. package/dist/ios-pad.js +47 -0
  182. package/dist/ios-phone.d.ts +2 -0
  183. package/dist/ios-phone.d.ts.map +1 -0
  184. package/dist/ios-phone.js +47 -0
  185. package/dist/ios.d.ts +2 -0
  186. package/dist/ios.d.ts.map +1 -0
  187. package/dist/ios.js +47 -0
  188. package/dist/macos.d.ts +2 -0
  189. package/dist/macos.d.ts.map +1 -0
  190. package/dist/macos.js +47 -0
  191. package/dist/media/native-webrtc.d.ts +6 -0
  192. package/dist/media/native-webrtc.d.ts.map +1 -0
  193. package/dist/platform/platform.d.ts +3 -0
  194. package/dist/platform/platform.d.ts.map +1 -0
  195. package/dist/runtime.d.ts +38 -0
  196. package/dist/runtime.d.ts.map +1 -0
  197. package/dist/runtime.js +30 -0
  198. package/dist/space-client/create-native-space-client.d.ts +17 -0
  199. package/dist/space-client/create-native-space-client.d.ts.map +1 -0
  200. package/dist/telemetry.d.ts +63 -0
  201. package/dist/telemetry.d.ts.map +1 -0
  202. package/dist/test-support/test-renderer.d.ts +20 -0
  203. package/dist/test-support/test-renderer.d.ts.map +1 -0
  204. package/dist/ui/appearance.d.ts +239 -0
  205. package/dist/ui/appearance.d.ts.map +1 -0
  206. package/dist/ui/appearance.js +14 -0
  207. package/dist/ui/native-appearance-context.d.ts +15 -0
  208. package/dist/ui/native-appearance-context.d.ts.map +1 -0
  209. package/dist/ui/native-theme.d.ts +17 -0
  210. package/dist/ui/native-theme.d.ts.map +1 -0
  211. package/dist/ui/native-types.d.ts +38 -0
  212. package/dist/ui/native-types.d.ts.map +1 -0
  213. package/dist/ui/participant-avatar.d.ts +21 -0
  214. package/dist/ui/participant-avatar.d.ts.map +1 -0
  215. package/dist/ui/theme-tokens.d.ts +25 -0
  216. package/dist/ui/theme-tokens.d.ts.map +1 -0
  217. package/dist/ui/theme.d.ts +404 -0
  218. package/dist/ui/theme.d.ts.map +1 -0
  219. package/dist/ui/theme.js +8 -0
  220. package/dist/utils/build-chalk-invite-link.d.ts +2 -0
  221. package/dist/utils/build-chalk-invite-link.d.ts.map +1 -0
  222. package/dist/utils/ios-simulator.d.ts +5 -0
  223. package/dist/utils/ios-simulator.d.ts.map +1 -0
  224. package/dist/utils/native-space-layout.d.ts +42 -0
  225. package/dist/utils/native-space-layout.d.ts.map +1 -0
  226. package/dist/whiteboard/embedded-whiteboard-assets.d.ts +7 -0
  227. package/dist/whiteboard/embedded-whiteboard-assets.d.ts.map +1 -0
  228. package/embedded/chalk-whiteboard/THIRD_PARTY_NOTICES.json +17 -0
  229. package/embedded/chalk-whiteboard/asset-manifest.json +1228 -0
  230. package/embedded/chalk-whiteboard/chalk.css +5 -0
  231. package/embedded/chalk-whiteboard/compatibility-manifest.json +37 -0
  232. package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Bold.woff2 +0 -0
  233. package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Medium.woff2 +0 -0
  234. package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Regular.woff2 +0 -0
  235. package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-SemiBold.woff2 +0 -0
  236. package/embedded/chalk-whiteboard/fonts/Cascadia/CascadiaCode-Regular.woff2 +0 -0
  237. package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2 +0 -0
  238. package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2 +0 -0
  239. package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2 +0 -0
  240. package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2 +0 -0
  241. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2 +0 -0
  242. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2 +0 -0
  243. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2 +0 -0
  244. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2 +0 -0
  245. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 +0 -0
  246. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2 +0 -0
  247. package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2 +0 -0
  248. package/embedded/chalk-whiteboard/fonts/Liberation/LiberationSans-Regular.woff2 +0 -0
  249. package/embedded/chalk-whiteboard/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2 +0 -0
  250. package/embedded/chalk-whiteboard/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2 +0 -0
  251. package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2 +0 -0
  252. package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2 +0 -0
  253. package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2 +0 -0
  254. package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2 +0 -0
  255. package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2 +0 -0
  256. package/embedded/chalk-whiteboard/fonts/Virgil/Virgil-Regular.woff2 +0 -0
  257. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2 +0 -0
  258. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2 +0 -0
  259. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2 +0 -0
  260. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2 +0 -0
  261. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2 +0 -0
  262. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2 +0 -0
  263. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2 +0 -0
  264. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2 +0 -0
  265. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0986d134c05864f5025962eef9f994a0.woff2 +0 -0
  266. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0b5d723fdc4e249c140f0909e87d03b4.woff2 +0 -0
  267. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0f626226ba1272e832aea87bafd9720e.woff2 +0 -0
  268. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0f7fb1e0d5015bb1371343153ecf7ce3.woff2 +0 -0
  269. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0fa55a080fcd0f9dc2e0b0058b793df8.woff2 +0 -0
  270. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0facdf1ea213ba40261022f5d5ed4493.woff2 +0 -0
  271. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-10a7ae9a371830a80c3d844acf1c02d7.woff2 +0 -0
  272. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-112c051027b2d766c19a519f6ee1f4f7.woff2 +0 -0
  273. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-11c345711937f0ba4b8f7b6b919c8440.woff2 +0 -0
  274. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-12b52b58eb3df36804b9a654ec9ee194.woff2 +0 -0
  275. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-13ae07ed2e272d26d59bc0691cd7117a.woff2 +0 -0
  276. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-13d2887ec8ee73c43acdabc52a05af7b.woff2 +0 -0
  277. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-145aa02cdd91946e67dc934e1acffe75.woff2 +0 -0
  278. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-15dc6d811c9cd078f9086a740d5a1038.woff2 +0 -0
  279. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-173945821411c09f70c95f98d590e697.woff2 +0 -0
  280. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1b611157cd46bb184d4fa4dae2d6a2b8.woff2 +0 -0
  281. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1e6fd68f1f3902ce48ce8c69df385622.woff2 +0 -0
  282. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1ee544f0f1dac422545c505baa788992.woff2 +0 -0
  283. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1fdc0c67ed57263a80fd108c1f6ccf24.woff2 +0 -0
  284. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-203b0e569e3b14aac86a003dc3fa523e.woff2 +0 -0
  285. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-20cc1bbf50e7efb442756cb605672c1f.woff2 +0 -0
  286. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-20e7bf72fa05de9adf7dbcc7bf51dde6.woff2 +0 -0
  287. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-21430ee05a1248901da8d0de08744d47.woff2 +0 -0
  288. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23686f7f29da6e8008c36dd3a80c83d6.woff2 +0 -0
  289. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23ad2d71b280f00b1363b95b7bea94eb.woff2 +0 -0
  290. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23f228f3999c01983860012330e4be08.woff2 +0 -0
  291. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-24476a126f129212beb33f66853ea151.woff2 +0 -0
  292. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-24a21c1e4449222e8d1898d69ff3a404.woff2 +0 -0
  293. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-25b7f38e18f035f96cb5e547bd2bd08c.woff2 +0 -0
  294. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-29cec36cd205b211da97acabaa62f055.woff2 +0 -0
  295. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2a26d20a23b00898ce82f09d2ee47c3f.woff2 +0 -0
  296. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2adbc89c11e65905393d3dfc468b9d5b.woff2 +0 -0
  297. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2b7441d46298788ac94e610ffcc709b6.woff2 +0 -0
  298. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2b77e8ebfb2367ab2662396a60e7d320.woff2 +0 -0
  299. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2cf96d082d35ea3d8106851223ad0d16.woff2 +0 -0
  300. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2d43040e86ff03ba677f6f9c04cd0805.woff2 +0 -0
  301. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2e33e8dc771ef5e1d9127d60a6b73679.woff2 +0 -0
  302. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-33432927cd87d40cfe393c7482bf221f.woff2 +0 -0
  303. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-353f33792a8f60dc69323ddf635a269e.woff2 +0 -0
  304. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-36925dfe329a45086cbb7fc5c20d45ac.woff2 +0 -0
  305. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3717077e38f98d89eae729b6c14e56dc.woff2 +0 -0
  306. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3756e81d3e149cf6099163ee79944fec.woff2 +0 -0
  307. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-395c35dd584b56b0789f58a0559beaf1.woff2 +0 -0
  308. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3c9de2ae0ea4bc91a510942dfa4be8d2.woff2 +0 -0
  309. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3cc70dbb64df5b21f1326cc24dee2195.woff2 +0 -0
  310. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3e1f8f654357353bf0e04ba5c34b5f7f.woff2 +0 -0
  311. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3e63ed8162808a9e425ed80a8bc79114.woff2 +0 -0
  312. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3eaa538115d76932653c21d8dc28f207.woff2 +0 -0
  313. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4095eb84ef3874e2600247bee0b04026.woff2 +0 -0
  314. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2 +0 -0
  315. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-450da755d5bcb70906e1295e559b9602.woff2 +0 -0
  316. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-452225341522a7942f0f6aab1a5c91a3.woff2 +0 -0
  317. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4535823663ad81405188a528d8f2b1a2.woff2 +0 -0
  318. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4806e761d750087c2d734fc64596eaff.woff2 +0 -0
  319. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4a0fdb40036e87b40aa08dd30584cb85.woff2 +0 -0
  320. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4a38cc3e9cf104e69ba246d37f8cf135.woff2 +0 -0
  321. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4aca6a43e59aceee2166b0c7e4e85ef1.woff2 +0 -0
  322. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4bfaa8ffa64c5ee560aa2daba7c9cbd3.woff2 +0 -0
  323. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4dc6d5f188d5c96d44815cd1e81aa885.woff2 +0 -0
  324. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4ddc14ed3eb0c3e46364317dfc0144a3.woff2 +0 -0
  325. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4ee10ae43505e2e0bc62656ced49c0fa.woff2 +0 -0
  326. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4f50e5136e136527280bc902c5817561.woff2 +0 -0
  327. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-51502f1206be09c565f1547c406e9558.woff2 +0 -0
  328. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-51a0e808bbc8361236ac521a119758a3.woff2 +0 -0
  329. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-52a84a22fd1369bffeaf21da2d6158dc.woff2 +0 -0
  330. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5330a2119a716e4e7224ed108b085dac.woff2 +0 -0
  331. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-543fa46ace099a7099dad69123399400.woff2 +0 -0
  332. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2 +0 -0
  333. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-54acdfc2166ad7fcbd074f75fd4a56ba.woff2 +0 -0
  334. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5572b3513ba8df57a3d5d7303ee6b11b.woff2 +0 -0
  335. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-56467a5c8840c4d23a60b2f935114848.woff2 +0 -0
  336. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-56a32a7689abd0326e57c10c6c069bb4.woff2 +0 -0
  337. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-57862b464a55b18c7bf234ce22907d73.woff2 +0 -0
  338. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-583d166e56ba0de4b77eabb47ef67839.woff2 +0 -0
  339. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5882ffa04f32584d26109137e2da4352.woff2 +0 -0
  340. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-58fd02350d0bc52cf1ca3bb32ce9766e.woff2 +0 -0
  341. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5935a5775af3d5c6307ac667bd9ae74e.woff2 +0 -0
  342. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-59e9ff77b0efaf684bc09274fb6908c9.woff2 +0 -0
  343. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a1ce3117cfe90c48e8fb4a9a00f694d.woff2 +0 -0
  344. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a45d991244d4c7140217e1e5f5ca4f4.woff2 +0 -0
  345. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a7fac4b8b23a6e4e5ba0c9bf1756c91.woff2 +0 -0
  346. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5b0ed6971aaab9c8ad563230bd5471a7.woff2 +0 -0
  347. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5d2898fbc097a7e24c6f38d80587621e.woff2 +0 -0
  348. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-603aefd23e350ba7eb124273e3c9bcf1.woff2 +0 -0
  349. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2 +0 -0
  350. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-60a41c7e1c68f22424e6d22df544bc82.woff2 +0 -0
  351. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-642b26e2e5f5fb780b51b593dbc8c851.woff2 +0 -0
  352. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-66493ba5a8367f2928812f446f47b56a.woff2 +0 -0
  353. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-670ba603758d94268e8606f240a42e12.woff2 +0 -0
  354. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-671a2c20b1eb9e4ef8a192833940e319.woff2 +0 -0
  355. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-684d65f1793cac449dde5d59cb3c47fb.woff2 +0 -0
  356. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-69c09cc5fa3e55c74fc4821f76909cc3.woff2 +0 -0
  357. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2 +0 -0
  358. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6e092f71c1e634059ada0e52abadce67.woff2 +0 -0
  359. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6f3256af8454371776bc46670d33cc65.woff2 +0 -0
  360. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2 +0 -0
  361. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-70c2eb8d64e71a42a834eb857ea9df51.woff2 +0 -0
  362. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-70e811fd7994e61f408c923de6ddd078.woff2 +0 -0
  363. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7197d6fda6cba7c3874c53d6381ca239.woff2 +0 -0
  364. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-72252d73220fa3cd856677888cee1635.woff2 +0 -0
  365. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-72536a3d71b694a0d53dd90ddceae41e.woff2 +0 -0
  366. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-726303e0774b4e678bff8c2deb6ca603.woff2 +0 -0
  367. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-733171b4ffcd17ea1fe1c0ba627173bf.woff2 +0 -0
  368. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-739bc1a567439c7cffcd1614644593d2.woff2 +0 -0
  369. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-73e309718fd16cea44b4d54a33581811.woff2 +0 -0
  370. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7494dc504ae00ee9cd0505f990f88c5d.woff2 +0 -0
  371. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-74e2263a91439c25b91d5132ce9f4d62.woff2 +0 -0
  372. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-761d05e3cd968cf574166867998ef06a.woff2 +0 -0
  373. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7718fe60986d8b42b1be9c5ace5ccf25.woff2 +0 -0
  374. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-774d4f764a1299da5d28ec2f2ffe0d69.woff2 +0 -0
  375. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-79d494361ae093b69e74ee9dbe65bfd4.woff2 +0 -0
  376. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-79f007c1c6d07557120982951ea67998.woff2 +0 -0
  377. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7a07ddc0f0c0f5f4a9bad6ee3dda66b5.woff2 +0 -0
  378. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7ab2bed91166a9dca83a5ebfbe2a7f38.woff2 +0 -0
  379. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7ccce86603f80a099ddb0cb21d4ae3e3.woff2 +0 -0
  380. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7e4bde7e9c7f84cd34d8a845e384c746.woff2 +0 -0
  381. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7e929f262f30c8ee78bf398150b1a7cd.woff2 +0 -0
  382. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2 +0 -0
  383. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7f855356ab893b0d2b9c1c83b8116f0e.woff2 +0 -0
  384. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-829615148e6357d826b9242eb7fbbd1e.woff2 +0 -0
  385. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-866fa7613df6b3fd272bcfd4530c0bb9.woff2 +0 -0
  386. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-87599f94b6cc129d505b375798d0d751.woff2 +0 -0
  387. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8c2f33cee3993174f7e87c28e4bf42ee.woff2 +0 -0
  388. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8d3bcabb847b56243b16afe62adaaf21.woff2 +0 -0
  389. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8de5b863cb50dfefdd07cb11c774d579.woff2 +0 -0
  390. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8e9f97f01034820170065b2921b4fb5e.woff2 +0 -0
  391. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8f476c4c99813d57cbe6eca4727388ad.woff2 +0 -0
  392. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-903bb6865f3452e2fda42e3a25547bc5.woff2 +0 -0
  393. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-91ddb2969bf2d31ba02ad82998d1314c.woff2 +0 -0
  394. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-938d90c10ff8c20386af7f242c05d6b0.woff2 +0 -0
  395. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-93fc8f28a33234bcadf1527cafabd502.woff2 +0 -0
  396. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-95429962233afd82db1c27df1500a28c.woff2 +0 -0
  397. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9544732d2e62d1a429674f8ee41b5d3a.woff2 +0 -0
  398. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9592bfc861f07bcb8d75c196b370e548.woff2 +0 -0
  399. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-95bfd249da4902577b4b7d76ebdd0b44.woff2 +0 -0
  400. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-968cffdc8ee679da094e77ebf50f58ef.woff2 +0 -0
  401. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-97f7f48ce90c9429bf32ae51469db74d.woff2 +0 -0
  402. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-982b630266d87db93d2539affb1275c6.woff2 +0 -0
  403. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-98f2ad84457de7f3740d9920b8fa8667.woff2 +0 -0
  404. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-99a16ef6a64934d5781933dbd9c46b2e.woff2 +0 -0
  405. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9cfb2a77a4e45025105ad29a1748b90d.woff2 +0 -0
  406. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9d81066dd2b337c938df6e90380a00dc.woff2 +0 -0
  407. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9eb5a99df4e76ac3363453ac9ca288b1.woff2 +0 -0
  408. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a004ddfcb26e67bd6e678c8ed19e25ce.woff2 +0 -0
  409. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a0ca5df4258213d7fc9fce80f65ce760.woff2 +0 -0
  410. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a1f916d6039285c4ffb900cd654e418f.woff2 +0 -0
  411. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a203b91dad570bf05a58c3c3ddb529bf.woff2 +0 -0
  412. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a365e82ed54697a52f27adcea1315fe8.woff2 +0 -0
  413. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2 +0 -0
  414. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a7accba310e821da5505f71c03b76bdb.woff2 +0 -0
  415. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-aa0d470430e6391eca720c7cfa44446f.woff2 +0 -0
  416. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-aa5c9ca6cf4fba00433b7aa3fa10671a.woff2 +0 -0
  417. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ac9ceb44437becc3e9c4dbfebab7fc2d.woff2 +0 -0
  418. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b1220a3c61f85cc0408deedb4c5f57a2.woff2 +0 -0
  419. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b358f7a51ece39a3247942b1feabdb29.woff2 +0 -0
  420. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b57aaedfd8ebdf3931f25119dc6a5eb2.woff2 +0 -0
  421. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b5c1596551c256e0e9cf02028595b092.woff2 +0 -0
  422. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b6d128682ee29e471486354d486a1b90.woff2 +0 -0
  423. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b6fd38ca30869792244804b04bc058da.woff2 +0 -0
  424. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b7d203b051eff504ff59ddca7576b6a9.woff2 +0 -0
  425. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2 +0 -0
  426. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ba3de316d63c7e339987b16f41a0b879.woff2 +0 -0
  427. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-bafff7a14c27403dcc6cf1432e8ea836.woff2 +0 -0
  428. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-bd77e3c7f9e0b072d96af37f73d1aa32.woff2 +0 -0
  429. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-be549ab72f0719d606a5c01e2c0219b6.woff2 +0 -0
  430. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c16ed9740b85badf16e86ea782a3062f.woff2 +0 -0
  431. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c1f94158256bb1f3bf665b053d895af9.woff2 +0 -0
  432. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c40533fdf4cc57177b12803598af7e59.woff2 +0 -0
  433. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c4a687ac4f0c2766eefc9f77ed99cddf.woff2 +0 -0
  434. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2 +0 -0
  435. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c8b71798409ccc126ee264a00aadcf21.woff2 +0 -0
  436. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c99eda15fc26a2941579560f76c3a5cf.woff2 +0 -0
  437. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2 +0 -0
  438. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cbaaefaaf326668277aa24dfa93c4d28.woff2 +0 -0
  439. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cd145ce4a0ea18469358df53c207bc1b.woff2 +0 -0
  440. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cdbce89e82cc1ab53a2decbf5819278f.woff2 +0 -0
  441. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ce4884f96f11589608b76b726a755803.woff2 +0 -0
  442. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cf2cc71752631e579e35b0e423bf2638.woff2 +0 -0
  443. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cf6ff4e0f491ca0cf3038187a997b9b4.woff2 +0 -0
  444. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cfb211578629b7e8153b37240de6a9d5.woff2 +0 -0
  445. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d0cf73942fea1c74edbdf0b3011f4656.woff2 +0 -0
  446. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d2666cbed13462c5dc36fa2f15c202ca.woff2 +0 -0
  447. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d3716376641d615e2995605b29bca7b6.woff2 +0 -0
  448. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-dac48066b5883d8b4551fc584f0c2a3e.woff2 +0 -0
  449. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-dbea1af6dcd9860be40c3d18254338f5.woff2 +0 -0
  450. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e11567fd2accf9957cd0d3c2be937d87.woff2 +0 -0
  451. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e2ead7ea7da0437f085f42ffc05f8d13.woff2 +0 -0
  452. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2 +0 -0
  453. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e480d9c614742d05f0e78f274f1e69e6.woff2 +0 -0
  454. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e4bca6cfa53e499cae0a6be4894a90e9.woff2 +0 -0
  455. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e51ef413167c6e14e0c0fdcc585f2fc9.woff2 +0 -0
  456. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e5f453bb04da18eed01675eeebd88bf8.woff2 +0 -0
  457. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e656f091b9dc4709722c9f4b84d3c797.woff2 +0 -0
  458. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ec181b795ac1fb5a50d700b6e996d745.woff2 +0 -0
  459. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ee8bae97908d5147b423f77ad0d3c1bb.woff2 +0 -0
  460. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f0f13b5c60e0af5553bd359f5513be1b.woff2 +0 -0
  461. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f2b54d4e7be0eaefe1c2c56836fa5368.woff2 +0 -0
  462. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f56414bf9bced67990def8660e306759.woff2 +0 -0
  463. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f5d079153c99a25b9be5b8583c4cc8a7.woff2 +0 -0
  464. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f6032fc06eb20480f096199713f70885.woff2 +0 -0
  465. package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f8ee5d36068a42b51d0e4a1116cfcec1.woff2 +0 -0
  466. package/embedded/chalk-whiteboard/index.css +1 -0
  467. package/embedded/chalk-whiteboard/index.html +17 -0
  468. package/embedded/chalk-whiteboard/licenses/Excalidraw.txt +21 -0
  469. package/embedded/chalk-whiteboard/licenses/MathJax.txt +202 -0
  470. package/embedded/chalk-whiteboard/mathjax/tex-svg.js +1 -0
  471. package/embedded/chalk-whiteboard/mathjax-config.js +1 -0
  472. package/embedded/chalk-whiteboard/renderer.js +4114 -0
  473. package/ios/ChalkCallKitManager.swift +385 -0
  474. package/ios/ChalkCallKitModule.swift +120 -0
  475. package/ios/ChalkCallKitModuleBridge.m +14 -0
  476. package/ios/ChalkWhiteboardAssets.swift +41 -0
  477. package/ios/ChalkWhiteboardAssetsBridge.m +10 -0
  478. package/package.json +184 -0
  479. package/src/android/connection-service.test.ts +114 -0
  480. package/src/android/connection-service.ts +106 -0
  481. package/src/android.ts +1 -0
  482. package/src/callkit/callkit.test.ts +95 -0
  483. package/src/callkit/callkit.ts +135 -0
  484. package/src/callkit/resolve-space-callkit-options.test.ts +68 -0
  485. package/src/callkit/resolve-space-callkit-options.ts +34 -0
  486. package/src/client.test.ts +12 -0
  487. package/src/client.ts +7 -0
  488. package/src/clipboard-store.ts +108 -0
  489. package/src/clipboard.test.ts +79 -0
  490. package/src/clipboard.ts +36 -0
  491. package/src/components/Chalk.test.tsx +213 -0
  492. package/src/components/Chalk.tsx +333 -0
  493. package/src/components/ChatMessageList.tsx +209 -0
  494. package/src/components/EmbeddedWhiteboard.test.tsx +92 -0
  495. package/src/components/EmbeddedWhiteboard.tsx +260 -0
  496. package/src/components/Entrance.test.tsx +19 -0
  497. package/src/components/Entrance.tsx +41 -0
  498. package/src/components/EntranceView.android.test.tsx +100 -0
  499. package/src/components/EntranceView.android.tsx +274 -0
  500. package/src/components/EntranceView.ios-pad.test.tsx +160 -0
  501. package/src/components/EntranceView.ios-pad.tsx +326 -0
  502. package/src/components/EntranceView.ios-phone.test.tsx +137 -0
  503. package/src/components/EntranceView.ios-phone.tsx +271 -0
  504. package/src/components/EntranceView.macos.tsx +278 -0
  505. package/src/components/EntranceView.test.tsx +15 -0
  506. package/src/components/EntranceView.tsx +38 -0
  507. package/src/components/FaceAvatar.tsx +120 -0
  508. package/src/components/GradientSurface.tsx +23 -0
  509. package/src/components/LogoElements.test.tsx +60 -0
  510. package/src/components/LogoElements.tsx +119 -0
  511. package/src/components/MediaView.tsx +76 -0
  512. package/src/components/ReactionPicker.test.tsx +19 -0
  513. package/src/components/ReactionPicker.tsx +98 -0
  514. package/src/components/RtcVideoView.test.tsx +12 -0
  515. package/src/components/RtcVideoView.tsx +15 -0
  516. package/src/components/SpaceView.android.test.tsx +11 -0
  517. package/src/components/SpaceView.android.tsx +1 -0
  518. package/src/components/SpaceView.ios-pad.test.tsx +11 -0
  519. package/src/components/SpaceView.ios-pad.tsx +1 -0
  520. package/src/components/SpaceView.ios-phone.test.tsx +11 -0
  521. package/src/components/SpaceView.ios-phone.tsx +1 -0
  522. package/src/components/SpaceView.macos.test.tsx +11 -0
  523. package/src/components/SpaceView.macos.tsx +1 -0
  524. package/src/components/SpaceView.shared.test.tsx +115 -0
  525. package/src/components/SpaceView.shared.tsx +87 -0
  526. package/src/components/SpaceView.test.tsx +15 -0
  527. package/src/components/SpaceView.tsx +52 -0
  528. package/src/components/android-connection-service-controller.test.ts +80 -0
  529. package/src/components/android-connection-service-controller.ts +132 -0
  530. package/src/components/episode-diagnostic-render-observer.test.ts +24 -0
  531. package/src/components/episode-diagnostic-render-observer.ts +12 -0
  532. package/src/components/native-animation-controller.test.ts +47 -0
  533. package/src/components/native-animation-controller.ts +36 -0
  534. package/src/components/native-chat.test.ts +22 -0
  535. package/src/components/native-chat.ts +23 -0
  536. package/src/components/native-entrance/entrance-controller-store.test.ts +75 -0
  537. package/src/components/native-entrance/entrance-controller-store.ts +112 -0
  538. package/src/components/native-entrance/useEntranceController.ts +60 -0
  539. package/src/components/native-joining-loading-animation.ts +26 -0
  540. package/src/components/native-media-visibility.test.ts +77 -0
  541. package/src/components/native-media-visibility.ts +18 -0
  542. package/src/components/native-space-callkit-controller.test.ts +62 -0
  543. package/src/components/native-space-callkit-controller.ts +131 -0
  544. package/src/components/native-space-view/AppearanceSettings.test.tsx +56 -0
  545. package/src/components/native-space-view/AppearanceSettings.tsx +114 -0
  546. package/src/components/native-space-view/ParticipantActionSheet.test.tsx +18 -0
  547. package/src/components/native-space-view/ParticipantActionSheet.tsx +99 -0
  548. package/src/components/native-space-view/SettingsSheet.test.tsx +17 -0
  549. package/src/components/native-space-view/SettingsSheet.tsx +164 -0
  550. package/src/components/native-space-view/SpaceActionMenu.test.tsx +110 -0
  551. package/src/components/native-space-view/SpaceActionMenu.tsx +78 -0
  552. package/src/components/native-space-view/SpaceBottomDock.android.test.tsx +61 -0
  553. package/src/components/native-space-view/SpaceBottomDock.android.tsx +115 -0
  554. package/src/components/native-space-view/SpaceChatSheet.test.tsx +18 -0
  555. package/src/components/native-space-view/SpaceChatSheet.tsx +179 -0
  556. package/src/components/native-space-view/SpaceGrid.android.tsx +323 -0
  557. package/src/components/native-space-view/SpaceMoreSheet.test.tsx +15 -0
  558. package/src/components/native-space-view/SpaceMoreSheet.tsx +161 -0
  559. package/src/components/native-space-view/SpacePanelSheet.test.tsx +15 -0
  560. package/src/components/native-space-view/SpacePanelSheet.tsx +45 -0
  561. package/src/components/native-space-view/SpacePeopleSheet.test.tsx +13 -0
  562. package/src/components/native-space-view/SpacePeopleSheet.tsx +116 -0
  563. package/src/components/native-space-view/SpaceStage.android.tsx +372 -0
  564. package/src/components/native-space-view/SpaceSurfacePrimitives.test.tsx +12 -0
  565. package/src/components/native-space-view/SpaceSurfacePrimitives.tsx +75 -0
  566. package/src/components/native-space-view/SpaceTopBar.android.test.tsx +43 -0
  567. package/src/components/native-space-view/SpaceTopBar.android.tsx +97 -0
  568. package/src/components/native-space-view/SpaceWhiteboardSurface.test.tsx +85 -0
  569. package/src/components/native-space-view/SpaceWhiteboardSurface.tsx +69 -0
  570. package/src/components/native-space-view/diagnostics.test.ts +31 -0
  571. package/src/components/native-space-view/diagnostics.ts +84 -0
  572. package/src/components/native-space-view/format-space-duration.test.ts +13 -0
  573. package/src/components/native-space-view/format-space-duration.ts +3 -0
  574. package/src/components/native-space-view/native-space-grid-keys.test.ts +11 -0
  575. package/src/components/native-space-view/native-space-grid-keys.ts +6 -0
  576. package/src/components/native-space-view/native-space-page-store.test.ts +23 -0
  577. package/src/components/native-space-view/native-space-page-store.ts +41 -0
  578. package/src/components/native-space-view/screen-share-availability.ts +21 -0
  579. package/src/components/native-space-view/space-chat-attachments.test.ts +33 -0
  580. package/src/components/native-space-view/space-chat-attachments.ts +39 -0
  581. package/src/components/native-space-view/space-panel-layout.ts +10 -0
  582. package/src/components/native-space-view/space-progressive-surface-helpers.test.ts +24 -0
  583. package/src/components/native-space-view/space-progressive-surface-helpers.ts +33 -0
  584. package/src/components/native-space-view/space-progressive-surface-types.ts +3 -0
  585. package/src/components/native-space-view/types.ts +25 -0
  586. package/src/components/native-space-view/useSpaceViewController.contract.test.ts +10 -0
  587. package/src/components/native-space-view/useSpaceViewController.contract.ts +34 -0
  588. package/src/components/native-space-view/useSpaceViewController.test.ts +105 -0
  589. package/src/components/native-space-view/useSpaceViewController.ts +396 -0
  590. package/src/components/native-space-view/useSpaceViewDerived.test.ts +58 -0
  591. package/src/components/native-space-view/useSpaceViewDerived.ts +29 -0
  592. package/src/components/native-space-view/useSpaceViewPanels.controlled.test.ts +40 -0
  593. package/src/components/native-space-view/useSpaceViewPanels.test.ts +73 -0
  594. package/src/components/native-space-view/useSpaceViewPanels.ts +170 -0
  595. package/src/components/rtc-video-view-availability.ts +16 -0
  596. package/src/components/space-lifecycle.test.ts +19 -0
  597. package/src/components/space-lifecycle.ts +2 -0
  598. package/src/components/useAndroidConnectionService.ts +55 -0
  599. package/src/context/space-client-context.test.tsx +10 -0
  600. package/src/context/space-client-context.tsx +21 -0
  601. package/src/diagnostics.test.ts +29 -0
  602. package/src/diagnostics.ts +187 -0
  603. package/src/hooks/entrance-preview-store.test.ts +79 -0
  604. package/src/hooks/entrance-preview-store.ts +99 -0
  605. package/src/hooks/external-store.ts +18 -0
  606. package/src/hooks/space-hooks.test.ts +76 -0
  607. package/src/hooks/space-hooks.ts +43 -0
  608. package/src/hooks/useEntrancePreview.ts +26 -0
  609. package/src/hooks/useLayout.test.ts +16 -0
  610. package/src/hooks/useLayout.ts +37 -0
  611. package/src/hooks/usePanels.ts +30 -0
  612. package/src/index.ts +10 -0
  613. package/src/invites.test.ts +56 -0
  614. package/src/invites.ts +43 -0
  615. package/src/ios-pad.ts +1 -0
  616. package/src/ios-phone.ts +1 -0
  617. package/src/ios.ts +1 -0
  618. package/src/macos.ts +1 -0
  619. package/src/media/native-webrtc.ts +11 -0
  620. package/src/platform/platform.ts +34 -0
  621. package/src/public-surface.test.ts +25 -0
  622. package/src/runtime.test.ts +83 -0
  623. package/src/runtime.ts +142 -0
  624. package/src/space-client/create-native-space-client.test.ts +247 -0
  625. package/src/space-client/create-native-space-client.ts +280 -0
  626. package/src/telemetry.test.ts +143 -0
  627. package/src/telemetry.ts +234 -0
  628. package/src/test-support/test-renderer.test.ts +9 -0
  629. package/src/test-support/test-renderer.ts +26 -0
  630. package/src/types/hugeicons-direct.d.ts +4 -0
  631. package/src/types/react-native-safe-area-context.d.ts +8 -0
  632. package/src/ui/appearance.test.ts +50 -0
  633. package/src/ui/appearance.ts +770 -0
  634. package/src/ui/native-appearance-context.controlled.test.tsx +41 -0
  635. package/src/ui/native-appearance-context.test.tsx +14 -0
  636. package/src/ui/native-appearance-context.tsx +74 -0
  637. package/src/ui/native-theme.test.ts +34 -0
  638. package/src/ui/native-theme.test.tsx +14 -0
  639. package/src/ui/native-theme.tsx +54 -0
  640. package/src/ui/native-types.ts +40 -0
  641. package/src/ui/participant-avatar.test.ts +29 -0
  642. package/src/ui/participant-avatar.ts +47 -0
  643. package/src/ui/theme-tokens.test.ts +14 -0
  644. package/src/ui/theme-tokens.ts +41 -0
  645. package/src/ui/theme.test.ts +36 -0
  646. package/src/ui/theme.ts +214 -0
  647. package/src/utils/build-chalk-invite-link.test.ts +12 -0
  648. package/src/utils/build-chalk-invite-link.ts +5 -0
  649. package/src/utils/ios-simulator.test.ts +96 -0
  650. package/src/utils/ios-simulator.ts +125 -0
  651. package/src/utils/native-space-layout.test.ts +170 -0
  652. package/src/utils/native-space-layout.ts +135 -0
  653. package/src/whiteboard/embedded-whiteboard-assets.test.ts +31 -0
  654. package/src/whiteboard/embedded-whiteboard-assets.ts +41 -0
@@ -0,0 +1,25 @@
1
+ import type { NativeParticipantState } from "../../ui/native-types";
2
+
3
+ export type SpaceParticipant = NativeParticipantState["participants"][number];
4
+ export type SpacePanelName = "chat" | "participants" | "settings" | "whiteboard";
5
+ export type SpaceViewAction = () => unknown | Promise<unknown>;
6
+ export type SpaceViewActionRunner = (action: SpaceViewAction) => Promise<void>;
7
+
8
+ export interface SpaceBottomDockProps {
9
+ simulatorMediaDisabled: boolean;
10
+ isMuted: boolean;
11
+ isCameraOff: boolean;
12
+ isHandRaised?: boolean;
13
+ isScreenSharing?: boolean;
14
+ unreadChatCount: number;
15
+ participantCount?: number;
16
+ onToggleAudio: () => void;
17
+ onToggleVideo: () => void;
18
+ onToggleHand?: () => void;
19
+ onToggleScreenShare?: () => void;
20
+ onOpenChat?: () => void;
21
+ onOpenParticipants?: () => void;
22
+ onOpenReactions?: () => void;
23
+ onOpenMore: () => void;
24
+ onLeave: () => void;
25
+ }
@@ -0,0 +1,10 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import type { SpaceViewControllerContractCheck } from "./useSpaceViewController.contract";
4
+
5
+ describe("useSpaceViewController contract", () => {
6
+ it("keeps the bidirectional return-shape assertion compiled", () => {
7
+ const contractCheck: SpaceViewControllerContractCheck = true;
8
+ expect(contractCheck).toBe(true);
9
+ });
10
+ });
@@ -0,0 +1,34 @@
1
+ import type { Reaction } from "@q9labsai/chalk-client";
2
+ import type { Dispatch, SetStateAction } from "react";
3
+
4
+ import type { SpacePanelName } from "./types";
5
+ import type { useSpaceViewController } from "./useSpaceViewController";
6
+
7
+ type ExpectedSpaceViewController = {
8
+ readonly simulatorMediaDisabled: boolean;
9
+ readonly spaceName: string;
10
+ readonly panel: SpacePanelName | null;
11
+ readonly isMuted: boolean;
12
+ readonly isCameraOff: boolean;
13
+ readonly participantCount: number;
14
+ readonly canChat: boolean;
15
+ readonly canParticipants: boolean;
16
+ readonly canScreenShare: boolean;
17
+ readonly canReactions: boolean;
18
+ readonly canHandRaise: boolean;
19
+ readonly canWhiteboard: boolean;
20
+ readonly chat: { readonly unreadCount: number; readonly messages: readonly unknown[] };
21
+ readonly participants: { readonly participants: readonly unknown[]; readonly localParticipant: unknown };
22
+ readonly layout: { readonly layout: "grid" | "focus" | "presentation"; readonly setLayout: (layout: "grid" | "focus" | "presentation") => void };
23
+ readonly setActionsOpen: Dispatch<SetStateAction<boolean>>;
24
+ readonly setReactionPickerOpen: Dispatch<SetStateAction<boolean>>;
25
+ readonly setChatDraft: Dispatch<SetStateAction<string>>;
26
+ readonly sendReaction: (reaction: Reaction) => void;
27
+ readonly sendChatMessage: () => void;
28
+ readonly handleLeave: () => void;
29
+ };
30
+
31
+ type Assert<T extends true> = T;
32
+ type IsAssignable<Current, Expected> = Current extends Expected ? true : false;
33
+
34
+ export type SpaceViewControllerContractCheck = Assert<IsAssignable<ReturnType<typeof useSpaceViewController>, ExpectedSpaceViewController>>;
@@ -0,0 +1,105 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+
3
+ const directClient = vi.hoisted(() => ({
4
+ chat: { files: { url: vi.fn(() => "https://example.test/file") }, loadOlder: vi.fn(async () => ({ status: "loaded" })), markRead: vi.fn(async () => null), send: vi.fn(async () => ({})) },
5
+ media: {
6
+ acceptRequest: vi.fn(async () => undefined),
7
+ declineRequest: vi.fn(async () => undefined),
8
+ setCameraEnabled: vi.fn(async () => undefined),
9
+ setMicrophoneEnabled: vi.fn(async () => undefined),
10
+ setScreenShareEnabled: vi.fn(async () => undefined),
11
+ },
12
+ participants: {
13
+ admit: vi.fn(async () => undefined),
14
+ assignRole: vi.fn(async () => undefined),
15
+ deny: vi.fn(async () => undefined),
16
+ lowerHand: vi.fn(async () => undefined),
17
+ mute: vi.fn(async () => undefined),
18
+ raiseHand: vi.fn(async () => undefined),
19
+ remove: vi.fn(async () => undefined),
20
+ renameSelf: vi.fn(async () => undefined),
21
+ requestMedia: vi.fn(async () => ({ status: "delivered" })),
22
+ stopScreenShare: vi.fn(async () => undefined),
23
+ stopVideo: vi.fn(async () => undefined),
24
+ },
25
+ reactions: { send: vi.fn(async () => ({})) },
26
+ whiteboard: { transport: vi.fn(() => null) },
27
+ }));
28
+
29
+ vi.mock("react", () => ({
30
+ useCallback: <T>(callback: T) => callback,
31
+ useEffect: () => undefined,
32
+ useMemo: <T>(factory: () => T) => factory(),
33
+ useState: <T>(initial: T): readonly [T, (next: T) => void] => [initial, vi.fn()],
34
+ }));
35
+ vi.mock("react-native", () => ({ Alert: { alert: vi.fn() }, Linking: { openURL: vi.fn(async () => undefined) } }));
36
+ vi.mock("../../context/space-client-context", () => ({ useSpaceClient: () => directClient }));
37
+ vi.mock("../../hooks/space-hooks", () => ({
38
+ useSelf: () => ({ participantId: "self", displayName: "Taylor", handRaised: false, can: (capability: string) => capability !== "endEpisode" }),
39
+ useParticipants: () => ({
40
+ roster: [
41
+ {
42
+ participantId: "self",
43
+ displayName: "Taylor",
44
+ role: "collaborator",
45
+ eligibleRoles: [],
46
+ capabilities: [],
47
+ handRaised: false,
48
+ media: { microphone: "active", camera: "active", screenShare: "inactive" },
49
+ },
50
+ ],
51
+ admissionQueue: [],
52
+ }),
53
+ useMedia: () => ({
54
+ local: {
55
+ microphone: { state: "enabled", track: null },
56
+ camera: { state: "enabled", track: null },
57
+ screen: { state: "disabled", track: null },
58
+ },
59
+ screenShare: { state: "disabled", track: null },
60
+ remote: [],
61
+ incomingRequests: [],
62
+ }),
63
+ useChat: () => ({ status: "ready", messages: [], pendingSends: [], readReceipts: [], unreadCount: 0, pagination: { cursor: null, hasOlder: false, historyTruncated: false } }),
64
+ useReactions: () => ({ active: [] }),
65
+ useWhiteboard: () => ({ engine: { status: "ready", sceneId: null, revision: null, error: null } }),
66
+ }));
67
+ vi.mock("../../utils/ios-simulator", () => ({ isIosSimulator: () => false }));
68
+ vi.mock("./useSpaceViewPanels", () => ({
69
+ useSpaceViewPanels: () => ({
70
+ layout: { layout: "grid" },
71
+ panel: null,
72
+ secondsElapsed: 5,
73
+ formattedDuration: "0:05",
74
+ actionsOpen: false,
75
+ reactionPickerOpen: false,
76
+ whiteboard: { isOpen: false, canDraw: true, canClear: false, elements: [], openParticipants: [], transport: null },
77
+ handleLeave: vi.fn(),
78
+ openPanel: vi.fn(),
79
+ closePanel: vi.fn(),
80
+ handleInviteParticipants: vi.fn(),
81
+ }),
82
+ }));
83
+ vi.mock("./useSpaceViewDerived", () => ({ useSpaceViewDerived: () => ({ isStageMode: false, gridPages: [], allParticipants: [] }) }));
84
+
85
+ import { useSpaceViewController } from "./useSpaceViewController";
86
+
87
+ describe("useSpaceViewController", () => {
88
+ it("binds native Space actions directly to the canonical SpaceClient", async () => {
89
+ const controller = useSpaceViewController({ spaceName: "Design review", onLeave: vi.fn() });
90
+
91
+ expect(controller.participants.localParticipant?.displayName).toBe("Taylor");
92
+ expect(controller.chat.isEnabled).toBe(true);
93
+ expect(controller.canSettings).toBe(true);
94
+ expect(controller.canInvite).toBe(false);
95
+ controller.toggleAudio();
96
+ controller.sendReaction("🎉");
97
+ controller.requestStartParticipantCamera("participant-2");
98
+
99
+ await vi.waitFor(() => {
100
+ expect(directClient.media.setMicrophoneEnabled).toHaveBeenCalledWith(false);
101
+ expect(directClient.reactions.send).toHaveBeenCalledWith("🎉");
102
+ expect(directClient.participants.requestMedia).toHaveBeenCalledWith("participant-2", "camera");
103
+ });
104
+ });
105
+ });
@@ -0,0 +1,396 @@
1
+ import type { ChatSendInput, Reaction } from "@q9labsai/chalk-client";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
+ import { Alert, Linking } from "react-native";
4
+
5
+ import { useSpaceClient } from "../../context/space-client-context";
6
+ import { useChat as useSpaceChat, useMedia as useSpaceMedia, useParticipants as useSpaceParticipants, useReactions as useSpaceReactions, useSelf, useWhiteboard } from "../../hooks/space-hooks";
7
+ import { getNativeJourneyContext } from "../../telemetry";
8
+ import type { NativeChatMessage, NativeParticipant, NativeReaction } from "../../ui/native-types";
9
+ import { isIosSimulator } from "../../utils/ios-simulator";
10
+ import type { SpaceViewProps } from "../SpaceView";
11
+ import { buildSpaceViewDiagnosticsSnapshot } from "./diagnostics";
12
+ import { useSpaceViewDerived } from "./useSpaceViewDerived";
13
+ import { useSpaceViewPanels } from "./useSpaceViewPanels";
14
+ import { resolveNativeScreenShareAvailability } from "./screen-share-availability";
15
+ import { normalizeChatFileDrafts, uploadAndSendNativeChatAttachments, type NativeChatFileDraft } from "./space-chat-attachments";
16
+
17
+ const spaceReactions = new Set<Reaction>(["👍", "❤️", "😂", "😮", "😢", "🎉"]);
18
+
19
+ /**
20
+ * The native Space UI consumes the canonical SpaceClient snapshot directly.
21
+ * This keeps the mature native renderer intact without re-projecting client
22
+ * state through a retired compatibility layer.
23
+ */
24
+ export function useSpaceViewController({ spaceName, inviteLink, layout: controlledLayout, onLayoutChange, features, onLeave, onEndEpisode, onDiagnosticsChange, pickChatFiles: pickChatFilesInput }: SpaceViewProps) {
25
+ const client = useSpaceClient();
26
+ const self = useSelf();
27
+ const participantSlice = useSpaceParticipants();
28
+ const media = useSpaceMedia();
29
+ const chatSlice = useSpaceChat();
30
+ const reactionSlice = useSpaceReactions();
31
+ const whiteboardSlice = useWhiteboard();
32
+ const journeyContext = getNativeJourneyContext(client);
33
+ const [actionsOpen, setActionsOpen] = useState(false);
34
+ const [reactionPickerOpen, setReactionPickerOpen] = useState(false);
35
+ const [chatDraft, setChatDraft] = useState("");
36
+ const [chatAttachments, setChatAttachments] = useState<readonly NativeChatFileDraft[]>([]);
37
+ const [chatAttachmentError, setChatAttachmentError] = useState<string | null>(null);
38
+ const [chatAttachmentPicking, setChatAttachmentPicking] = useState(false);
39
+ const [chatAttachmentUploading, setChatAttachmentUploading] = useState(false);
40
+
41
+ const run = useCallback(async (action: () => unknown | Promise<unknown>) => {
42
+ try {
43
+ await action();
44
+ } catch (cause) {
45
+ Alert.alert("Action failed", cause instanceof Error ? cause.message : "Chalk could not complete the action.");
46
+ }
47
+ }, []);
48
+
49
+ const localParticipantId = self.participantId;
50
+ const participants = useMemo(
51
+ () =>
52
+ participantSlice.roster.map((participant): NativeParticipant => {
53
+ const local = participant.participantId === localParticipantId;
54
+ const remoteMedia = media.remote.filter((publication) => publication.participantId === participant.participantId);
55
+ return {
56
+ ...participant,
57
+ id: participant.participantId,
58
+ audioEnabled: local ? media.local.microphone.state === "enabled" || media.local.microphone.state === "requesting" : participant.media.microphone === "active",
59
+ videoEnabled: local ? media.local.camera.state === "enabled" || media.local.camera.state === "requesting" : participant.media.camera === "active",
60
+ audioTrack: local ? media.local.microphone.track : (remoteMedia.find((publication) => publication.source === "microphone")?.track ?? null),
61
+ videoTrack: local ? media.local.camera.track : (remoteMedia.find((publication) => publication.source === "camera")?.track ?? null),
62
+ screenShareTrack: local ? media.screenShare.track : (remoteMedia.find((publication) => publication.source === "screen")?.track ?? null),
63
+ };
64
+ }),
65
+ [localParticipantId, media.local.camera, media.local.microphone, media.remote, media.screenShare.track, participantSlice.roster],
66
+ );
67
+ const localParticipant = useMemo(() => participants.find((participant) => participant.id === localParticipantId) ?? null, [localParticipantId, participants]);
68
+ const spaceParticipants = useMemo(
69
+ () => ({
70
+ participants,
71
+ localParticipant,
72
+ remoteParticipants: participants.filter((participant) => participant.id !== localParticipantId),
73
+ activeSpeaker: null,
74
+ count: participants.length,
75
+ participantCount: participants.length,
76
+ getParticipant: (participantId: string) => participants.find((participant) => participant.id === participantId),
77
+ updateDisplayName: (displayName: string) => client.participants.renameSelf(displayName),
78
+ }),
79
+ [client.participants, localParticipant, localParticipantId, participants],
80
+ );
81
+
82
+ const isLocalSharing = media.screenShare.state === "enabled" || media.screenShare.state === "requesting";
83
+ const remoteScreenShare = useMemo(() => media.remote.find((publication) => publication.source === "screen") ?? null, [media.remote]);
84
+ const screenShare = useMemo(
85
+ () => ({
86
+ isActive: isLocalSharing || remoteScreenShare !== null,
87
+ isStarting: media.screenShare.state === "requesting",
88
+ isLocalSharing,
89
+ sharerParticipantId: isLocalSharing ? localParticipantId : (remoteScreenShare?.participantId ?? null),
90
+ videoTrack: isLocalSharing ? media.screenShare.track : (remoteScreenShare?.track ?? null),
91
+ audioTrack: null,
92
+ start: async () => {
93
+ await client.media.setScreenShareEnabled(true);
94
+ return true;
95
+ },
96
+ stop: () => client.media.setScreenShareEnabled(false),
97
+ toggle: async () => {
98
+ const enabled = !isLocalSharing;
99
+ await client.media.setScreenShareEnabled(enabled);
100
+ return enabled;
101
+ },
102
+ }),
103
+ [client.media, isLocalSharing, localParticipantId, media.screenShare.state, media.screenShare.track, remoteScreenShare],
104
+ );
105
+
106
+ const interactionState = useMemo(() => {
107
+ const raisedHands = participantSlice.roster.filter((participant) => participant.handRaised).map((participant) => participant.participantId);
108
+ const activeReactions: NativeReaction[] = reactionSlice.active.map((reaction) => ({
109
+ id: reaction.eventId,
110
+ emoji: reaction.reaction,
111
+ participantId: reaction.participantId,
112
+ participantName: reaction.displayName,
113
+ }));
114
+ return {
115
+ isHandRaised: self.handRaised,
116
+ raisedHands,
117
+ raisedHandCount: raisedHands.length,
118
+ activeReactions,
119
+ reactionEnabled: self.can("sendReaction"),
120
+ raiseHand: () => client.participants.raiseHand(),
121
+ lowerHand: () => client.participants.lowerHand(),
122
+ toggleHand: () => (self.handRaised ? client.participants.lowerHand() : client.participants.raiseHand()),
123
+ sendReaction: (reaction: Reaction) => client.reactions.send(reaction),
124
+ };
125
+ }, [client.participants, client.reactions, participantSlice.roster, reactionSlice.active, self]);
126
+
127
+ const chat = useMemo(() => {
128
+ const messages: NativeChatMessage[] = chatSlice.messages.map((message) => ({
129
+ id: message.messageId,
130
+ sequence: message.sequence,
131
+ senderId: message.participantId,
132
+ senderName: message.displayName,
133
+ text: message.text,
134
+ content: message.text,
135
+ attachments: message.attachments,
136
+ readBy: chatSlice.readReceipts
137
+ .filter((receipt) => receipt.participantId !== message.participantId && receipt.participantId !== localParticipantId && sequenceAtOrAfter(receipt.readThroughSequence, message.sequence))
138
+ .map((receipt) => ({
139
+ ...receipt,
140
+ displayName: participantSlice.roster.find((participant) => participant.participantId === receipt.participantId)?.displayName ?? "Participant",
141
+ })),
142
+ timestamp: Date.parse(message.createdAt),
143
+ }));
144
+ const pendingMessages = chatSlice.pendingSends.map((pending) => ({ ...pending, state: pending.status }));
145
+ const sendMessage = (content: string | ChatSendInput) => client.chat.send(typeof content === "string" ? { text: content } : content).then(() => undefined);
146
+ const markAsRead = (throughSequence?: string) => {
147
+ const target = throughSequence ? chatSlice.messages.find((message) => message.sequence === throughSequence) : chatSlice.messages.at(-1);
148
+ return target ? client.chat.markRead(target.messageId) : Promise.resolve(null);
149
+ };
150
+ return {
151
+ messages,
152
+ isEnabled: self.can("sendChat"),
153
+ count: messages.length,
154
+ unreadCount: chatSlice.unreadCount,
155
+ pendingMessages,
156
+ hasMore: chatSlice.pagination.hasOlder,
157
+ isLoadingOlder: chatSlice.status === "loading",
158
+ sendMessage,
159
+ retryMessage: (clientMessageId: string) => {
160
+ const pending = chatSlice.pendingSends.find((message) => message.clientMessageId === clientMessageId);
161
+ return pending ? client.chat.send({ text: pending.text, attachments: pending.attachments }).then(() => undefined) : Promise.reject(new Error("The pending message is no longer available."));
162
+ },
163
+ loadOlderMessages: () => client.chat.loadOlder().then(() => undefined),
164
+ reactToMessage: () => {
165
+ throw new Error("Per-message reactions are not part of the actions contract.");
166
+ },
167
+ markAsRead,
168
+ markAsHidden: markAsRead,
169
+ getMessage: (id: string) => messages.find((message) => message.id === id),
170
+ };
171
+ }, [chatSlice, client.chat, localParticipantId, participantSlice.roster, self]);
172
+
173
+ const canWhiteboard = features?.whiteboard !== false && whiteboardSlice.engine.status !== "unsubscribed";
174
+ const canDraw = canWhiteboard && self.can("drawWhiteboard");
175
+ const canClear = canWhiteboard && self.can("manageWhiteboard");
176
+ const whiteboardTransport = useMemo(() => client.whiteboard.transport(), [client.whiteboard, whiteboardSlice.engine.status]);
177
+ const canEndEpisode = self.can("endEpisode");
178
+ const screenShareAvailability = useMemo(() => resolveNativeScreenShareAvailability({ featureEnabled: features?.screenShare !== false }), [features?.screenShare]);
179
+ const capabilities = useMemo(
180
+ () => ({
181
+ canEndEpisode,
182
+ canChat: features?.chat !== false && self.can("sendChat"),
183
+ canParticipants: features?.participants !== false,
184
+ canScreenShare: screenShareAvailability.enabled && self.can("publishScreen"),
185
+ canReactions: features?.reactions !== false && self.can("sendReaction"),
186
+ canHandRaise: features?.handRaise !== false && self.can("raiseHand"),
187
+ canInvite: features?.info !== false && Boolean(inviteLink),
188
+ canSettings: features?.settings !== false,
189
+ canWhiteboard,
190
+ canManageAdmission: features?.admission !== false && self.can("manageAdmission"),
191
+ canRequestMedia: self.can("requestMediaOthers"),
192
+ canMuteParticipants: self.can("muteOthers"),
193
+ canRemoveParticipants: self.can("removeParticipant"),
194
+ canStopParticipantCamera: self.can("stopVideoOthers"),
195
+ canStopParticipantScreenShare: self.can("stopScreenOthers"),
196
+ canModerate: self.can("manageAdmission") || self.can("assignRoles") || self.can("requestMediaOthers") || self.can("muteOthers") || self.can("removeParticipant") || self.can("stopVideoOthers") || self.can("stopScreenOthers"),
197
+ screenShareAvailability,
198
+ }),
199
+ [canEndEpisode, canWhiteboard, features?.admission, features?.chat, features?.handRaise, features?.info, features?.participants, features?.reactions, features?.settings, inviteLink, screenShareAvailability, self],
200
+ );
201
+
202
+ const spacePanels = useSpaceViewPanels({
203
+ spaceName,
204
+ inviteLink,
205
+ layout: controlledLayout,
206
+ onLayoutChange,
207
+ canWhiteboard,
208
+ canDraw,
209
+ canClear,
210
+ canEndEpisode,
211
+ transport: whiteboardTransport,
212
+ onLeave,
213
+ onEndEpisode,
214
+ run,
215
+ journeyContext,
216
+ });
217
+ const derived = useSpaceViewDerived({ participants, localParticipant, screenShare, isWhiteboardOpen: spacePanels.whiteboard.isOpen });
218
+
219
+ useEffect(() => {
220
+ const request = media.incomingRequests[0];
221
+ if (!request) return;
222
+ Alert.alert(request.kind === "unmute" ? "Unmute request" : "Camera request", `${request.actorDisplayName ?? "A Space organizer"} is asking you to ${request.kind === "unmute" ? "unmute" : "start your camera"}.`, [
223
+ { text: "Not now", style: "cancel", onPress: () => void run(() => client.media.declineRequest(request.requestId)) },
224
+ { text: "Allow", onPress: () => void run(() => client.media.acceptRequest(request.requestId)) },
225
+ ]);
226
+ }, [client.media, media.incomingRequests, run]);
227
+
228
+ const spaceDiagnostics = useMemo(
229
+ () =>
230
+ buildSpaceViewDiagnosticsSnapshot({
231
+ featureFlags: {
232
+ chat: capabilities.canChat,
233
+ participants: capabilities.canParticipants,
234
+ screenShare: capabilities.canScreenShare,
235
+ reactions: capabilities.canReactions,
236
+ handRaise: capabilities.canHandRaise,
237
+ whiteboard: capabilities.canWhiteboard,
238
+ },
239
+ canEndEpisode: capabilities.canEndEpisode,
240
+ participantCount: spaceParticipants.participantCount,
241
+ raisedHandCount: interactionState.raisedHandCount,
242
+ unreadChatCount: chat.unreadCount,
243
+ isScreenShareActive: screenShare.isActive,
244
+ isLocalScreenSharing: screenShare.isLocalSharing,
245
+ screenShareSharerParticipantId: screenShare.sharerParticipantId,
246
+ canModerate: capabilities.canModerate,
247
+ screenShareAvailability,
248
+ }),
249
+ [capabilities, chat.unreadCount, interactionState.raisedHandCount, spaceParticipants.participantCount, screenShare.isActive, screenShare.isLocalSharing, screenShare.sharerParticipantId, screenShareAvailability],
250
+ );
251
+ useEffect(() => onDiagnosticsChange?.(spaceDiagnostics), [onDiagnosticsChange, spaceDiagnostics]);
252
+
253
+ const pickChatFiles = useCallback(async () => {
254
+ if (!pickChatFilesInput) return;
255
+ setChatAttachmentPicking(true);
256
+ try {
257
+ const picked = normalizeChatFileDrafts(await pickChatFilesInput());
258
+ if (picked.error) {
259
+ setChatAttachmentError(picked.error);
260
+ return;
261
+ }
262
+ const combined = normalizeChatFileDrafts([...chatAttachments.map((draft) => draft.file), ...picked.files.map((draft) => draft.file)]);
263
+ if (combined.error) {
264
+ setChatAttachmentError(combined.error);
265
+ return;
266
+ }
267
+ setChatAttachmentError(null);
268
+ setChatAttachments(combined.files);
269
+ } catch (cause) {
270
+ setChatAttachmentError(cause instanceof Error ? cause.message : "Could not read the selected files.");
271
+ } finally {
272
+ setChatAttachmentPicking(false);
273
+ }
274
+ }, [chatAttachments, pickChatFilesInput]);
275
+
276
+ const removeChatAttachment = useCallback((index: number) => {
277
+ setChatAttachments((current) => current.filter((_, currentIndex) => currentIndex !== index));
278
+ setChatAttachmentError(null);
279
+ }, []);
280
+
281
+ const sendChatMessage = useCallback(() => {
282
+ const text = chatDraft.trim();
283
+ if (!text && chatAttachments.length === 0) return;
284
+ void run(async () => {
285
+ setChatAttachmentUploading(true);
286
+ setChatAttachmentError(null);
287
+ try {
288
+ await uploadAndSendNativeChatAttachments(chatAttachments, text, client.chat.files.upload, chat.sendMessage);
289
+ setChatDraft("");
290
+ setChatAttachments([]);
291
+ } catch (cause) {
292
+ setChatAttachmentError(cause instanceof Error ? cause.message : "Could not send the attachments.");
293
+ throw cause;
294
+ } finally {
295
+ setChatAttachmentUploading(false);
296
+ }
297
+ });
298
+ }, [chat, chatAttachments, chatDraft, client.chat.files, run]);
299
+
300
+ return {
301
+ simulatorMediaDisabled: isIosSimulator(),
302
+ spaceName: spaceName || "Space",
303
+ panel: spacePanels.panel,
304
+ selfName: self.displayName || "Participant",
305
+ isMuted: !(media.local.microphone.state === "enabled" || media.local.microphone.state === "requesting"),
306
+ isCameraOff: !(media.local.camera.state === "enabled" || media.local.camera.state === "requesting"),
307
+ handRaised: interactionState.isHandRaised,
308
+ raisedHandCount: interactionState.raisedHandCount,
309
+ activeReactions: interactionState.activeReactions.slice(-3),
310
+ secondsElapsed: spacePanels.secondsElapsed,
311
+ formattedDuration: spacePanels.formattedDuration,
312
+ actionsOpen,
313
+ reactionPickerOpen,
314
+ chatDraft,
315
+ chatAttachments,
316
+ chatAttachmentError,
317
+ chatAttachmentPicking,
318
+ chatAttachmentUploading,
319
+ canPickChatFiles: Boolean(pickChatFilesInput),
320
+ participantCount: spaceParticipants.participantCount,
321
+ canChat: capabilities.canChat,
322
+ canParticipants: capabilities.canParticipants,
323
+ canScreenShare: capabilities.canScreenShare,
324
+ canReactions: capabilities.canReactions,
325
+ canHandRaise: capabilities.canHandRaise,
326
+ canInvite: capabilities.canInvite,
327
+ canSettings: capabilities.canSettings,
328
+ canWhiteboard: capabilities.canWhiteboard,
329
+ canManageAdmission: capabilities.canManageAdmission,
330
+ canRequestMedia: capabilities.canRequestMedia,
331
+ canMuteParticipants: capabilities.canMuteParticipants,
332
+ canRemoveParticipants: capabilities.canRemoveParticipants,
333
+ canStopParticipantCamera: capabilities.canStopParticipantCamera,
334
+ canStopParticipantScreenShare: capabilities.canStopParticipantScreenShare,
335
+ admissionRequests: participantSlice.admissionQueue,
336
+ spaceDiagnostics,
337
+ participants: spaceParticipants,
338
+ settings: {
339
+ displayName: self.displayName ?? "",
340
+ microphoneEnabled: media.local.microphone.state === "enabled" || media.local.microphone.state === "requesting",
341
+ cameraEnabled: media.local.camera.state === "enabled" || media.local.camera.state === "requesting",
342
+ devices: media.devices,
343
+ selection: media.selection,
344
+ updateDisplayName: (displayName: string) => {
345
+ const nextDisplayName = displayName.trim();
346
+ if (nextDisplayName) void run(() => client.participants.renameSelf(nextDisplayName));
347
+ },
348
+ selectMicrophone: (deviceId: string) => void run(() => client.media.selectMicrophone(deviceId)),
349
+ selectCamera: (deviceId: string) => void run(() => client.media.selectCamera(deviceId)),
350
+ selectSpeaker: (deviceId: string) => void run(() => client.media.selectSpeaker(deviceId)),
351
+ },
352
+ chat,
353
+ interactions: interactionState,
354
+ screenShare,
355
+ layout: spacePanels.layout,
356
+ whiteboard: spacePanels.whiteboard,
357
+ derived,
358
+ setActionsOpen,
359
+ setReactionPickerOpen,
360
+ setChatDraft,
361
+ pickChatFiles,
362
+ removeChatAttachment,
363
+ handleLeave: spacePanels.handleLeave,
364
+ openPanel: spacePanels.openPanel,
365
+ closePanel: spacePanels.closePanel,
366
+ handleInviteParticipants: spacePanels.handleInviteParticipants,
367
+ toggleAudio: () => void run(() => client.media.setMicrophoneEnabled(!(media.local.microphone.state === "enabled" || media.local.microphone.state === "requesting"))),
368
+ toggleVideo: () => void run(() => client.media.setCameraEnabled(!(media.local.camera.state === "enabled" || media.local.camera.state === "requesting"))),
369
+ toggleScreenShare: () => void run(screenShare.toggle),
370
+ toggleHand: () => void run(interactionState.toggleHand),
371
+ sendReaction: (reaction: Reaction) => {
372
+ if (!spaceReactions.has(reaction)) return;
373
+ void run(() => interactionState.sendReaction(reaction));
374
+ },
375
+ sendChatMessage,
376
+ openChatAttachment: (attachmentId: string) => {
377
+ const attachment = chat.messages.flatMap((message) => message.attachments).find((candidate) => candidate.attachmentId === attachmentId);
378
+ if (attachment) void run(() => Linking.openURL(client.chat.files.url(attachment)));
379
+ },
380
+ markChatMessageVisible: (sequence: string) => void run(() => chat.markAsRead(sequence)),
381
+ admitParticipant: (requestId: string) => void run(() => client.participants.admit(requestId)),
382
+ denyAdmission: (requestId: string) => void run(() => client.participants.deny(requestId)),
383
+ removeParticipant: (participantId: string) => void run(() => client.participants.remove(participantId)),
384
+ muteParticipant: (participantId: string) => void run(() => client.participants.mute(participantId)),
385
+ requestUnmuteParticipant: (participantId: string) => void run(() => client.participants.requestMedia(participantId, "microphone")),
386
+ requestStartParticipantCamera: (participantId: string) => void run(() => client.participants.requestMedia(participantId, "camera")),
387
+ stopParticipantCamera: (participantId: string) => void run(() => client.participants.stopVideo(participantId)),
388
+ stopParticipantScreenShare: (participantId: string) => void run(() => client.participants.stopScreenShare(participantId)),
389
+ };
390
+ }
391
+
392
+ function sequenceAtOrAfter(value: string, floor: string): boolean {
393
+ const normalizedValue = value.replace(/^0+(?=\d)/, "");
394
+ const normalizedFloor = floor.replace(/^0+(?=\d)/, "");
395
+ return normalizedValue.length > normalizedFloor.length || (normalizedValue.length === normalizedFloor.length && normalizedValue >= normalizedFloor);
396
+ }
@@ -0,0 +1,58 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ const viewport = vi.hoisted(() => ({ width: 500 }));
4
+ const defaultViewportWidth = 500;
5
+
6
+ vi.mock("react", () => ({
7
+ useMemo: <T>(factory: () => T) => factory(),
8
+ }));
9
+ vi.mock("react-native", () => ({
10
+ useWindowDimensions: () => ({ width: viewport.width, height: 800 }),
11
+ }));
12
+
13
+ import { useSpaceViewDerived } from "./useSpaceViewDerived";
14
+
15
+ describe("useSpaceViewDerived", () => {
16
+ beforeEach(() => {
17
+ viewport.width = defaultViewportWidth;
18
+ });
19
+
20
+ afterEach(() => {
21
+ viewport.width = defaultViewportWidth;
22
+ });
23
+
24
+ it("marks compact whiteboard layouts and keeps the local participant first", () => {
25
+ const local = { id: "local", screenShareTrack: null };
26
+ const remote = { id: "remote", screenShareTrack: null };
27
+
28
+ const derived = useSpaceViewDerived({
29
+ participants: [remote] as never,
30
+ localParticipant: local as never,
31
+ screenShare: { isActive: false, isLocalSharing: false, sharerParticipantId: null, videoTrack: null },
32
+ isWhiteboardOpen: true,
33
+ });
34
+
35
+ expect(derived.isCompactViewport).toBe(true);
36
+ expect(derived.primaryContent).toBe("whiteboard");
37
+ expect(derived.allParticipants.map((participant) => participant.id)).toEqual(["local", "remote"]);
38
+ });
39
+
40
+ it("uses the wide viewport to expose an active remote screen share", () => {
41
+ viewport.width = 1024;
42
+ const local = { id: "local", screenShareTrack: null };
43
+ const remote = { id: "remote", screenShareTrack: null };
44
+ const track = { readyState: "live" } as never;
45
+
46
+ const derived = useSpaceViewDerived({
47
+ participants: [remote] as never,
48
+ localParticipant: local as never,
49
+ screenShare: { isActive: true, isLocalSharing: false, sharerParticipantId: "remote", videoTrack: track },
50
+ isWhiteboardOpen: false,
51
+ });
52
+
53
+ expect(derived.isCompactViewport).toBe(false);
54
+ expect(derived.primaryContent).toBe("screen-share");
55
+ expect(derived.screenSharer).toBe(remote);
56
+ expect(derived.screenShareTrack).toBe(track);
57
+ });
58
+ });
@@ -0,0 +1,29 @@
1
+ import type { NativeParticipantState } from "../../ui/native-types";
2
+ import { useMemo } from "react";
3
+ import { useWindowDimensions } from "react-native";
4
+ import { NATIVE_COMPACT_VIEWPORT_MAX_WIDTH, resolveNativeSpaceLayout, type NativeScreenShareStateLike } from "../../utils/native-space-layout";
5
+
6
+ type SpaceParticipant = NativeParticipantState["participants"][number];
7
+
8
+ interface UseSpaceViewDerivedOptions {
9
+ participants: readonly SpaceParticipant[];
10
+ localParticipant: SpaceParticipant | null;
11
+ screenShare: NativeScreenShareStateLike;
12
+ isWhiteboardOpen: boolean;
13
+ }
14
+
15
+ export function useSpaceViewDerived({ participants, localParticipant, screenShare, isWhiteboardOpen }: UseSpaceViewDerivedOptions) {
16
+ const { width } = useWindowDimensions();
17
+
18
+ return useMemo(
19
+ () =>
20
+ resolveNativeSpaceLayout({
21
+ participants,
22
+ localParticipant,
23
+ screenShare,
24
+ isWhiteboardOpen,
25
+ isCompactViewport: width < NATIVE_COMPACT_VIEWPORT_MAX_WIDTH,
26
+ }),
27
+ [participants, localParticipant, screenShare, isWhiteboardOpen, width],
28
+ );
29
+ }