@q9labsai/chalk-react-native 4.1.17 → 5.0.1
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/README.md +134 -29
- package/android/build.gradle +35 -0
- package/android/compatibility/ModuleApiCompatibility.java +215 -0
- package/android/src/main/AndroidManifest.xml +2 -1
- package/android/src/main/java/ai/q9labs/chalk/reactnative/ChalkSpaceForegroundService.java +105 -31
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAndroidConnectionServicePackage.kt +2 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkAudioRouteModule.kt +137 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/ChalkCallServiceModule.kt +32 -0
- package/android/src/main/kotlin/ai/q9labs/chalk/reactnative/CommunicationDeviceListener.kt +23 -0
- package/android/src/test/kotlin/ai/q9labs/chalk/compatibility/UnsafeSignatures.kt +29 -0
- package/dist/android/call-service.d.ts +4 -0
- package/dist/android/call-service.d.ts.map +1 -0
- package/dist/avatar/FaceAvatar.d.ts +19 -0
- package/dist/avatar/FaceAvatar.d.ts.map +1 -0
- package/dist/avatar/tile-avatar-size.d.ts +3 -0
- package/dist/avatar/tile-avatar-size.d.ts.map +1 -0
- package/dist/chunk-GYVZSOGQ.js +30 -0
- package/dist/chunk-IHE6EA3T.js +25 -0
- package/dist/chunk-OIBT2FNM.js +1479 -0
- package/dist/client.d.ts +1 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +185 -2
- package/dist/components/EmbeddedWhiteboard.d.ts.map +1 -1
- package/dist/components/native-media-visibility.d.ts +3 -2
- package/dist/components/native-media-visibility.d.ts.map +1 -1
- package/dist/components/useAndroidCallService.d.ts +8 -0
- package/dist/components/useAndroidCallService.d.ts.map +1 -0
- package/dist/dev.d.ts +10 -0
- package/dist/dev.d.ts.map +1 -0
- package/dist/dev.js +10 -0
- package/dist/dock/Dock.d.ts +23 -0
- package/dist/dock/Dock.d.ts.map +1 -0
- package/dist/dock/LeaveMenu.d.ts +12 -0
- package/dist/dock/LeaveMenu.d.ts.map +1 -0
- package/dist/dock/MoreSheet.d.ts +17 -0
- package/dist/dock/MoreSheet.d.ts.map +1 -0
- package/dist/dock/ReactionBurst.d.ts +8 -0
- package/dist/dock/ReactionBurst.d.ts.map +1 -0
- package/dist/dock/RoutePicker.d.ts +16 -0
- package/dist/dock/RoutePicker.d.ts.map +1 -0
- package/dist/dock/audio-route.d.ts +25 -0
- package/dist/dock/audio-route.d.ts.map +1 -0
- package/dist/error-YOPTEH5N.wav +0 -0
- package/dist/frame/CallFrame.d.ts +17 -0
- package/dist/frame/CallFrame.d.ts.map +1 -0
- package/dist/frame/Chalk.d.ts +40 -0
- package/dist/frame/Chalk.d.ts.map +1 -0
- package/dist/frame/back-handler.d.ts +6 -0
- package/dist/frame/back-handler.d.ts.map +1 -0
- package/dist/frame/dev-scenario.d.ts +28 -0
- package/dist/frame/dev-scenario.d.ts.map +1 -0
- package/dist/frame/device-layout.d.ts +16 -0
- package/dist/frame/device-layout.d.ts.map +1 -0
- package/dist/frame/measurement.d.ts +28 -0
- package/dist/frame/measurement.d.ts.map +1 -0
- package/dist/frame/portal.d.ts +24 -0
- package/dist/frame/portal.d.ts.map +1 -0
- package/dist/frame/preferences.d.ts +21 -0
- package/dist/frame/preferences.d.ts.map +1 -0
- package/dist/frame/regions.d.ts +25 -0
- package/dist/frame/regions.d.ts.map +1 -0
- package/dist/hand-DFWVXPH2.wav +0 -0
- package/dist/haptics/haptics.d.ts +12 -0
- package/dist/haptics/haptics.d.ts.map +1 -0
- package/dist/header/CallDetailsSheet.d.ts +18 -0
- package/dist/header/CallDetailsSheet.d.ts.map +1 -0
- package/dist/header/Header.d.ts +17 -0
- package/dist/header/Header.d.ts.map +1 -0
- package/dist/header/QrCode.d.ts +6 -0
- package/dist/header/QrCode.d.ts.map +1 -0
- package/dist/icons/Icon.d.ts +12 -0
- package/dist/icons/Icon.d.ts.map +1 -0
- package/dist/icons/icon-element.d.ts +24 -0
- package/dist/icons/icon-element.d.ts.map +1 -0
- package/dist/icons/icon-paths.d.ts +530 -0
- package/dist/icons/icon-paths.d.ts.map +1 -0
- package/dist/index.d.ts +6 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2956 -38
- package/dist/join-Z6RL5AHE.wav +0 -0
- package/dist/knock-4VBQSHK4.wav +0 -0
- package/dist/leave-MQLZOWQD.wav +0 -0
- package/dist/limbo/Limbo.d.ts +25 -0
- package/dist/limbo/Limbo.d.ts.map +1 -0
- package/dist/limbo/Veil.d.ts +10 -0
- package/dist/limbo/Veil.d.ts.map +1 -0
- package/dist/media/native-capture-error.d.ts +7 -0
- package/dist/media/native-capture-error.d.ts.map +1 -0
- package/dist/message-6Y6WJGTB.wav +0 -0
- package/dist/motion/MovingFrame.d.ts +36 -0
- package/dist/motion/MovingFrame.d.ts.map +1 -0
- package/dist/motion/motion.d.ts +82 -0
- package/dist/motion/motion.d.ts.map +1 -0
- package/dist/motion/presence.d.ts +6 -0
- package/dist/motion/presence.d.ts.map +1 -0
- package/dist/motion/press.d.ts +15 -0
- package/dist/motion/press.d.ts.map +1 -0
- package/dist/mute-H5SJFXVI.wav +0 -0
- package/dist/primitives/BottomSheet.d.ts +36 -0
- package/dist/primitives/BottomSheet.d.ts.map +1 -0
- package/dist/primitives/ChalkText.d.ts +13 -0
- package/dist/primitives/ChalkText.d.ts.map +1 -0
- package/dist/primitives/CopyButton.d.ts +11 -0
- package/dist/primitives/CopyButton.d.ts.map +1 -0
- package/dist/primitives/IconButton.d.ts +26 -0
- package/dist/primitives/IconButton.d.ts.map +1 -0
- package/dist/primitives/Menu.d.ts +39 -0
- package/dist/primitives/Menu.d.ts.map +1 -0
- package/dist/primitives/NameTag.d.ts +19 -0
- package/dist/primitives/NameTag.d.ts.map +1 -0
- package/dist/primitives/PillButton.d.ts +19 -0
- package/dist/primitives/PillButton.d.ts.map +1 -0
- package/dist/primitives/SegmentedControl.d.ts +17 -0
- package/dist/primitives/SegmentedControl.d.ts.map +1 -0
- package/dist/primitives/SheetGroup.d.ts +24 -0
- package/dist/primitives/SheetGroup.d.ts.map +1 -0
- package/dist/primitives/Switch.d.ts +9 -0
- package/dist/primitives/Switch.d.ts.map +1 -0
- package/dist/primitives/TileShell.d.ts +18 -0
- package/dist/primitives/TileShell.d.ts.map +1 -0
- package/dist/primitives/announce.d.ts +3 -0
- package/dist/primitives/announce.d.ts.map +1 -0
- package/dist/primitives/menu-placement.d.ts +32 -0
- package/dist/primitives/menu-placement.d.ts.map +1 -0
- package/dist/primitives/toast/Toast.d.ts +8 -0
- package/dist/primitives/toast/Toast.d.ts.map +1 -0
- package/dist/primitives/toast/ToastStack.d.ts +18 -0
- package/dist/primitives/toast/ToastStack.d.ts.map +1 -0
- package/dist/primitives/toast/toast-store.d.ts +39 -0
- package/dist/primitives/toast/toast-store.d.ts.map +1 -0
- package/dist/recording-Q4GB77Y4.wav +0 -0
- package/dist/sheets/people-chat/ChatNotices.d.ts +14 -0
- package/dist/sheets/people-chat/ChatNotices.d.ts.map +1 -0
- package/dist/sheets/people-chat/ChatTab.d.ts +6 -0
- package/dist/sheets/people-chat/ChatTab.d.ts.map +1 -0
- package/dist/sheets/people-chat/Composer.d.ts +7 -0
- package/dist/sheets/people-chat/Composer.d.ts.map +1 -0
- package/dist/sheets/people-chat/PeopleChatSheet.d.ts +17 -0
- package/dist/sheets/people-chat/PeopleChatSheet.d.ts.map +1 -0
- package/dist/sheets/people-chat/PeopleTab.d.ts +3 -0
- package/dist/sheets/people-chat/PeopleTab.d.ts.map +1 -0
- package/dist/sheets/people-chat/PhotoViewer.d.ts +19 -0
- package/dist/sheets/people-chat/PhotoViewer.d.ts.map +1 -0
- package/dist/sheets/people-chat/TextField.d.ts +4 -0
- package/dist/sheets/people-chat/TextField.d.ts.map +1 -0
- package/dist/sheets/people-chat/attachments.d.ts +33 -0
- package/dist/sheets/people-chat/attachments.d.ts.map +1 -0
- package/dist/sheets/people-chat/chat-model.d.ts +64 -0
- package/dist/sheets/people-chat/chat-model.d.ts.map +1 -0
- package/dist/sheets/people-chat/people-model.d.ts +43 -0
- package/dist/sheets/people-chat/people-model.d.ts.map +1 -0
- package/dist/sounds/sounds.d.ts +33 -0
- package/dist/sounds/sounds.d.ts.map +1 -0
- package/dist/space-client/create-native-space-client.d.ts +0 -4
- package/dist/space-client/create-native-space-client.d.ts.map +1 -1
- package/dist/space-client/random-uuid.d.ts +7 -0
- package/dist/space-client/random-uuid.d.ts.map +1 -0
- package/dist/stage/ContentTile.d.ts +18 -0
- package/dist/stage/ContentTile.d.ts.map +1 -0
- package/dist/stage/ParticipantTile.d.ts +18 -0
- package/dist/stage/ParticipantTile.d.ts.map +1 -0
- package/dist/stage/Stage.d.ts +14 -0
- package/dist/stage/Stage.d.ts.map +1 -0
- package/dist/stage/TileSheet.d.ts +12 -0
- package/dist/stage/TileSheet.d.ts.map +1 -0
- package/dist/stage/camera.d.ts +7 -0
- package/dist/stage/camera.d.ts.map +1 -0
- package/dist/stage/layout.d.ts +57 -0
- package/dist/stage/layout.d.ts.map +1 -0
- package/dist/stage/space-selector.d.ts +10 -0
- package/dist/stage/space-selector.d.ts.map +1 -0
- package/dist/stage/stage-view.d.ts +23 -0
- package/dist/stage/stage-view.d.ts.map +1 -0
- package/dist/status/CallOverlays.d.ts +17 -0
- package/dist/status/CallOverlays.d.ts.map +1 -0
- package/dist/status/ChalkArrival.d.ts +24 -0
- package/dist/status/ChalkArrival.d.ts.map +1 -0
- package/dist/status/StatusPage.d.ts +14 -0
- package/dist/status/StatusPage.d.ts.map +1 -0
- package/dist/status/call-screen.d.ts +20 -0
- package/dist/status/call-screen.d.ts.map +1 -0
- package/dist/test-VD2KAM4D.wav +0 -0
- package/dist/theme/theme.d.ts +15 -0
- package/dist/theme/theme.d.ts.map +1 -0
- package/dist/theme/tokens.d.ts +248 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/toasts/CallEventToasts.d.ts +21 -0
- package/dist/toasts/CallEventToasts.d.ts.map +1 -0
- package/dist/toasts/notices.d.ts +34 -0
- package/dist/toasts/notices.d.ts.map +1 -0
- package/dist/ui/ChalkUI.d.ts +12 -0
- package/dist/ui/ChalkUI.d.ts.map +1 -0
- package/dist/ui.d.ts +25 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +77 -0
- package/dist/unmute-2XR2LICU.wav +0 -0
- package/embedded/chalk-whiteboard/asset-manifest.json +2 -2
- package/embedded/chalk-whiteboard/renderer.js +510 -510
- package/ios/ChalkAudioRouteModule.swift +93 -0
- package/ios/ChalkAudioRouteModuleBridge.m +9 -0
- package/package.json +46 -76
- package/src/android/call-service.ts +19 -0
- package/src/avatar/FaceAvatar.tsx +145 -0
- package/src/avatar/tile-avatar-size.ts +4 -0
- package/src/client.ts +1 -5
- package/src/components/EmbeddedWhiteboard.tsx +14 -71
- package/src/components/native-media-visibility.ts +1 -2
- package/src/components/useAndroidCallService.ts +41 -0
- package/src/dev.ts +9 -0
- package/src/dock/Dock.tsx +95 -0
- package/src/dock/LeaveMenu.tsx +21 -0
- package/src/dock/MoreSheet.tsx +233 -0
- package/src/dock/ReactionBurst.tsx +55 -0
- package/src/dock/RoutePicker.tsx +42 -0
- package/src/dock/audio-route.ts +69 -0
- package/src/frame/CallFrame.tsx +209 -0
- package/src/frame/Chalk.tsx +83 -0
- package/src/frame/back-handler.ts +19 -0
- package/src/frame/dev-scenario.ts +48 -0
- package/src/frame/device-layout.tsx +31 -0
- package/src/frame/measurement.ts +44 -0
- package/src/frame/portal.tsx +107 -0
- package/src/frame/preferences.tsx +48 -0
- package/src/frame/regions.test.ts +38 -0
- package/src/frame/regions.ts +60 -0
- package/src/haptics/haptics.ts +19 -0
- package/src/header/CallDetailsSheet.tsx +139 -0
- package/src/header/Header.tsx +107 -0
- package/src/header/QrCode.tsx +34 -0
- package/src/icons/Icon.tsx +35 -0
- package/src/icons/icon-element.ts +11 -0
- package/src/icons/icon-paths.ts +199 -0
- package/src/index.ts +6 -9
- package/src/limbo/Limbo.tsx +159 -0
- package/src/limbo/Veil.tsx +36 -0
- package/src/media/native-capture-error.test.ts +19 -0
- package/src/media/native-capture-error.ts +13 -0
- package/src/motion/MovingFrame.tsx +101 -0
- package/src/motion/motion.ts +33 -0
- package/src/motion/presence.ts +20 -0
- package/src/motion/press.ts +35 -0
- package/src/primitives/BottomSheet.tsx +211 -0
- package/src/primitives/ChalkText.tsx +23 -0
- package/src/primitives/CopyButton.tsx +78 -0
- package/src/primitives/IconButton.tsx +90 -0
- package/src/primitives/Menu.tsx +212 -0
- package/src/primitives/NameTag.tsx +68 -0
- package/src/primitives/PillButton.tsx +56 -0
- package/src/primitives/SegmentedControl.tsx +55 -0
- package/src/primitives/SheetGroup.tsx +72 -0
- package/src/primitives/Switch.tsx +39 -0
- package/src/primitives/TileShell.tsx +53 -0
- package/src/primitives/announce.ts +7 -0
- package/src/primitives/menu-placement.test.ts +50 -0
- package/src/primitives/menu-placement.ts +43 -0
- package/src/primitives/toast/Toast.tsx +50 -0
- package/src/primitives/toast/ToastStack.tsx +89 -0
- package/src/primitives/toast/toast-store.ts +86 -0
- package/src/sheets/people-chat/ChatNotices.tsx +69 -0
- package/src/sheets/people-chat/ChatTab.tsx +186 -0
- package/src/sheets/people-chat/Composer.tsx +182 -0
- package/src/sheets/people-chat/PeopleChatSheet.tsx +100 -0
- package/src/sheets/people-chat/PeopleTab.tsx +326 -0
- package/src/sheets/people-chat/PhotoViewer.tsx +132 -0
- package/src/sheets/people-chat/TextField.tsx +14 -0
- package/src/sheets/people-chat/attachments.tsx +183 -0
- package/src/sheets/people-chat/chat-model.ts +157 -0
- package/src/sheets/people-chat/people-chat-model.test.ts +98 -0
- package/src/sheets/people-chat/people-model.ts +68 -0
- package/src/sounds/assets/error.wav +0 -0
- package/src/sounds/assets/hand.wav +0 -0
- package/src/sounds/assets/join.wav +0 -0
- package/src/sounds/assets/knock.wav +0 -0
- package/src/sounds/assets/leave.wav +0 -0
- package/src/sounds/assets/message.wav +0 -0
- package/src/sounds/assets/mute.wav +0 -0
- package/src/sounds/assets/recording.wav +0 -0
- package/src/sounds/assets/test.wav +0 -0
- package/src/sounds/assets/unmute.wav +0 -0
- package/src/sounds/assets.d.ts +5 -0
- package/src/sounds/sounds.ts +50 -0
- package/src/space-client/create-native-space-client.ts +20 -181
- package/src/space-client/random-uuid.ts +17 -0
- package/src/space-client/whiteboard-watchdog.test.ts +23 -0
- package/src/stage/ContentTile.tsx +100 -0
- package/src/stage/ParticipantTile.tsx +140 -0
- package/src/stage/Stage.tsx +152 -0
- package/src/stage/TileSheet.tsx +116 -0
- package/src/stage/camera.ts +20 -0
- package/src/stage/layout.test.ts +77 -0
- package/src/stage/layout.ts +226 -0
- package/src/stage/space-selector.ts +31 -0
- package/src/stage/stage-view.tsx +68 -0
- package/src/status/CallOverlays.tsx +47 -0
- package/src/status/ChalkArrival.tsx +53 -0
- package/src/status/StatusPage.tsx +123 -0
- package/src/status/call-screen.test.ts +42 -0
- package/src/status/call-screen.ts +29 -0
- package/src/theme/theme.tsx +28 -0
- package/src/theme/tokens.ts +247 -0
- package/src/toasts/CallEventToasts.tsx +192 -0
- package/src/toasts/notices.test.ts +92 -0
- package/src/toasts/notices.ts +62 -0
- package/src/ui/ChalkUI.tsx +49 -0
- package/src/ui.ts +24 -0
- package/dist/android.d.ts +0 -2
- package/dist/android.d.ts.map +0 -1
- package/dist/android.js +0 -62
- package/dist/chunk-2OS7SSXE.js +0 -552
- package/dist/chunk-5DQ4KBRH.js +0 -690
- package/dist/chunk-ITLUHTVS.js +0 -5271
- package/dist/chunk-JB4LNWVP.js +0 -247
- package/dist/components/Chalk.d.ts +0 -79
- package/dist/components/Chalk.d.ts.map +0 -1
- package/dist/components/ChatMessageList.d.ts +0 -11
- package/dist/components/ChatMessageList.d.ts.map +0 -1
- package/dist/components/Entrance.d.ts +0 -22
- package/dist/components/Entrance.d.ts.map +0 -1
- package/dist/components/EntranceView.android.d.ts +0 -4
- package/dist/components/EntranceView.android.d.ts.map +0 -1
- package/dist/components/EntranceView.d.ts +0 -18
- package/dist/components/EntranceView.d.ts.map +0 -1
- package/dist/components/EntranceView.ios-pad.d.ts +0 -3
- package/dist/components/EntranceView.ios-pad.d.ts.map +0 -1
- package/dist/components/EntranceView.ios-phone.d.ts +0 -3
- package/dist/components/EntranceView.ios-phone.d.ts.map +0 -1
- package/dist/components/EntranceView.macos.d.ts +0 -4
- package/dist/components/EntranceView.macos.d.ts.map +0 -1
- package/dist/components/FaceAvatar.d.ts +0 -16
- package/dist/components/FaceAvatar.d.ts.map +0 -1
- package/dist/components/GradientSurface.d.ts +0 -14
- package/dist/components/GradientSurface.d.ts.map +0 -1
- package/dist/components/MediaView.d.ts +0 -14
- package/dist/components/MediaView.d.ts.map +0 -1
- package/dist/components/ReactionPicker.d.ts +0 -10
- package/dist/components/ReactionPicker.d.ts.map +0 -1
- package/dist/components/SpaceView.android.d.ts +0 -2
- package/dist/components/SpaceView.android.d.ts.map +0 -1
- package/dist/components/SpaceView.d.ts +0 -33
- package/dist/components/SpaceView.d.ts.map +0 -1
- package/dist/components/SpaceView.ios-pad.d.ts +0 -2
- package/dist/components/SpaceView.ios-pad.d.ts.map +0 -1
- package/dist/components/SpaceView.ios-phone.d.ts +0 -2
- package/dist/components/SpaceView.ios-phone.d.ts.map +0 -1
- package/dist/components/SpaceView.macos.d.ts +0 -2
- package/dist/components/SpaceView.macos.d.ts.map +0 -1
- package/dist/components/SpaceView.shared.d.ts +0 -3
- package/dist/components/SpaceView.shared.d.ts.map +0 -1
- package/dist/components/episode-diagnostic-render-observer.d.ts +0 -2
- package/dist/components/episode-diagnostic-render-observer.d.ts.map +0 -1
- package/dist/components/logo/Logo.d.ts +0 -11
- package/dist/components/logo/Logo.d.ts.map +0 -1
- package/dist/components/native-animation-controller.d.ts +0 -7
- package/dist/components/native-animation-controller.d.ts.map +0 -1
- package/dist/components/native-chat.d.ts +0 -8
- package/dist/components/native-chat.d.ts.map +0 -1
- package/dist/components/native-entrance/entrance-controller-store.d.ts +0 -34
- package/dist/components/native-entrance/entrance-controller-store.d.ts.map +0 -1
- package/dist/components/native-entrance/useEntranceController.d.ts +0 -19
- package/dist/components/native-entrance/useEntranceController.d.ts.map +0 -1
- package/dist/components/native-joining-loading-animation.d.ts +0 -9
- package/dist/components/native-joining-loading-animation.d.ts.map +0 -1
- package/dist/components/native-space-view/AppearanceSettings.d.ts +0 -2
- package/dist/components/native-space-view/AppearanceSettings.d.ts.map +0 -1
- package/dist/components/native-space-view/FeedbackSheet.d.ts +0 -12
- package/dist/components/native-space-view/FeedbackSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/ParticipantActionSheet.d.ts +0 -9
- package/dist/components/native-space-view/ParticipantActionSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/SettingsSheet.d.ts +0 -7
- package/dist/components/native-space-view/SettingsSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceActionMenu.d.ts +0 -10
- package/dist/components/native-space-view/SpaceActionMenu.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceBottomDock.android.d.ts +0 -4
- package/dist/components/native-space-view/SpaceBottomDock.android.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceChatAttachment.d.ts +0 -8
- package/dist/components/native-space-view/SpaceChatAttachment.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceChatSheet.d.ts +0 -5
- package/dist/components/native-space-view/SpaceChatSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceGrid.android.d.ts +0 -8
- package/dist/components/native-space-view/SpaceGrid.android.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceMoreSheet.d.ts +0 -7
- package/dist/components/native-space-view/SpaceMoreSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/SpacePanelSheet.d.ts +0 -5
- package/dist/components/native-space-view/SpacePanelSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/SpacePeopleSheet.d.ts +0 -5
- package/dist/components/native-space-view/SpacePeopleSheet.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceStage.android.d.ts +0 -29
- package/dist/components/native-space-view/SpaceStage.android.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts +0 -30
- package/dist/components/native-space-view/SpaceSurfacePrimitives.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceTopBar.android.d.ts +0 -11
- package/dist/components/native-space-view/SpaceTopBar.android.d.ts.map +0 -1
- package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts +0 -15
- package/dist/components/native-space-view/SpaceWhiteboardSurface.d.ts.map +0 -1
- package/dist/components/native-space-view/diagnostics.d.ts +0 -48
- package/dist/components/native-space-view/diagnostics.d.ts.map +0 -1
- package/dist/components/native-space-view/format-space-duration.d.ts +0 -2
- package/dist/components/native-space-view/format-space-duration.d.ts.map +0 -1
- package/dist/components/native-space-view/native-space-grid-keys.d.ts +0 -3
- package/dist/components/native-space-view/native-space-grid-keys.d.ts.map +0 -1
- package/dist/components/native-space-view/native-space-page-store.d.ts +0 -8
- package/dist/components/native-space-view/native-space-page-store.d.ts.map +0 -1
- package/dist/components/native-space-view/space-chat-attachments.d.ts +0 -15
- package/dist/components/native-space-view/space-chat-attachments.d.ts.map +0 -1
- package/dist/components/native-space-view/space-panel-layout.d.ts +0 -10
- package/dist/components/native-space-view/space-panel-layout.d.ts.map +0 -1
- package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts +0 -16
- package/dist/components/native-space-view/space-progressive-surface-helpers.d.ts.map +0 -1
- package/dist/components/native-space-view/space-progressive-surface-types.d.ts +0 -3
- package/dist/components/native-space-view/space-progressive-surface-types.d.ts.map +0 -1
- package/dist/components/native-space-view/types.d.ts +0 -24
- package/dist/components/native-space-view/types.d.ts.map +0 -1
- package/dist/components/native-space-view/useSpaceViewController.contract.d.ts +0 -41
- package/dist/components/native-space-view/useSpaceViewController.contract.d.ts.map +0 -1
- package/dist/components/native-space-view/useSpaceViewController.d.ts +0 -156
- package/dist/components/native-space-view/useSpaceViewController.d.ts.map +0 -1
- package/dist/components/native-space-view/useSpaceViewDerived.d.ts +0 -12
- package/dist/components/native-space-view/useSpaceViewDerived.d.ts.map +0 -1
- package/dist/components/native-space-view/useSpaceViewPanels.d.ts +0 -70
- package/dist/components/native-space-view/useSpaceViewPanels.d.ts.map +0 -1
- package/dist/feedback/native-capture.d.ts +0 -9
- package/dist/feedback/native-capture.d.ts.map +0 -1
- package/dist/feedback/native-evidence.d.ts +0 -3
- package/dist/feedback/native-evidence.d.ts.map +0 -1
- package/dist/hooks/entrance-preview-store.d.ts +0 -16
- package/dist/hooks/entrance-preview-store.d.ts.map +0 -1
- package/dist/hooks/useEntrancePreview.d.ts +0 -7
- package/dist/hooks/useEntrancePreview.d.ts.map +0 -1
- package/dist/hooks/useLayout.d.ts +0 -16
- package/dist/hooks/useLayout.d.ts.map +0 -1
- package/dist/hooks/usePanels.d.ts +0 -12
- package/dist/hooks/usePanels.d.ts.map +0 -1
- package/dist/ios-pad.d.ts +0 -2
- package/dist/ios-pad.d.ts.map +0 -1
- package/dist/ios-pad.js +0 -62
- package/dist/ios-phone.d.ts +0 -2
- package/dist/ios-phone.d.ts.map +0 -1
- package/dist/ios-phone.js +0 -62
- package/dist/ios.d.ts +0 -2
- package/dist/ios.d.ts.map +0 -1
- package/dist/ios.js +0 -62
- package/dist/macos.d.ts +0 -2
- package/dist/macos.d.ts.map +0 -1
- package/dist/macos.js +0 -62
- package/dist/space-client/cloudflare-rtk-native.d.ts +0 -3
- package/dist/space-client/cloudflare-rtk-native.d.ts.map +0 -1
- package/dist/telemetry.d.ts +0 -63
- package/dist/telemetry.d.ts.map +0 -1
- package/dist/ui/appearance.d.ts +0 -246
- package/dist/ui/appearance.d.ts.map +0 -1
- package/dist/ui/appearance.js +0 -14
- package/dist/ui/native-appearance-context.d.ts +0 -15
- package/dist/ui/native-appearance-context.d.ts.map +0 -1
- package/dist/ui/native-theme.d.ts +0 -17
- package/dist/ui/native-theme.d.ts.map +0 -1
- package/dist/ui/native-types.d.ts +0 -38
- package/dist/ui/native-types.d.ts.map +0 -1
- package/dist/ui/participant-avatar.d.ts +0 -21
- package/dist/ui/participant-avatar.d.ts.map +0 -1
- package/dist/ui/theme-tokens.d.ts +0 -25
- package/dist/ui/theme-tokens.d.ts.map +0 -1
- package/dist/ui/theme.d.ts +0 -404
- package/dist/ui/theme.d.ts.map +0 -1
- package/dist/ui/theme.js +0 -8
- package/dist/utils/native-space-layout.d.ts +0 -42
- package/dist/utils/native-space-layout.d.ts.map +0 -1
- package/src/android.ts +0 -1
- package/src/components/Chalk.tsx +0 -363
- package/src/components/ChatMessageList.tsx +0 -209
- package/src/components/Entrance.tsx +0 -42
- package/src/components/EntranceView.android.tsx +0 -274
- package/src/components/EntranceView.ios-pad.tsx +0 -326
- package/src/components/EntranceView.ios-phone.tsx +0 -271
- package/src/components/EntranceView.macos.tsx +0 -278
- package/src/components/EntranceView.tsx +0 -38
- package/src/components/FaceAvatar.tsx +0 -120
- package/src/components/GradientSurface.tsx +0 -23
- package/src/components/MediaView.tsx +0 -76
- package/src/components/ReactionPicker.tsx +0 -98
- package/src/components/SpaceView.android.tsx +0 -1
- package/src/components/SpaceView.ios-pad.tsx +0 -1
- package/src/components/SpaceView.ios-phone.tsx +0 -1
- package/src/components/SpaceView.macos.tsx +0 -1
- package/src/components/SpaceView.shared.tsx +0 -98
- package/src/components/SpaceView.tsx +0 -54
- package/src/components/episode-diagnostic-render-observer.ts +0 -12
- package/src/components/logo/Logo.tsx +0 -309
- package/src/components/native-animation-controller.ts +0 -36
- package/src/components/native-chat.ts +0 -23
- package/src/components/native-entrance/entrance-controller-store.ts +0 -112
- package/src/components/native-entrance/useEntranceController.ts +0 -60
- package/src/components/native-joining-loading-animation.ts +0 -26
- package/src/components/native-space-view/AppearanceSettings.tsx +0 -114
- package/src/components/native-space-view/FeedbackSheet.tsx +0 -296
- package/src/components/native-space-view/ParticipantActionSheet.tsx +0 -99
- package/src/components/native-space-view/SettingsSheet.tsx +0 -164
- package/src/components/native-space-view/SpaceActionMenu.tsx +0 -109
- package/src/components/native-space-view/SpaceBottomDock.android.tsx +0 -115
- package/src/components/native-space-view/SpaceChatAttachment.tsx +0 -105
- package/src/components/native-space-view/SpaceChatSheet.tsx +0 -184
- package/src/components/native-space-view/SpaceGrid.android.tsx +0 -323
- package/src/components/native-space-view/SpaceMoreSheet.tsx +0 -190
- package/src/components/native-space-view/SpacePanelSheet.tsx +0 -45
- package/src/components/native-space-view/SpacePeopleSheet.tsx +0 -116
- package/src/components/native-space-view/SpaceStage.android.tsx +0 -372
- package/src/components/native-space-view/SpaceSurfacePrimitives.tsx +0 -75
- package/src/components/native-space-view/SpaceTopBar.android.tsx +0 -113
- package/src/components/native-space-view/SpaceWhiteboardSurface.tsx +0 -69
- package/src/components/native-space-view/diagnostics.ts +0 -84
- package/src/components/native-space-view/format-space-duration.ts +0 -3
- package/src/components/native-space-view/native-space-grid-keys.ts +0 -6
- package/src/components/native-space-view/native-space-page-store.ts +0 -41
- package/src/components/native-space-view/space-chat-attachments.test.ts +0 -26
- package/src/components/native-space-view/space-chat-attachments.ts +0 -37
- package/src/components/native-space-view/space-panel-layout.ts +0 -10
- package/src/components/native-space-view/space-progressive-surface-helpers.ts +0 -33
- package/src/components/native-space-view/space-progressive-surface-types.ts +0 -3
- package/src/components/native-space-view/types.ts +0 -25
- package/src/components/native-space-view/useSpaceViewController.contract.ts +0 -34
- package/src/components/native-space-view/useSpaceViewController.ts +0 -416
- package/src/components/native-space-view/useSpaceViewDerived.ts +0 -29
- package/src/components/native-space-view/useSpaceViewPanels.ts +0 -170
- package/src/feedback/native-capture.ts +0 -62
- package/src/feedback/native-evidence.ts +0 -37
- package/src/hooks/entrance-preview-store.ts +0 -99
- package/src/hooks/useEntrancePreview.ts +0 -26
- package/src/hooks/useLayout.ts +0 -37
- package/src/hooks/usePanels.ts +0 -30
- package/src/ios-pad.ts +0 -1
- package/src/ios-phone.ts +0 -1
- package/src/ios.ts +0 -1
- package/src/macos.ts +0 -1
- package/src/space-client/cloudflare-rtk-native.ts +0 -104
- package/src/telemetry.ts +0 -234
- package/src/types/hugeicons-direct.d.ts +0 -4
- package/src/types/react-native-safe-area-context.d.ts +0 -8
- package/src/ui/appearance.ts +0 -808
- package/src/ui/native-appearance-context.tsx +0 -74
- package/src/ui/native-theme.tsx +0 -54
- package/src/ui/native-types.ts +0 -40
- package/src/ui/participant-avatar.ts +0 -47
- package/src/ui/theme-tokens.ts +0 -41
- package/src/ui/theme.ts +0 -214
- package/src/utils/native-space-layout.ts +0 -135
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import AVFoundation
|
|
2
|
+
import Foundation
|
|
3
|
+
import React
|
|
4
|
+
import UIKit
|
|
5
|
+
|
|
6
|
+
/// Lists the call's audio outputs (earpiece, speaker, wired and Bluetooth headsets) and switches
|
|
7
|
+
/// between them on the shared play-and-record session that WebRTC owns.
|
|
8
|
+
@objc(ChalkAudioRouteModule)
|
|
9
|
+
final class ChalkAudioRouteModule: RCTEventEmitter {
|
|
10
|
+
private let eventName = "ChalkAudioRouteChanged"
|
|
11
|
+
private var observer: NSObjectProtocol?
|
|
12
|
+
|
|
13
|
+
override class func requiresMainQueueSetup() -> Bool {
|
|
14
|
+
false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override func constantsToExport() -> [AnyHashable: Any]! {
|
|
18
|
+
["eventName": eventName]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override func supportedEvents() -> [String]! {
|
|
22
|
+
[eventName]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override func startObserving() {
|
|
26
|
+
observer = NotificationCenter.default.addObserver(forName: AVAudioSession.routeChangeNotification, object: nil, queue: .main) { [weak self] _ in
|
|
27
|
+
guard let self else { return }
|
|
28
|
+
self.sendEvent(withName: self.eventName, body: self.snapshot())
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override func stopObserving() {
|
|
33
|
+
if let observer { NotificationCenter.default.removeObserver(observer) }
|
|
34
|
+
observer = nil
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@objc(getRoutes:rejecter:)
|
|
38
|
+
func getRoutes(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
39
|
+
resolve(snapshot())
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc(selectRoute:resolver:rejecter:)
|
|
43
|
+
func selectRoute(_ id: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
44
|
+
let session = AVAudioSession.sharedInstance()
|
|
45
|
+
do {
|
|
46
|
+
if id == "speaker" {
|
|
47
|
+
try session.overrideOutputAudioPort(.speaker)
|
|
48
|
+
} else {
|
|
49
|
+
try session.overrideOutputAudioPort(.none)
|
|
50
|
+
let port = session.availableInputs?.first { input in
|
|
51
|
+
id == "earpiece" ? input.portType == .builtInMic : input.uid == id
|
|
52
|
+
}
|
|
53
|
+
if let port { try session.setPreferredInput(port) }
|
|
54
|
+
}
|
|
55
|
+
resolve(snapshot())
|
|
56
|
+
} catch {
|
|
57
|
+
reject("audio_route_failed", "Couldn't switch the audio output to \(id).", error)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private func snapshot() -> [String: Any] {
|
|
62
|
+
let session = AVAudioSession.sharedInstance()
|
|
63
|
+
let isPhone = UIDevice.current.userInterfaceIdiom == .phone
|
|
64
|
+
var routes: [[String: String]] = []
|
|
65
|
+
if isPhone { routes.append(["id": "earpiece", "kind": "earpiece", "name": ""]) }
|
|
66
|
+
routes.append(["id": "speaker", "kind": "speaker", "name": ""])
|
|
67
|
+
for input in session.availableInputs ?? [] {
|
|
68
|
+
guard let kind = Self.headsetKind(input.portType) else { continue }
|
|
69
|
+
routes.append(["id": input.uid, "kind": kind, "name": input.portName])
|
|
70
|
+
}
|
|
71
|
+
return ["routes": routes, "selected": selectedId(session, routes: routes)]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private func selectedId(_ session: AVAudioSession, routes: [[String: String]]) -> String {
|
|
75
|
+
guard let output = session.currentRoute.outputs.first else { return "speaker" }
|
|
76
|
+
switch output.portType {
|
|
77
|
+
case .builtInSpeaker: return "speaker"
|
|
78
|
+
case .builtInReceiver: return "earpiece"
|
|
79
|
+
default:
|
|
80
|
+
// Headsets report the same port as input and output, so the input's id names the route.
|
|
81
|
+
let input = session.currentRoute.inputs.first { Self.headsetKind($0.portType) != nil }
|
|
82
|
+
return input?.uid ?? routes.first { $0["name"] == output.portName }?["id"] ?? "speaker"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private static func headsetKind(_ port: AVAudioSession.Port) -> String? {
|
|
87
|
+
switch port {
|
|
88
|
+
case .bluetoothHFP, .bluetoothLE, .bluetoothA2DP: return "bluetooth"
|
|
89
|
+
case .headsetMic, .usbAudio: return "wired"
|
|
90
|
+
default: return nil
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(ChalkAudioRouteModule, RCTEventEmitter)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(getRoutes:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
7
|
+
RCT_EXTERN_METHOD(selectRoute:(NSString *)id resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
8
|
+
|
|
9
|
+
@end
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@q9labsai/chalk-react-native",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,21 +22,6 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"typesVersions": {
|
|
24
24
|
"*": {
|
|
25
|
-
"android": [
|
|
26
|
-
"./dist/android.d.ts"
|
|
27
|
-
],
|
|
28
|
-
"ios": [
|
|
29
|
-
"./dist/ios.d.ts"
|
|
30
|
-
],
|
|
31
|
-
"ios-phone": [
|
|
32
|
-
"./dist/ios-phone.d.ts"
|
|
33
|
-
],
|
|
34
|
-
"ios-pad": [
|
|
35
|
-
"./dist/ios-pad.d.ts"
|
|
36
|
-
],
|
|
37
|
-
"macos": [
|
|
38
|
-
"./dist/macos.d.ts"
|
|
39
|
-
],
|
|
40
25
|
"runtime": [
|
|
41
26
|
"./dist/runtime.d.ts"
|
|
42
27
|
],
|
|
@@ -49,11 +34,8 @@
|
|
|
49
34
|
"invites": [
|
|
50
35
|
"./dist/invites.d.ts"
|
|
51
36
|
],
|
|
52
|
-
"
|
|
53
|
-
"./dist/ui
|
|
54
|
-
],
|
|
55
|
-
"appearance": [
|
|
56
|
-
"./dist/ui/appearance.d.ts"
|
|
37
|
+
"ui": [
|
|
38
|
+
"./dist/ui.d.ts"
|
|
57
39
|
],
|
|
58
40
|
"client": [
|
|
59
41
|
"./dist/client.d.ts"
|
|
@@ -72,36 +54,6 @@
|
|
|
72
54
|
"require": "./dist/index.js",
|
|
73
55
|
"default": "./dist/index.js"
|
|
74
56
|
},
|
|
75
|
-
"./android": {
|
|
76
|
-
"types": "./dist/android.d.ts",
|
|
77
|
-
"react-native": "./dist/android.js",
|
|
78
|
-
"import": "./dist/android.js",
|
|
79
|
-
"default": "./dist/android.js"
|
|
80
|
-
},
|
|
81
|
-
"./ios": {
|
|
82
|
-
"types": "./dist/ios.d.ts",
|
|
83
|
-
"react-native": "./dist/ios.js",
|
|
84
|
-
"import": "./dist/ios.js",
|
|
85
|
-
"default": "./dist/ios.js"
|
|
86
|
-
},
|
|
87
|
-
"./ios-phone": {
|
|
88
|
-
"types": "./dist/ios-phone.d.ts",
|
|
89
|
-
"react-native": "./dist/ios-phone.js",
|
|
90
|
-
"import": "./dist/ios-phone.js",
|
|
91
|
-
"default": "./dist/ios-phone.js"
|
|
92
|
-
},
|
|
93
|
-
"./ios-pad": {
|
|
94
|
-
"types": "./dist/ios-pad.d.ts",
|
|
95
|
-
"react-native": "./dist/ios-pad.js",
|
|
96
|
-
"import": "./dist/ios-pad.js",
|
|
97
|
-
"default": "./dist/ios-pad.js"
|
|
98
|
-
},
|
|
99
|
-
"./macos": {
|
|
100
|
-
"types": "./dist/macos.d.ts",
|
|
101
|
-
"react-native": "./dist/macos.js",
|
|
102
|
-
"import": "./dist/macos.js",
|
|
103
|
-
"default": "./dist/macos.js"
|
|
104
|
-
},
|
|
105
57
|
"./runtime": {
|
|
106
58
|
"types": "./dist/runtime.d.ts",
|
|
107
59
|
"react-native": "./dist/runtime.js",
|
|
@@ -120,24 +72,24 @@
|
|
|
120
72
|
"import": "./dist/diagnostics.js",
|
|
121
73
|
"default": "./dist/diagnostics.js"
|
|
122
74
|
},
|
|
75
|
+
"./dev": {
|
|
76
|
+
"types": "./dist/dev.d.ts",
|
|
77
|
+
"react-native": "./dist/dev.js",
|
|
78
|
+
"import": "./dist/dev.js",
|
|
79
|
+
"default": "./dist/dev.js"
|
|
80
|
+
},
|
|
81
|
+
"./ui": {
|
|
82
|
+
"types": "./dist/ui.d.ts",
|
|
83
|
+
"react-native": "./dist/ui.js",
|
|
84
|
+
"import": "./dist/ui.js",
|
|
85
|
+
"default": "./dist/ui.js"
|
|
86
|
+
},
|
|
123
87
|
"./invites": {
|
|
124
88
|
"types": "./dist/invites.d.ts",
|
|
125
89
|
"react-native": "./dist/invites.js",
|
|
126
90
|
"import": "./dist/invites.js",
|
|
127
91
|
"default": "./dist/invites.js"
|
|
128
92
|
},
|
|
129
|
-
"./theme": {
|
|
130
|
-
"types": "./dist/ui/theme.d.ts",
|
|
131
|
-
"react-native": "./dist/ui/theme.js",
|
|
132
|
-
"import": "./dist/ui/theme.js",
|
|
133
|
-
"default": "./dist/ui/theme.js"
|
|
134
|
-
},
|
|
135
|
-
"./appearance": {
|
|
136
|
-
"types": "./dist/ui/appearance.d.ts",
|
|
137
|
-
"react-native": "./dist/ui/appearance.js",
|
|
138
|
-
"import": "./dist/ui/appearance.js",
|
|
139
|
-
"default": "./dist/ui/appearance.js"
|
|
140
|
-
},
|
|
141
93
|
"./client": {
|
|
142
94
|
"types": "./dist/client.d.ts",
|
|
143
95
|
"react-native": "./dist/client.js",
|
|
@@ -150,38 +102,56 @@
|
|
|
150
102
|
"registry": "https://registry.npmjs.org/"
|
|
151
103
|
},
|
|
152
104
|
"dependencies": {
|
|
153
|
-
"@q9labsai/chalk-client": "^
|
|
154
|
-
"@q9labsai/chalk-whiteboard": "^
|
|
155
|
-
"@q9labsai/facehash": "^
|
|
105
|
+
"@q9labsai/chalk-client": "^5.0.1",
|
|
106
|
+
"@q9labsai/chalk-whiteboard": "^5.0.1",
|
|
107
|
+
"@q9labsai/facehash": "^5.0.1",
|
|
108
|
+
"uqr": "^0.1.3"
|
|
156
109
|
},
|
|
157
110
|
"devDependencies": {
|
|
158
111
|
"@types/node": "^26.2.0",
|
|
159
112
|
"@types/react": "^19.2.18",
|
|
160
|
-
"
|
|
113
|
+
"expo-audio": "~55.0.18",
|
|
114
|
+
"expo-clipboard": "~55.0.9",
|
|
115
|
+
"expo-crypto": "~55.0.19",
|
|
116
|
+
"expo-document-picker": "~55.0.15",
|
|
117
|
+
"expo-file-system": "~55.0.24",
|
|
118
|
+
"expo-haptics": "~55.0.18",
|
|
119
|
+
"react-native-gesture-handler": "~2.30.1",
|
|
120
|
+
"react-native-reanimated": "4.2.1",
|
|
121
|
+
"react-native-safe-area-context": "~5.6.2",
|
|
122
|
+
"react-native-svg": "^15.15.3",
|
|
161
123
|
"react-native-webview": "13.16.1",
|
|
124
|
+
"react-native-worklets": "0.7.2",
|
|
162
125
|
"typescript": "^6.0.3"
|
|
163
126
|
},
|
|
164
127
|
"peerDependencies": {
|
|
165
128
|
"@cloudflare/react-native-webrtc": "~125.0.1 || ~125.0.3",
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
"
|
|
129
|
+
"expo-audio": "~55.0.18",
|
|
130
|
+
"expo-clipboard": "~55.0.9",
|
|
131
|
+
"expo-crypto": "~55.0.19",
|
|
132
|
+
"expo-document-picker": "~55.0.15",
|
|
133
|
+
"expo-file-system": "~55.0.24",
|
|
134
|
+
"expo-haptics": "~55.0.18",
|
|
169
135
|
"react": "^18.0.0 || ^19.0.0",
|
|
170
136
|
"react-native": ">=0.77",
|
|
137
|
+
"react-native-gesture-handler": "~2.30.1",
|
|
138
|
+
"react-native-reanimated": "4.2.1",
|
|
139
|
+
"react-native-safe-area-context": "~5.6.2",
|
|
171
140
|
"react-native-svg": "^15.15.3",
|
|
172
|
-
"react-native-
|
|
173
|
-
"react-native-
|
|
141
|
+
"react-native-webview": "^13.16.1",
|
|
142
|
+
"react-native-worklets": "0.7.2"
|
|
174
143
|
},
|
|
175
144
|
"scripts": {
|
|
176
|
-
"build": "rm -rf ./dist && tsup ./src/index.ts ./src/client.ts ./src/
|
|
145
|
+
"build": "rm -rf ./dist && tsup ./src/index.ts ./src/client.ts ./src/runtime.ts ./src/clipboard.ts ./src/diagnostics.ts ./src/dev.ts ./src/invites.ts ./src/ui.ts --format esm --out-dir ./dist --platform browser --external react --external react-native --external react-native-webview --external @q9labsai/chalk-whiteboard --external @cloudflare/react-native-webrtc --external expo-audio --external expo-clipboard --external expo-crypto --external expo-document-picker --external expo-file-system --external expo-haptics --external react-native-gesture-handler --external react-native-reanimated --external react-native-safe-area-context --external react-native-svg --loader .wav=copy && pnpm run build:types && pnpm run sync:whiteboard-assets",
|
|
177
146
|
"build:types": "rm -f tsconfig.tsbuildinfo && tsc --build tsconfig.json",
|
|
178
|
-
"dev": "tsup ./src/index.ts ./src/client.ts ./src/
|
|
147
|
+
"dev": "tsup ./src/index.ts ./src/client.ts ./src/runtime.ts ./src/clipboard.ts ./src/diagnostics.ts ./src/dev.ts ./src/invites.ts ./src/ui.ts --format esm --out-dir ./dist --platform browser --external react --external react-native --external react-native-webview --external @q9labsai/chalk-whiteboard --external @cloudflare/react-native-webrtc --external expo-audio --external expo-clipboard --external expo-crypto --external expo-document-picker --external expo-file-system --external expo-haptics --external react-native-gesture-handler --external react-native-reanimated --external react-native-safe-area-context --external react-native-svg --loader .wav=copy --watch",
|
|
179
148
|
"sync:whiteboard-assets": "node ./scripts/sync-whiteboard-assets.mjs",
|
|
180
149
|
"test": "pnpm exec vitest run",
|
|
181
|
-
"check-types": "tsc --project tsconfig.check-types.json --noEmit",
|
|
150
|
+
"check-types": "tsc-rs --project tsconfig.check-types.json --noEmit",
|
|
182
151
|
"check:tokens": "node ./scripts/check-tokenized-styles.mjs",
|
|
152
|
+
"check:worklets": "node ./scripts/check-worklet-directives.mjs",
|
|
183
153
|
"check:client-package": "node ./scripts/check-client-package.mjs",
|
|
184
|
-
"lint": "pnpm run check:tokens && pnpm exec oxfmt --check . && tsc --project tsconfig.check-types.json --noEmit",
|
|
154
|
+
"lint": "pnpm run check:tokens && pnpm run check:worklets && pnpm exec oxfmt --check . && tsc --project tsconfig.check-types.json --noEmit",
|
|
185
155
|
"clean": "rm -rf dist"
|
|
186
156
|
}
|
|
187
157
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NativeModules, Platform } from "react-native";
|
|
2
|
+
|
|
3
|
+
type NativeCallServiceModule = {
|
|
4
|
+
readonly start: () => Promise<boolean>;
|
|
5
|
+
readonly stop: () => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const nativeModule: NativeCallServiceModule | undefined = NativeModules.ChalkCallService;
|
|
9
|
+
|
|
10
|
+
/** Starts the Android foreground service for the call. Resolves false when there's nothing to keep running (no microphone or camera permission) or Android refused the start. */
|
|
11
|
+
export async function startAndroidCallService(): Promise<boolean> {
|
|
12
|
+
if (Platform.OS !== "android" || !nativeModule) return false;
|
|
13
|
+
return nativeModule.start();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function stopAndroidCallService(): Promise<void> {
|
|
17
|
+
if (Platform.OS !== "android" || !nativeModule) return;
|
|
18
|
+
await nativeModule.stop();
|
|
19
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { createFacehashScene, getColor, getForegroundColor, type Intensity3D } from "@q9labsai/facehash";
|
|
2
|
+
import { memo, useCallback, useEffect, useMemo } from "react";
|
|
3
|
+
import { Platform, StyleSheet, View } from "react-native";
|
|
4
|
+
import Animated, { cancelAnimation, useAnimatedStyle, useReducedMotion, useSharedValue, withDelay, withRepeat, withSequence, withTiming, type SharedValue } from "react-native-reanimated";
|
|
5
|
+
import Svg, { G, Path, Text as SvgText } from "react-native-svg";
|
|
6
|
+
import { timings } from "../motion/motion";
|
|
7
|
+
import { easings, identityColors } from "../theme/tokens";
|
|
8
|
+
|
|
9
|
+
export type FaceAvatarProps = {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly size: number;
|
|
12
|
+
/** `bold` is the 3D style for tiles; `subtle` is for rows, pills, chat and toasts. */
|
|
13
|
+
readonly style?: "bold" | "subtle";
|
|
14
|
+
/** Live speaking level from 0 to 1. While it moves, the face bobs and the mouth opens. */
|
|
15
|
+
readonly level?: SharedValue<number>;
|
|
16
|
+
/** Eyes drift on their own every 1.8 s, as on the mockup's touch devices. Off for small avatars. */
|
|
17
|
+
readonly lookAround?: boolean;
|
|
18
|
+
readonly testID?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const INTENSITY: Readonly<Record<"bold" | "subtle", Intensity3D>> = { bold: "dramatic", subtle: "subtle" };
|
|
22
|
+
const MONO = Platform.select({ ios: "Menlo", default: "monospace" });
|
|
23
|
+
const FRONT_HOLD_MS = 1400;
|
|
24
|
+
const LOOK_INTERVAL_MS = 1800;
|
|
25
|
+
const LOOK_MS = 700;
|
|
26
|
+
const BOB = 5;
|
|
27
|
+
const MOUTH = 0.55;
|
|
28
|
+
const CLOSED = 0.05;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A Facehash avatar drawn natively. The face blinks on its own rhythm, reacts to the speaking
|
|
32
|
+
* level, and turns to the front for a moment when touched. All motion runs on the UI thread and
|
|
33
|
+
* stops with reduced motion. Decorative: the parent names the person.
|
|
34
|
+
*/
|
|
35
|
+
export const FaceAvatar = memo(function FaceAvatar({ name, size, style = "subtle", level, lookAround = false, testID }: FaceAvatarProps): React.JSX.Element {
|
|
36
|
+
const reduceMotion = useReducedMotion();
|
|
37
|
+
const scene = useMemo(() => createFacehashScene({ name, colorsLength: identityColors.length, intensity3d: INTENSITY[style] }), [name, style]);
|
|
38
|
+
const background = getColor(identityColors, scene.data.colorIndex);
|
|
39
|
+
const foreground = getForegroundColor(background);
|
|
40
|
+
const geometry = scene.faceGeometry;
|
|
41
|
+
const box = scene.faceBox;
|
|
42
|
+
const eyeCenter = box.y + geometry.leftEyeAnchor.y * (box.height / geometry.viewBox.height);
|
|
43
|
+
const unit = size / 100;
|
|
44
|
+
const projection = scene.projection;
|
|
45
|
+
|
|
46
|
+
const turned = useSharedValue(1);
|
|
47
|
+
const blink = useSharedValue(1);
|
|
48
|
+
const lookX = useSharedValue(0);
|
|
49
|
+
const lookY = useSharedValue(0);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (reduceMotion) {
|
|
53
|
+
blink.value = 1;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const { delay, duration } = scene.data.blinkTimings.left;
|
|
57
|
+
const total = duration * 1000;
|
|
58
|
+
const close = { duration: total * 0.04, easing: easings.standard };
|
|
59
|
+
blink.value = withDelay(delay * 1000, withRepeat(withSequence(withDelay(total * 0.92, withTiming(CLOSED, close)), withTiming(1, close)), -1));
|
|
60
|
+
return () => cancelAnimation(blink);
|
|
61
|
+
}, [blink, reduceMotion, scene]);
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!lookAround || reduceMotion) return;
|
|
65
|
+
const timer = setInterval(() => {
|
|
66
|
+
if (Math.random() < 0.5 || turned.value < 1) return;
|
|
67
|
+
lookX.value = withTiming((Math.random() * 2 - 1) * 6, { duration: LOOK_MS, easing: easings.standard });
|
|
68
|
+
lookY.value = withTiming((Math.random() * 2 - 1) * 4, { duration: LOOK_MS, easing: easings.standard });
|
|
69
|
+
}, LOOK_INTERVAL_MS);
|
|
70
|
+
return () => clearInterval(timer);
|
|
71
|
+
}, [lookAround, lookX, lookY, reduceMotion, turned]);
|
|
72
|
+
|
|
73
|
+
const turnToFront = useCallback(() => {
|
|
74
|
+
if (reduceMotion) return;
|
|
75
|
+
turned.value = withSequence(withTiming(0, timings.avatarTurn), withDelay(FRONT_HOLD_MS, withTiming(1, timings.avatarTurn)));
|
|
76
|
+
lookX.value = withTiming(0, { duration: 250, easing: easings.standard });
|
|
77
|
+
lookY.value = withTiming(0, { duration: 250, easing: easings.standard });
|
|
78
|
+
blink.value = withSequence(withTiming(CLOSED, { duration: 150, easing: easings.standard }), withTiming(1, { duration: 150, easing: easings.standard }));
|
|
79
|
+
}, [blink, lookX, lookY, reduceMotion, turned]);
|
|
80
|
+
|
|
81
|
+
const bobStyle = useAnimatedStyle(() => {
|
|
82
|
+
"worklet";
|
|
83
|
+
return { transform: [{ translateY: level ? -level.value * BOB * unit : 0 }] };
|
|
84
|
+
});
|
|
85
|
+
const poseStyle = useAnimatedStyle(() => {
|
|
86
|
+
"worklet";
|
|
87
|
+
const t = turned.value;
|
|
88
|
+
return {
|
|
89
|
+
transform: [{ translateX: projection.translateX * unit * t }, { translateY: projection.translateY * unit * t }, { skewX: `${projection.skewX * t}deg` }, { skewY: `${projection.skewY * t}deg` }, { scaleX: 1 + (projection.scaleX - 1) * t }, { scaleY: 1 + (projection.scaleY - 1) * t }],
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
const eyesLookStyle = useAnimatedStyle(() => {
|
|
93
|
+
"worklet";
|
|
94
|
+
return { transform: [{ translateX: lookX.value * unit }, { translateY: lookY.value * unit }] };
|
|
95
|
+
});
|
|
96
|
+
const mouthLookStyle = useAnimatedStyle(() => {
|
|
97
|
+
"worklet";
|
|
98
|
+
return { transform: [{ translateX: (lookX.value / 2) * unit }, { translateY: (lookY.value / 2) * unit }] };
|
|
99
|
+
});
|
|
100
|
+
const blinkStyle = useAnimatedStyle(() => {
|
|
101
|
+
"worklet";
|
|
102
|
+
return { transform: [{ scaleY: blink.value }] };
|
|
103
|
+
});
|
|
104
|
+
const mouthStyle = useAnimatedStyle(() => {
|
|
105
|
+
"worklet";
|
|
106
|
+
return { transform: [{ scaleY: 1 + (level ? level.value : 0) * MOUTH }] };
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const faceTransform = `translate(${box.x} ${box.y}) scale(${box.width / geometry.viewBox.width} ${box.height / geometry.viewBox.height})`;
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<View onTouchStart={turnToFront} style={[styles.circle, { width: size, height: size, borderRadius: size / 2, backgroundColor: background }]} testID={testID}>
|
|
113
|
+
<Animated.View style={[StyleSheet.absoluteFill, bobStyle]}>
|
|
114
|
+
<Animated.View style={[StyleSheet.absoluteFill, poseStyle]}>
|
|
115
|
+
<Animated.View style={[StyleSheet.absoluteFill, eyesLookStyle]}>
|
|
116
|
+
<Animated.View style={[StyleSheet.absoluteFill, { transformOrigin: `50% ${eyeCenter}%` }, blinkStyle]}>
|
|
117
|
+
<Svg height={size} viewBox="0 0 100 100" width={size}>
|
|
118
|
+
<G transform={faceTransform}>
|
|
119
|
+
{[...geometry.leftEyePaths, ...geometry.rightEyePaths].map((d) => (
|
|
120
|
+
<Path d={d} fill={foreground} key={d} />
|
|
121
|
+
))}
|
|
122
|
+
</G>
|
|
123
|
+
</Svg>
|
|
124
|
+
</Animated.View>
|
|
125
|
+
</Animated.View>
|
|
126
|
+
<Animated.View style={[StyleSheet.absoluteFill, mouthLookStyle]}>
|
|
127
|
+
<Animated.View style={[StyleSheet.absoluteFill, styles.mouthOrigin, mouthStyle]}>
|
|
128
|
+
<Svg height={size} viewBox="0 0 100 100" width={size}>
|
|
129
|
+
<SvgText alignmentBaseline="middle" fill={foreground} fontFamily={MONO} fontSize={scene.initialLayout.fontSize} fontWeight="700" textAnchor="middle" x={scene.initialLayout.x} y={scene.initialLayout.y}>
|
|
130
|
+
{scene.data.initial}
|
|
131
|
+
</SvgText>
|
|
132
|
+
</Svg>
|
|
133
|
+
</Animated.View>
|
|
134
|
+
</Animated.View>
|
|
135
|
+
</Animated.View>
|
|
136
|
+
</Animated.View>
|
|
137
|
+
</View>
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const styles = StyleSheet.create({
|
|
142
|
+
circle: { overflow: "hidden" },
|
|
143
|
+
// The initial sits on y = 70 with a 26-unit font, so its baseline is near y = 79.
|
|
144
|
+
mouthOrigin: { transformOrigin: "50% 79%" },
|
|
145
|
+
});
|
package/src/client.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Native implementation seam for advanced construction. The turnkey root
|
|
3
|
-
* remains `Chalk`; applications that need direct lifecycle ownership can
|
|
4
|
-
* create the React Native SpaceClient through this explicit subpath.
|
|
5
|
-
*/
|
|
1
|
+
/** Native client construction for applications that own the call lifecycle. */
|
|
6
2
|
export { createNativeSpaceClient } from "./space-client/create-native-space-client";
|
|
7
3
|
export type { NativeSpaceClientOptions } from "./space-client/create-native-space-client";
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ChalkWhiteboardController, type ChalkEmbeddedWhiteboardTransport, type ChalkEmbeddedWhiteboardViewport } from "@q9labsai/chalk-whiteboard/embedded";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { ActivityIndicator, Pressable,
|
|
3
|
+
import { ActivityIndicator, Pressable, Text, useWindowDimensions, View, type LayoutChangeEvent, type StyleProp, type ViewStyle } from "react-native";
|
|
4
4
|
import WebView, { type WebViewMessageEvent, type WebViewNavigation } from "react-native-webview";
|
|
5
5
|
|
|
6
|
-
import { useNativeTheme } from "../ui/native-theme";
|
|
7
6
|
import { isEmbeddedWhiteboardNavigationAllowed, rendererURLWithContext, resolveEmbeddedWhiteboardRendererURL } from "../whiteboard/embedded-whiteboard-assets";
|
|
8
7
|
import { createEmbeddedWhiteboardViewport } from "../whiteboard/embedded-whiteboard-viewport";
|
|
9
8
|
|
|
@@ -39,8 +38,7 @@ export const embeddedWhiteboardWebViewSecurityPolicy = Object.freeze({
|
|
|
39
38
|
});
|
|
40
39
|
|
|
41
40
|
export function EmbeddedWhiteboard({ transport, journeyId, traceparent, tracestate, canDraw, canClear, theme: themeOverride, localParticipantColor, rendererURL: rendererURLOverride, style, testID, onMetric, onError, onUserExport }: EmbeddedWhiteboardProps): React.JSX.Element {
|
|
42
|
-
const
|
|
43
|
-
const theme = themeOverride ?? nativeTheme.colorScheme;
|
|
41
|
+
const theme = themeOverride ?? "light";
|
|
44
42
|
const webViewRef = useRef<WebView>(null);
|
|
45
43
|
const controllerRef = useRef<ChalkWhiteboardController | null>(null);
|
|
46
44
|
const listenersRef = useRef(new Set<(message: string) => void>());
|
|
@@ -158,26 +156,26 @@ export function EmbeddedWhiteboard({ transport, journeyId, traceparent, tracesta
|
|
|
158
156
|
|
|
159
157
|
if (loadError) {
|
|
160
158
|
return (
|
|
161
|
-
<View style={[
|
|
162
|
-
<Text
|
|
163
|
-
<Text
|
|
164
|
-
<Pressable accessibilityRole="button" onPress={retryRenderer}
|
|
165
|
-
<Text
|
|
159
|
+
<View style={[{ flex: 1 }, style]} testID={testID}>
|
|
160
|
+
<Text>Whiteboard unavailable</Text>
|
|
161
|
+
<Text>{loadError}</Text>
|
|
162
|
+
<Pressable accessibilityRole="button" onPress={retryRenderer}>
|
|
163
|
+
<Text>Retry</Text>
|
|
166
164
|
</Pressable>
|
|
167
165
|
</View>
|
|
168
166
|
);
|
|
169
167
|
}
|
|
170
168
|
if (!sourceURL || !rendererURL) {
|
|
171
169
|
return (
|
|
172
|
-
<View style={[
|
|
173
|
-
<ActivityIndicator
|
|
174
|
-
<Text
|
|
170
|
+
<View style={[{ flex: 1 }, style]} testID={testID}>
|
|
171
|
+
<ActivityIndicator />
|
|
172
|
+
<Text>Loading whiteboard…</Text>
|
|
175
173
|
</View>
|
|
176
174
|
);
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
return (
|
|
180
|
-
<View onLayout={handleLayout} style={[
|
|
178
|
+
<View onLayout={handleLayout} style={[{ flex: 1 }, style]} testID={testID}>
|
|
181
179
|
<WebView
|
|
182
180
|
key={rendererGeneration}
|
|
183
181
|
ref={webViewRef}
|
|
@@ -197,12 +195,12 @@ export function EmbeddedWhiteboard({ transport, journeyId, traceparent, tracesta
|
|
|
197
195
|
pullToRefreshEnabled={false}
|
|
198
196
|
scrollEnabled={false}
|
|
199
197
|
source={{ uri: sourceURL }}
|
|
200
|
-
style={
|
|
198
|
+
style={{ flex: 1 }}
|
|
201
199
|
webviewDebuggingEnabled={typeof __DEV__ !== "undefined" && __DEV__}
|
|
202
200
|
/>
|
|
203
201
|
{compatibilityNotice ? (
|
|
204
|
-
<View pointerEvents="none"
|
|
205
|
-
<Text
|
|
202
|
+
<View pointerEvents="none">
|
|
203
|
+
<Text>{compatibilityNotice}</Text>
|
|
206
204
|
</View>
|
|
207
205
|
) : null}
|
|
208
206
|
</View>
|
|
@@ -212,58 +210,3 @@ export function EmbeddedWhiteboard({ transport, journeyId, traceparent, tracesta
|
|
|
212
210
|
function createRendererGeneration(): string {
|
|
213
211
|
return globalThis.crypto?.randomUUID?.() ?? `whiteboard-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
214
212
|
}
|
|
215
|
-
|
|
216
|
-
const styles = StyleSheet.create({
|
|
217
|
-
container: {
|
|
218
|
-
flex: 1,
|
|
219
|
-
overflow: "hidden",
|
|
220
|
-
},
|
|
221
|
-
webView: {
|
|
222
|
-
flex: 1,
|
|
223
|
-
},
|
|
224
|
-
compatibilityNotice: {
|
|
225
|
-
position: "absolute",
|
|
226
|
-
top: 12,
|
|
227
|
-
left: 12,
|
|
228
|
-
right: 12,
|
|
229
|
-
borderRadius: 10,
|
|
230
|
-
paddingHorizontal: 12,
|
|
231
|
-
paddingVertical: 10,
|
|
232
|
-
},
|
|
233
|
-
compatibilityNoticeText: {
|
|
234
|
-
fontSize: 13,
|
|
235
|
-
fontWeight: "700",
|
|
236
|
-
textAlign: "center",
|
|
237
|
-
},
|
|
238
|
-
status: {
|
|
239
|
-
flex: 1,
|
|
240
|
-
alignItems: "center",
|
|
241
|
-
justifyContent: "center",
|
|
242
|
-
gap: 10,
|
|
243
|
-
padding: 24,
|
|
244
|
-
},
|
|
245
|
-
loadingMessage: {
|
|
246
|
-
fontSize: 14,
|
|
247
|
-
fontWeight: "600",
|
|
248
|
-
},
|
|
249
|
-
errorTitle: {
|
|
250
|
-
fontSize: 17,
|
|
251
|
-
fontWeight: "700",
|
|
252
|
-
},
|
|
253
|
-
errorMessage: {
|
|
254
|
-
fontSize: 13,
|
|
255
|
-
textAlign: "center",
|
|
256
|
-
},
|
|
257
|
-
retryButton: {
|
|
258
|
-
borderRadius: 8,
|
|
259
|
-
paddingHorizontal: 16,
|
|
260
|
-
paddingVertical: 10,
|
|
261
|
-
},
|
|
262
|
-
retryButtonPressed: {
|
|
263
|
-
opacity: 0.75,
|
|
264
|
-
},
|
|
265
|
-
retryButtonText: {
|
|
266
|
-
fontSize: 14,
|
|
267
|
-
fontWeight: "700",
|
|
268
|
-
},
|
|
269
|
-
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { NativeParticipant as Participant } from "../ui/native-types";
|
|
2
1
|
import type { NativeMediaStreamTrack } from "../media/native-webrtc";
|
|
3
2
|
|
|
4
|
-
export function shouldRenderNativeMediaTrack({ participant, track, mediaKind = "camera" }: { participant:
|
|
3
|
+
export function shouldRenderNativeMediaTrack({ participant, track, mediaKind = "camera" }: { participant: { readonly videoEnabled: boolean } | null; track: MediaStreamTrack | NativeMediaStreamTrack | null | undefined; mediaKind?: "camera" | "screen-share" }): boolean {
|
|
5
4
|
if (!track) {
|
|
6
5
|
return false;
|
|
7
6
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { AppState } from "react-native";
|
|
3
|
+
import { startAndroidCallService, stopAndroidCallService } from "../android/call-service";
|
|
4
|
+
import { useConnection, useMedia } from "../hooks/space-hooks";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Runs the Android foreground service for as long as the person is in the call, so the microphone
|
|
8
|
+
* and camera keep working in the background. It starts again when the microphone or camera turns on,
|
|
9
|
+
* because that's when the person has granted the permission the service declares, and on every return
|
|
10
|
+
* to the foreground, because Android can refuse a start made while the app is in the background.
|
|
11
|
+
*/
|
|
12
|
+
export function useAndroidCallService(): void {
|
|
13
|
+
const connection = useConnection();
|
|
14
|
+
const media = useMedia();
|
|
15
|
+
const inCall = connection.status === "live" || connection.status === "reconnecting";
|
|
16
|
+
const microphoneOn = media.local.microphone.state === "enabled";
|
|
17
|
+
const cameraOn = media.local.camera.state === "enabled";
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!inCall) return;
|
|
21
|
+
const start = () => {
|
|
22
|
+
startAndroidCallService().catch((error: unknown) => {
|
|
23
|
+
console.warn("Failed to start the Android call service", error);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
start();
|
|
27
|
+
const subscription = AppState.addEventListener("change", (state) => {
|
|
28
|
+
if (state === "active") start();
|
|
29
|
+
});
|
|
30
|
+
return () => subscription.remove();
|
|
31
|
+
}, [inCall, microphoneOn, cameraOn]);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!inCall) return;
|
|
35
|
+
return () => {
|
|
36
|
+
stopAndroidCallService().catch((error: unknown) => {
|
|
37
|
+
console.warn("Failed to stop the Android call service", error);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
}, [inCall]);
|
|
41
|
+
}
|