@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.
- package/Q9ChalkReactNative.podspec +27 -0
- package/README.md +41 -0
- package/android/build.gradle +43 -0
- package/android/consumer-rules.pro +1 -0
- package/android/src/main/AndroidManifest.xml +24 -0
- package/android/src/main/java/ai/q9labs/chalk/reactnative/ChalkSpaceForegroundService.java +94 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAndroidConnectionServiceModule.kt +161 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAndroidConnectionServicePackage.kt +18 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkConnectionRegistry.kt +120 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkSelfManagedConnection.kt +64 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkSelfManagedConnectionService.kt +35 -0
- package/dist/android/connection-service.d.ts +26 -0
- package/dist/android/connection-service.d.ts.map +1 -0
- package/dist/android.d.ts +2 -0
- package/dist/android.d.ts.map +1 -0
- package/dist/android.js +47 -0
- package/dist/callkit/callkit.d.ts +61 -0
- package/dist/callkit/callkit.d.ts.map +1 -0
- package/dist/callkit/resolve-space-callkit-options.d.ts +17 -0
- package/dist/callkit/resolve-space-callkit-options.d.ts.map +1 -0
- package/dist/chunk-BXIZIHIO.js +4501 -0
- package/dist/chunk-F3NPRVHO.js +121 -0
- package/dist/chunk-HXYIJ75K.js +394 -0
- package/dist/chunk-IMKSYT7R.js +653 -0
- package/dist/chunk-JB4LNWVP.js +247 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +6 -0
- package/dist/clipboard-store.d.ts +17 -0
- package/dist/clipboard-store.d.ts.map +1 -0
- package/dist/clipboard.d.ts +10 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clipboard.js +108 -0
- package/dist/components/Chalk.d.ts +77 -0
- package/dist/components/Chalk.d.ts.map +1 -0
- package/dist/components/ChatMessageList.d.ts +11 -0
- package/dist/components/ChatMessageList.d.ts.map +1 -0
- package/dist/components/EmbeddedWhiteboard.d.ts +46 -0
- package/dist/components/EmbeddedWhiteboard.d.ts.map +1 -0
- package/dist/components/Entrance.d.ts +22 -0
- package/dist/components/Entrance.d.ts.map +1 -0
- package/dist/components/EntranceView.android.d.ts +4 -0
- package/dist/components/EntranceView.android.d.ts.map +1 -0
- package/dist/components/EntranceView.d.ts +18 -0
- package/dist/components/EntranceView.d.ts.map +1 -0
- package/dist/components/EntranceView.ios-pad.d.ts +3 -0
- package/dist/components/EntranceView.ios-pad.d.ts.map +1 -0
- package/dist/components/EntranceView.ios-phone.d.ts +3 -0
- package/dist/components/EntranceView.ios-phone.d.ts.map +1 -0
- package/dist/components/EntranceView.macos.d.ts +4 -0
- package/dist/components/EntranceView.macos.d.ts.map +1 -0
- package/dist/components/FaceAvatar.d.ts +16 -0
- package/dist/components/FaceAvatar.d.ts.map +1 -0
- package/dist/components/GradientSurface.d.ts +14 -0
- package/dist/components/GradientSurface.d.ts.map +1 -0
- package/dist/components/LogoElements.d.ts +6 -0
- package/dist/components/LogoElements.d.ts.map +1 -0
- package/dist/components/MediaView.d.ts +14 -0
- package/dist/components/MediaView.d.ts.map +1 -0
- package/dist/components/ReactionPicker.d.ts +10 -0
- package/dist/components/ReactionPicker.d.ts.map +1 -0
- package/dist/components/RtcVideoView.d.ts +4 -0
- package/dist/components/RtcVideoView.d.ts.map +1 -0
- package/dist/components/SpaceView.android.d.ts +2 -0
- package/dist/components/SpaceView.android.d.ts.map +1 -0
- package/dist/components/SpaceView.d.ts +31 -0
- package/dist/components/SpaceView.d.ts.map +1 -0
- package/dist/components/SpaceView.ios-pad.d.ts +2 -0
- package/dist/components/SpaceView.ios-pad.d.ts.map +1 -0
- package/dist/components/SpaceView.ios-phone.d.ts +2 -0
- package/dist/components/SpaceView.ios-phone.d.ts.map +1 -0
- package/dist/components/SpaceView.macos.d.ts +2 -0
- package/dist/components/SpaceView.macos.d.ts.map +1 -0
- package/dist/components/SpaceView.shared.d.ts +3 -0
- package/dist/components/SpaceView.shared.d.ts.map +1 -0
- package/dist/components/android-connection-service-controller.d.ts +33 -0
- package/dist/components/android-connection-service-controller.d.ts.map +1 -0
- package/dist/components/episode-diagnostic-render-observer.d.ts +2 -0
- package/dist/components/episode-diagnostic-render-observer.d.ts.map +1 -0
- package/dist/components/native-animation-controller.d.ts +7 -0
- package/dist/components/native-animation-controller.d.ts.map +1 -0
- package/dist/components/native-chat.d.ts +8 -0
- package/dist/components/native-chat.d.ts.map +1 -0
- package/dist/components/native-entrance/entrance-controller-store.d.ts +34 -0
- package/dist/components/native-entrance/entrance-controller-store.d.ts.map +1 -0
- package/dist/components/native-entrance/useEntranceController.d.ts +19 -0
- package/dist/components/native-entrance/useEntranceController.d.ts.map +1 -0
- package/dist/components/native-joining-loading-animation.d.ts +9 -0
- package/dist/components/native-joining-loading-animation.d.ts.map +1 -0
- package/dist/components/native-media-visibility.d.ts +8 -0
- package/dist/components/native-media-visibility.d.ts.map +1 -0
- package/dist/components/native-space-callkit-controller.d.ts +39 -0
- package/dist/components/native-space-callkit-controller.d.ts.map +1 -0
- package/dist/components/native-space-view/AppearanceSettings.d.ts +2 -0
- package/dist/components/native-space-view/AppearanceSettings.d.ts.map +1 -0
- package/dist/components/native-space-view/ParticipantActionSheet.d.ts +9 -0
- package/dist/components/native-space-view/ParticipantActionSheet.d.ts.map +1 -0
- package/dist/components/native-space-view/SettingsSheet.d.ts +7 -0
- package/dist/components/native-space-view/SettingsSheet.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceActionMenu.d.ts +8 -0
- package/dist/components/native-space-view/SpaceActionMenu.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceBottomDock.android.d.ts +4 -0
- package/dist/components/native-space-view/SpaceBottomDock.android.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceChatSheet.d.ts +5 -0
- package/dist/components/native-space-view/SpaceChatSheet.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceGrid.android.d.ts +8 -0
- package/dist/components/native-space-view/SpaceGrid.android.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceMoreSheet.d.ts +6 -0
- package/dist/components/native-space-view/SpaceMoreSheet.d.ts.map +1 -0
- package/dist/components/native-space-view/SpacePanelSheet.d.ts +5 -0
- package/dist/components/native-space-view/SpacePanelSheet.d.ts.map +1 -0
- package/dist/components/native-space-view/SpacePeopleSheet.d.ts +5 -0
- package/dist/components/native-space-view/SpacePeopleSheet.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceStage.android.d.ts +29 -0
- package/dist/components/native-space-view/SpaceStage.android.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts +30 -0
- package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceTopBar.android.d.ts +9 -0
- package/dist/components/native-space-view/SpaceTopBar.android.d.ts.map +1 -0
- package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts +15 -0
- package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts.map +1 -0
- package/dist/components/native-space-view/diagnostics.d.ts +48 -0
- package/dist/components/native-space-view/diagnostics.d.ts.map +1 -0
- package/dist/components/native-space-view/format-space-duration.d.ts +2 -0
- package/dist/components/native-space-view/format-space-duration.d.ts.map +1 -0
- package/dist/components/native-space-view/native-space-grid-keys.d.ts +3 -0
- package/dist/components/native-space-view/native-space-grid-keys.d.ts.map +1 -0
- package/dist/components/native-space-view/native-space-page-store.d.ts +8 -0
- package/dist/components/native-space-view/native-space-page-store.d.ts.map +1 -0
- package/dist/components/native-space-view/screen-share-availability.d.ts +9 -0
- package/dist/components/native-space-view/screen-share-availability.d.ts.map +1 -0
- package/dist/components/native-space-view/space-chat-attachments.d.ts +15 -0
- package/dist/components/native-space-view/space-chat-attachments.d.ts.map +1 -0
- package/dist/components/native-space-view/space-panel-layout.d.ts +10 -0
- package/dist/components/native-space-view/space-panel-layout.d.ts.map +1 -0
- package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts +16 -0
- package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts.map +1 -0
- package/dist/components/native-space-view/space-progressive-surface-types.d.ts +3 -0
- package/dist/components/native-space-view/space-progressive-surface-types.d.ts.map +1 -0
- package/dist/components/native-space-view/types.d.ts +24 -0
- package/dist/components/native-space-view/types.d.ts.map +1 -0
- package/dist/components/native-space-view/useSpaceViewController.contract.d.ts +41 -0
- package/dist/components/native-space-view/useSpaceViewController.contract.d.ts.map +1 -0
- package/dist/components/native-space-view/useSpaceViewController.d.ts +150 -0
- package/dist/components/native-space-view/useSpaceViewController.d.ts.map +1 -0
- package/dist/components/native-space-view/useSpaceViewDerived.d.ts +12 -0
- package/dist/components/native-space-view/useSpaceViewDerived.d.ts.map +1 -0
- package/dist/components/native-space-view/useSpaceViewPanels.d.ts +70 -0
- package/dist/components/native-space-view/useSpaceViewPanels.d.ts.map +1 -0
- package/dist/components/rtc-video-view-availability.d.ts +13 -0
- package/dist/components/rtc-video-view-availability.d.ts.map +1 -0
- package/dist/components/space-lifecycle.d.ts +3 -0
- package/dist/components/space-lifecycle.d.ts.map +1 -0
- package/dist/components/useAndroidConnectionService.d.ts +14 -0
- package/dist/components/useAndroidConnectionService.d.ts.map +1 -0
- package/dist/context/space-client-context.d.ts +9 -0
- package/dist/context/space-client-context.d.ts.map +1 -0
- package/dist/diagnostics.d.ts +50 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +143 -0
- package/dist/hooks/entrance-preview-store.d.ts +16 -0
- package/dist/hooks/entrance-preview-store.d.ts.map +1 -0
- package/dist/hooks/external-store.d.ts +10 -0
- package/dist/hooks/external-store.d.ts.map +1 -0
- package/dist/hooks/space-hooks.d.ts +10 -0
- package/dist/hooks/space-hooks.d.ts.map +1 -0
- package/dist/hooks/useEntrancePreview.d.ts +7 -0
- package/dist/hooks/useEntrancePreview.d.ts.map +1 -0
- package/dist/hooks/useLayout.d.ts +16 -0
- package/dist/hooks/useLayout.d.ts.map +1 -0
- package/dist/hooks/usePanels.d.ts +12 -0
- package/dist/hooks/usePanels.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/invites.d.ts +3 -0
- package/dist/invites.d.ts.map +1 -0
- package/dist/invites.js +41 -0
- package/dist/ios-pad.d.ts +2 -0
- package/dist/ios-pad.d.ts.map +1 -0
- package/dist/ios-pad.js +47 -0
- package/dist/ios-phone.d.ts +2 -0
- package/dist/ios-phone.d.ts.map +1 -0
- package/dist/ios-phone.js +47 -0
- package/dist/ios.d.ts +2 -0
- package/dist/ios.d.ts.map +1 -0
- package/dist/ios.js +47 -0
- package/dist/macos.d.ts +2 -0
- package/dist/macos.d.ts.map +1 -0
- package/dist/macos.js +47 -0
- package/dist/media/native-webrtc.d.ts +6 -0
- package/dist/media/native-webrtc.d.ts.map +1 -0
- package/dist/platform/platform.d.ts +3 -0
- package/dist/platform/platform.d.ts.map +1 -0
- package/dist/runtime.d.ts +38 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +30 -0
- package/dist/space-client/create-native-space-client.d.ts +17 -0
- package/dist/space-client/create-native-space-client.d.ts.map +1 -0
- package/dist/telemetry.d.ts +63 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/test-support/test-renderer.d.ts +20 -0
- package/dist/test-support/test-renderer.d.ts.map +1 -0
- package/dist/ui/appearance.d.ts +239 -0
- package/dist/ui/appearance.d.ts.map +1 -0
- package/dist/ui/appearance.js +14 -0
- package/dist/ui/native-appearance-context.d.ts +15 -0
- package/dist/ui/native-appearance-context.d.ts.map +1 -0
- package/dist/ui/native-theme.d.ts +17 -0
- package/dist/ui/native-theme.d.ts.map +1 -0
- package/dist/ui/native-types.d.ts +38 -0
- package/dist/ui/native-types.d.ts.map +1 -0
- package/dist/ui/participant-avatar.d.ts +21 -0
- package/dist/ui/participant-avatar.d.ts.map +1 -0
- package/dist/ui/theme-tokens.d.ts +25 -0
- package/dist/ui/theme-tokens.d.ts.map +1 -0
- package/dist/ui/theme.d.ts +404 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +8 -0
- package/dist/utils/build-chalk-invite-link.d.ts +2 -0
- package/dist/utils/build-chalk-invite-link.d.ts.map +1 -0
- package/dist/utils/ios-simulator.d.ts +5 -0
- package/dist/utils/ios-simulator.d.ts.map +1 -0
- package/dist/utils/native-space-layout.d.ts +42 -0
- package/dist/utils/native-space-layout.d.ts.map +1 -0
- package/dist/whiteboard/embedded-whiteboard-assets.d.ts +7 -0
- package/dist/whiteboard/embedded-whiteboard-assets.d.ts.map +1 -0
- package/embedded/chalk-whiteboard/THIRD_PARTY_NOTICES.json +17 -0
- package/embedded/chalk-whiteboard/asset-manifest.json +1228 -0
- package/embedded/chalk-whiteboard/chalk.css +5 -0
- package/embedded/chalk-whiteboard/compatibility-manifest.json +37 -0
- package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Bold.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Medium.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Regular.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Assistant/Assistant-SemiBold.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Cascadia/CascadiaCode-Regular.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Liberation/LiberationSans-Regular.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Virgil/Virgil-Regular.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0986d134c05864f5025962eef9f994a0.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0b5d723fdc4e249c140f0909e87d03b4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0f626226ba1272e832aea87bafd9720e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0f7fb1e0d5015bb1371343153ecf7ce3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0fa55a080fcd0f9dc2e0b0058b793df8.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0facdf1ea213ba40261022f5d5ed4493.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-10a7ae9a371830a80c3d844acf1c02d7.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-112c051027b2d766c19a519f6ee1f4f7.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-11c345711937f0ba4b8f7b6b919c8440.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-12b52b58eb3df36804b9a654ec9ee194.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-13ae07ed2e272d26d59bc0691cd7117a.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-13d2887ec8ee73c43acdabc52a05af7b.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-145aa02cdd91946e67dc934e1acffe75.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-15dc6d811c9cd078f9086a740d5a1038.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-173945821411c09f70c95f98d590e697.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1b611157cd46bb184d4fa4dae2d6a2b8.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1e6fd68f1f3902ce48ce8c69df385622.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1ee544f0f1dac422545c505baa788992.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1fdc0c67ed57263a80fd108c1f6ccf24.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-203b0e569e3b14aac86a003dc3fa523e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-20cc1bbf50e7efb442756cb605672c1f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-20e7bf72fa05de9adf7dbcc7bf51dde6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-21430ee05a1248901da8d0de08744d47.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23686f7f29da6e8008c36dd3a80c83d6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23ad2d71b280f00b1363b95b7bea94eb.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23f228f3999c01983860012330e4be08.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-24476a126f129212beb33f66853ea151.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-24a21c1e4449222e8d1898d69ff3a404.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-25b7f38e18f035f96cb5e547bd2bd08c.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-29cec36cd205b211da97acabaa62f055.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2a26d20a23b00898ce82f09d2ee47c3f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2adbc89c11e65905393d3dfc468b9d5b.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2b7441d46298788ac94e610ffcc709b6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2b77e8ebfb2367ab2662396a60e7d320.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2cf96d082d35ea3d8106851223ad0d16.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2d43040e86ff03ba677f6f9c04cd0805.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2e33e8dc771ef5e1d9127d60a6b73679.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-33432927cd87d40cfe393c7482bf221f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-353f33792a8f60dc69323ddf635a269e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-36925dfe329a45086cbb7fc5c20d45ac.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3717077e38f98d89eae729b6c14e56dc.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3756e81d3e149cf6099163ee79944fec.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-395c35dd584b56b0789f58a0559beaf1.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3c9de2ae0ea4bc91a510942dfa4be8d2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3cc70dbb64df5b21f1326cc24dee2195.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3e1f8f654357353bf0e04ba5c34b5f7f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3e63ed8162808a9e425ed80a8bc79114.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3eaa538115d76932653c21d8dc28f207.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4095eb84ef3874e2600247bee0b04026.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-450da755d5bcb70906e1295e559b9602.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-452225341522a7942f0f6aab1a5c91a3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4535823663ad81405188a528d8f2b1a2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4806e761d750087c2d734fc64596eaff.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4a0fdb40036e87b40aa08dd30584cb85.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4a38cc3e9cf104e69ba246d37f8cf135.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4aca6a43e59aceee2166b0c7e4e85ef1.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4bfaa8ffa64c5ee560aa2daba7c9cbd3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4dc6d5f188d5c96d44815cd1e81aa885.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4ddc14ed3eb0c3e46364317dfc0144a3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4ee10ae43505e2e0bc62656ced49c0fa.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4f50e5136e136527280bc902c5817561.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-51502f1206be09c565f1547c406e9558.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-51a0e808bbc8361236ac521a119758a3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-52a84a22fd1369bffeaf21da2d6158dc.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5330a2119a716e4e7224ed108b085dac.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-543fa46ace099a7099dad69123399400.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-54acdfc2166ad7fcbd074f75fd4a56ba.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5572b3513ba8df57a3d5d7303ee6b11b.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-56467a5c8840c4d23a60b2f935114848.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-56a32a7689abd0326e57c10c6c069bb4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-57862b464a55b18c7bf234ce22907d73.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-583d166e56ba0de4b77eabb47ef67839.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5882ffa04f32584d26109137e2da4352.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-58fd02350d0bc52cf1ca3bb32ce9766e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5935a5775af3d5c6307ac667bd9ae74e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-59e9ff77b0efaf684bc09274fb6908c9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a1ce3117cfe90c48e8fb4a9a00f694d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a45d991244d4c7140217e1e5f5ca4f4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a7fac4b8b23a6e4e5ba0c9bf1756c91.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5b0ed6971aaab9c8ad563230bd5471a7.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5d2898fbc097a7e24c6f38d80587621e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-603aefd23e350ba7eb124273e3c9bcf1.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-60a41c7e1c68f22424e6d22df544bc82.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-642b26e2e5f5fb780b51b593dbc8c851.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-66493ba5a8367f2928812f446f47b56a.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-670ba603758d94268e8606f240a42e12.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-671a2c20b1eb9e4ef8a192833940e319.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-684d65f1793cac449dde5d59cb3c47fb.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-69c09cc5fa3e55c74fc4821f76909cc3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6e092f71c1e634059ada0e52abadce67.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6f3256af8454371776bc46670d33cc65.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-70c2eb8d64e71a42a834eb857ea9df51.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-70e811fd7994e61f408c923de6ddd078.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7197d6fda6cba7c3874c53d6381ca239.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-72252d73220fa3cd856677888cee1635.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-72536a3d71b694a0d53dd90ddceae41e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-726303e0774b4e678bff8c2deb6ca603.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-733171b4ffcd17ea1fe1c0ba627173bf.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-739bc1a567439c7cffcd1614644593d2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-73e309718fd16cea44b4d54a33581811.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7494dc504ae00ee9cd0505f990f88c5d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-74e2263a91439c25b91d5132ce9f4d62.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-761d05e3cd968cf574166867998ef06a.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7718fe60986d8b42b1be9c5ace5ccf25.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-774d4f764a1299da5d28ec2f2ffe0d69.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-79d494361ae093b69e74ee9dbe65bfd4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-79f007c1c6d07557120982951ea67998.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7a07ddc0f0c0f5f4a9bad6ee3dda66b5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7ab2bed91166a9dca83a5ebfbe2a7f38.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7ccce86603f80a099ddb0cb21d4ae3e3.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7e4bde7e9c7f84cd34d8a845e384c746.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7e929f262f30c8ee78bf398150b1a7cd.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7f855356ab893b0d2b9c1c83b8116f0e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-829615148e6357d826b9242eb7fbbd1e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-866fa7613df6b3fd272bcfd4530c0bb9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-87599f94b6cc129d505b375798d0d751.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8c2f33cee3993174f7e87c28e4bf42ee.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8d3bcabb847b56243b16afe62adaaf21.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8de5b863cb50dfefdd07cb11c774d579.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8e9f97f01034820170065b2921b4fb5e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8f476c4c99813d57cbe6eca4727388ad.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-903bb6865f3452e2fda42e3a25547bc5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-91ddb2969bf2d31ba02ad82998d1314c.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-938d90c10ff8c20386af7f242c05d6b0.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-93fc8f28a33234bcadf1527cafabd502.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-95429962233afd82db1c27df1500a28c.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9544732d2e62d1a429674f8ee41b5d3a.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9592bfc861f07bcb8d75c196b370e548.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-95bfd249da4902577b4b7d76ebdd0b44.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-968cffdc8ee679da094e77ebf50f58ef.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-97f7f48ce90c9429bf32ae51469db74d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-982b630266d87db93d2539affb1275c6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-98f2ad84457de7f3740d9920b8fa8667.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-99a16ef6a64934d5781933dbd9c46b2e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9cfb2a77a4e45025105ad29a1748b90d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9d81066dd2b337c938df6e90380a00dc.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9eb5a99df4e76ac3363453ac9ca288b1.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a004ddfcb26e67bd6e678c8ed19e25ce.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a0ca5df4258213d7fc9fce80f65ce760.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a1f916d6039285c4ffb900cd654e418f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a203b91dad570bf05a58c3c3ddb529bf.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a365e82ed54697a52f27adcea1315fe8.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a7accba310e821da5505f71c03b76bdb.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-aa0d470430e6391eca720c7cfa44446f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-aa5c9ca6cf4fba00433b7aa3fa10671a.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ac9ceb44437becc3e9c4dbfebab7fc2d.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b1220a3c61f85cc0408deedb4c5f57a2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b358f7a51ece39a3247942b1feabdb29.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b57aaedfd8ebdf3931f25119dc6a5eb2.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b5c1596551c256e0e9cf02028595b092.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b6d128682ee29e471486354d486a1b90.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b6fd38ca30869792244804b04bc058da.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b7d203b051eff504ff59ddca7576b6a9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ba3de316d63c7e339987b16f41a0b879.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-bafff7a14c27403dcc6cf1432e8ea836.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-bd77e3c7f9e0b072d96af37f73d1aa32.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-be549ab72f0719d606a5c01e2c0219b6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c16ed9740b85badf16e86ea782a3062f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c1f94158256bb1f3bf665b053d895af9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c40533fdf4cc57177b12803598af7e59.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c4a687ac4f0c2766eefc9f77ed99cddf.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c8b71798409ccc126ee264a00aadcf21.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c99eda15fc26a2941579560f76c3a5cf.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cbaaefaaf326668277aa24dfa93c4d28.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cd145ce4a0ea18469358df53c207bc1b.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cdbce89e82cc1ab53a2decbf5819278f.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ce4884f96f11589608b76b726a755803.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cf2cc71752631e579e35b0e423bf2638.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cf6ff4e0f491ca0cf3038187a997b9b4.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cfb211578629b7e8153b37240de6a9d5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d0cf73942fea1c74edbdf0b3011f4656.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d2666cbed13462c5dc36fa2f15c202ca.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d3716376641d615e2995605b29bca7b6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-dac48066b5883d8b4551fc584f0c2a3e.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-dbea1af6dcd9860be40c3d18254338f5.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e11567fd2accf9957cd0d3c2be937d87.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e2ead7ea7da0437f085f42ffc05f8d13.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e480d9c614742d05f0e78f274f1e69e6.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e4bca6cfa53e499cae0a6be4894a90e9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e51ef413167c6e14e0c0fdcc585f2fc9.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e5f453bb04da18eed01675eeebd88bf8.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e656f091b9dc4709722c9f4b84d3c797.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ec181b795ac1fb5a50d700b6e996d745.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ee8bae97908d5147b423f77ad0d3c1bb.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f0f13b5c60e0af5553bd359f5513be1b.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f2b54d4e7be0eaefe1c2c56836fa5368.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f56414bf9bced67990def8660e306759.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f5d079153c99a25b9be5b8583c4cc8a7.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f6032fc06eb20480f096199713f70885.woff2 +0 -0
- package/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f8ee5d36068a42b51d0e4a1116cfcec1.woff2 +0 -0
- package/embedded/chalk-whiteboard/index.css +1 -0
- package/embedded/chalk-whiteboard/index.html +17 -0
- package/embedded/chalk-whiteboard/licenses/Excalidraw.txt +21 -0
- package/embedded/chalk-whiteboard/licenses/MathJax.txt +202 -0
- package/embedded/chalk-whiteboard/mathjax/tex-svg.js +1 -0
- package/embedded/chalk-whiteboard/mathjax-config.js +1 -0
- package/embedded/chalk-whiteboard/renderer.js +4114 -0
- package/ios/ChalkCallKitManager.swift +385 -0
- package/ios/ChalkCallKitModule.swift +120 -0
- package/ios/ChalkCallKitModuleBridge.m +14 -0
- package/ios/ChalkWhiteboardAssets.swift +41 -0
- package/ios/ChalkWhiteboardAssetsBridge.m +10 -0
- package/package.json +184 -0
- package/src/android/connection-service.test.ts +114 -0
- package/src/android/connection-service.ts +106 -0
- package/src/android.ts +1 -0
- package/src/callkit/callkit.test.ts +95 -0
- package/src/callkit/callkit.ts +135 -0
- package/src/callkit/resolve-space-callkit-options.test.ts +68 -0
- package/src/callkit/resolve-space-callkit-options.ts +34 -0
- package/src/client.test.ts +12 -0
- package/src/client.ts +7 -0
- package/src/clipboard-store.ts +108 -0
- package/src/clipboard.test.ts +79 -0
- package/src/clipboard.ts +36 -0
- package/src/components/Chalk.test.tsx +213 -0
- package/src/components/Chalk.tsx +333 -0
- package/src/components/ChatMessageList.tsx +209 -0
- package/src/components/EmbeddedWhiteboard.test.tsx +92 -0
- package/src/components/EmbeddedWhiteboard.tsx +260 -0
- package/src/components/Entrance.test.tsx +19 -0
- package/src/components/Entrance.tsx +41 -0
- package/src/components/EntranceView.android.test.tsx +100 -0
- package/src/components/EntranceView.android.tsx +274 -0
- package/src/components/EntranceView.ios-pad.test.tsx +160 -0
- package/src/components/EntranceView.ios-pad.tsx +326 -0
- package/src/components/EntranceView.ios-phone.test.tsx +137 -0
- package/src/components/EntranceView.ios-phone.tsx +271 -0
- package/src/components/EntranceView.macos.tsx +278 -0
- package/src/components/EntranceView.test.tsx +15 -0
- package/src/components/EntranceView.tsx +38 -0
- package/src/components/FaceAvatar.tsx +120 -0
- package/src/components/GradientSurface.tsx +23 -0
- package/src/components/LogoElements.test.tsx +60 -0
- package/src/components/LogoElements.tsx +119 -0
- package/src/components/MediaView.tsx +76 -0
- package/src/components/ReactionPicker.test.tsx +19 -0
- package/src/components/ReactionPicker.tsx +98 -0
- package/src/components/RtcVideoView.test.tsx +12 -0
- package/src/components/RtcVideoView.tsx +15 -0
- package/src/components/SpaceView.android.test.tsx +11 -0
- package/src/components/SpaceView.android.tsx +1 -0
- package/src/components/SpaceView.ios-pad.test.tsx +11 -0
- package/src/components/SpaceView.ios-pad.tsx +1 -0
- package/src/components/SpaceView.ios-phone.test.tsx +11 -0
- package/src/components/SpaceView.ios-phone.tsx +1 -0
- package/src/components/SpaceView.macos.test.tsx +11 -0
- package/src/components/SpaceView.macos.tsx +1 -0
- package/src/components/SpaceView.shared.test.tsx +115 -0
- package/src/components/SpaceView.shared.tsx +87 -0
- package/src/components/SpaceView.test.tsx +15 -0
- package/src/components/SpaceView.tsx +52 -0
- package/src/components/android-connection-service-controller.test.ts +80 -0
- package/src/components/android-connection-service-controller.ts +132 -0
- package/src/components/episode-diagnostic-render-observer.test.ts +24 -0
- package/src/components/episode-diagnostic-render-observer.ts +12 -0
- package/src/components/native-animation-controller.test.ts +47 -0
- package/src/components/native-animation-controller.ts +36 -0
- package/src/components/native-chat.test.ts +22 -0
- package/src/components/native-chat.ts +23 -0
- package/src/components/native-entrance/entrance-controller-store.test.ts +75 -0
- package/src/components/native-entrance/entrance-controller-store.ts +112 -0
- package/src/components/native-entrance/useEntranceController.ts +60 -0
- package/src/components/native-joining-loading-animation.ts +26 -0
- package/src/components/native-media-visibility.test.ts +77 -0
- package/src/components/native-media-visibility.ts +18 -0
- package/src/components/native-space-callkit-controller.test.ts +62 -0
- package/src/components/native-space-callkit-controller.ts +131 -0
- package/src/components/native-space-view/AppearanceSettings.test.tsx +56 -0
- package/src/components/native-space-view/AppearanceSettings.tsx +114 -0
- package/src/components/native-space-view/ParticipantActionSheet.test.tsx +18 -0
- package/src/components/native-space-view/ParticipantActionSheet.tsx +99 -0
- package/src/components/native-space-view/SettingsSheet.test.tsx +17 -0
- package/src/components/native-space-view/SettingsSheet.tsx +164 -0
- package/src/components/native-space-view/SpaceActionMenu.test.tsx +110 -0
- package/src/components/native-space-view/SpaceActionMenu.tsx +78 -0
- package/src/components/native-space-view/SpaceBottomDock.android.test.tsx +61 -0
- package/src/components/native-space-view/SpaceBottomDock.android.tsx +115 -0
- package/src/components/native-space-view/SpaceChatSheet.test.tsx +18 -0
- package/src/components/native-space-view/SpaceChatSheet.tsx +179 -0
- package/src/components/native-space-view/SpaceGrid.android.tsx +323 -0
- package/src/components/native-space-view/SpaceMoreSheet.test.tsx +15 -0
- package/src/components/native-space-view/SpaceMoreSheet.tsx +161 -0
- package/src/components/native-space-view/SpacePanelSheet.test.tsx +15 -0
- package/src/components/native-space-view/SpacePanelSheet.tsx +45 -0
- package/src/components/native-space-view/SpacePeopleSheet.test.tsx +13 -0
- package/src/components/native-space-view/SpacePeopleSheet.tsx +116 -0
- package/src/components/native-space-view/SpaceStage.android.tsx +372 -0
- package/src/components/native-space-view/SpaceSurfacePrimitives.test.tsx +12 -0
- package/src/components/native-space-view/SpaceSurfacePrimitives.tsx +75 -0
- package/src/components/native-space-view/SpaceTopBar.android.test.tsx +43 -0
- package/src/components/native-space-view/SpaceTopBar.android.tsx +97 -0
- package/src/components/native-space-view/SpaceWhiteboardSurface.test.tsx +85 -0
- package/src/components/native-space-view/SpaceWhiteboardSurface.tsx +69 -0
- package/src/components/native-space-view/diagnostics.test.ts +31 -0
- package/src/components/native-space-view/diagnostics.ts +84 -0
- package/src/components/native-space-view/format-space-duration.test.ts +13 -0
- package/src/components/native-space-view/format-space-duration.ts +3 -0
- package/src/components/native-space-view/native-space-grid-keys.test.ts +11 -0
- package/src/components/native-space-view/native-space-grid-keys.ts +6 -0
- package/src/components/native-space-view/native-space-page-store.test.ts +23 -0
- package/src/components/native-space-view/native-space-page-store.ts +41 -0
- package/src/components/native-space-view/screen-share-availability.ts +21 -0
- package/src/components/native-space-view/space-chat-attachments.test.ts +33 -0
- package/src/components/native-space-view/space-chat-attachments.ts +39 -0
- package/src/components/native-space-view/space-panel-layout.ts +10 -0
- package/src/components/native-space-view/space-progressive-surface-helpers.test.ts +24 -0
- package/src/components/native-space-view/space-progressive-surface-helpers.ts +33 -0
- package/src/components/native-space-view/space-progressive-surface-types.ts +3 -0
- package/src/components/native-space-view/types.ts +25 -0
- package/src/components/native-space-view/useSpaceViewController.contract.test.ts +10 -0
- package/src/components/native-space-view/useSpaceViewController.contract.ts +34 -0
- package/src/components/native-space-view/useSpaceViewController.test.ts +105 -0
- package/src/components/native-space-view/useSpaceViewController.ts +396 -0
- package/src/components/native-space-view/useSpaceViewDerived.test.ts +58 -0
- package/src/components/native-space-view/useSpaceViewDerived.ts +29 -0
- package/src/components/native-space-view/useSpaceViewPanels.controlled.test.ts +40 -0
- package/src/components/native-space-view/useSpaceViewPanels.test.ts +73 -0
- package/src/components/native-space-view/useSpaceViewPanels.ts +170 -0
- package/src/components/rtc-video-view-availability.ts +16 -0
- package/src/components/space-lifecycle.test.ts +19 -0
- package/src/components/space-lifecycle.ts +2 -0
- package/src/components/useAndroidConnectionService.ts +55 -0
- package/src/context/space-client-context.test.tsx +10 -0
- package/src/context/space-client-context.tsx +21 -0
- package/src/diagnostics.test.ts +29 -0
- package/src/diagnostics.ts +187 -0
- package/src/hooks/entrance-preview-store.test.ts +79 -0
- package/src/hooks/entrance-preview-store.ts +99 -0
- package/src/hooks/external-store.ts +18 -0
- package/src/hooks/space-hooks.test.ts +76 -0
- package/src/hooks/space-hooks.ts +43 -0
- package/src/hooks/useEntrancePreview.ts +26 -0
- package/src/hooks/useLayout.test.ts +16 -0
- package/src/hooks/useLayout.ts +37 -0
- package/src/hooks/usePanels.ts +30 -0
- package/src/index.ts +10 -0
- package/src/invites.test.ts +56 -0
- package/src/invites.ts +43 -0
- package/src/ios-pad.ts +1 -0
- package/src/ios-phone.ts +1 -0
- package/src/ios.ts +1 -0
- package/src/macos.ts +1 -0
- package/src/media/native-webrtc.ts +11 -0
- package/src/platform/platform.ts +34 -0
- package/src/public-surface.test.ts +25 -0
- package/src/runtime.test.ts +83 -0
- package/src/runtime.ts +142 -0
- package/src/space-client/create-native-space-client.test.ts +247 -0
- package/src/space-client/create-native-space-client.ts +280 -0
- package/src/telemetry.test.ts +143 -0
- package/src/telemetry.ts +234 -0
- package/src/test-support/test-renderer.test.ts +9 -0
- package/src/test-support/test-renderer.ts +26 -0
- package/src/types/hugeicons-direct.d.ts +4 -0
- package/src/types/react-native-safe-area-context.d.ts +8 -0
- package/src/ui/appearance.test.ts +50 -0
- package/src/ui/appearance.ts +770 -0
- package/src/ui/native-appearance-context.controlled.test.tsx +41 -0
- package/src/ui/native-appearance-context.test.tsx +14 -0
- package/src/ui/native-appearance-context.tsx +74 -0
- package/src/ui/native-theme.test.ts +34 -0
- package/src/ui/native-theme.test.tsx +14 -0
- package/src/ui/native-theme.tsx +54 -0
- package/src/ui/native-types.ts +40 -0
- package/src/ui/participant-avatar.test.ts +29 -0
- package/src/ui/participant-avatar.ts +47 -0
- package/src/ui/theme-tokens.test.ts +14 -0
- package/src/ui/theme-tokens.ts +41 -0
- package/src/ui/theme.test.ts +36 -0
- package/src/ui/theme.ts +214 -0
- package/src/utils/build-chalk-invite-link.test.ts +12 -0
- package/src/utils/build-chalk-invite-link.ts +5 -0
- package/src/utils/ios-simulator.test.ts +96 -0
- package/src/utils/ios-simulator.ts +125 -0
- package/src/utils/native-space-layout.test.ts +170 -0
- package/src/utils/native-space-layout.ts +135 -0
- package/src/whiteboard/embedded-whiteboard-assets.test.ts +31 -0
- 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
|
+
}
|