@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,247 @@
|
|
|
1
|
+
import { Easing } from "react-native-reanimated";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Design tokens for the call, copied from the approved mobile mockup
|
|
5
|
+
* (`.dev` and `.dev.light` in mobile-mockup.html) and named by role as in design.md.
|
|
6
|
+
* This file and `fixed` below are the only places a colour literal may appear.
|
|
7
|
+
*/
|
|
8
|
+
export type ColorScheme = "dark" | "light";
|
|
9
|
+
|
|
10
|
+
export type Palette = {
|
|
11
|
+
/** Call background and status pages. */
|
|
12
|
+
readonly canvas: string;
|
|
13
|
+
/** Sheets, cards, the people pill and header buttons. */
|
|
14
|
+
readonly surface: string;
|
|
15
|
+
/** Tile background and the letterbox colour of shared content. */
|
|
16
|
+
readonly tile: string;
|
|
17
|
+
/** Round dock buttons, fields, chat bubbles, selected rows. */
|
|
18
|
+
readonly raised: string;
|
|
19
|
+
/** Menus, popovers and toasts. */
|
|
20
|
+
readonly popover: string;
|
|
21
|
+
/** Pressed row, expanded control, the default pill button. */
|
|
22
|
+
readonly hover: string;
|
|
23
|
+
/** Pressed surface of a raised control, switch track when off. */
|
|
24
|
+
readonly pressed: string;
|
|
25
|
+
readonly line: string;
|
|
26
|
+
readonly lineStrong: string;
|
|
27
|
+
readonly text: string;
|
|
28
|
+
readonly textStrong: string;
|
|
29
|
+
readonly textSoft: string;
|
|
30
|
+
readonly textMuted: string;
|
|
31
|
+
/** Focus ring: the mockup draws `outline: 2px solid var(--tx)`. */
|
|
32
|
+
readonly focus: string;
|
|
33
|
+
readonly danger: string;
|
|
34
|
+
readonly dangerPressed: string;
|
|
35
|
+
readonly dangerText: string;
|
|
36
|
+
readonly success: string;
|
|
37
|
+
readonly warning: string;
|
|
38
|
+
/** The call's accent: unread dots and your own reactions. */
|
|
39
|
+
readonly info: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const dark: Palette = {
|
|
43
|
+
canvas: "#0B0C0E",
|
|
44
|
+
surface: "#151619",
|
|
45
|
+
tile: "#151619",
|
|
46
|
+
raised: "#1D1F23",
|
|
47
|
+
popover: "#1D1F23",
|
|
48
|
+
hover: "#272A2F",
|
|
49
|
+
pressed: "#30333A",
|
|
50
|
+
line: "rgba(255,255,255,0.08)",
|
|
51
|
+
lineStrong: "rgba(255,255,255,0.14)",
|
|
52
|
+
text: "#ECECEE",
|
|
53
|
+
textStrong: "#FFFFFF",
|
|
54
|
+
textSoft: "#C4C6CC",
|
|
55
|
+
textMuted: "#9A9CA3",
|
|
56
|
+
focus: "#ECECEE",
|
|
57
|
+
danger: "#E5484D",
|
|
58
|
+
dangerPressed: "#C93D42",
|
|
59
|
+
dangerText: "#FF6B6B",
|
|
60
|
+
success: "#80B879",
|
|
61
|
+
warning: "#D9B641",
|
|
62
|
+
info: "#55AAC9",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const light: Palette = {
|
|
66
|
+
canvas: "#F3F3F5",
|
|
67
|
+
surface: "#FFFFFF",
|
|
68
|
+
tile: "#E2E2E7",
|
|
69
|
+
raised: "#ECECF0",
|
|
70
|
+
popover: "#FFFFFF",
|
|
71
|
+
hover: "#E1E1E6",
|
|
72
|
+
pressed: "#D3D3D9",
|
|
73
|
+
line: "rgba(0,0,0,0.09)",
|
|
74
|
+
lineStrong: "rgba(0,0,0,0.15)",
|
|
75
|
+
text: "#18181B",
|
|
76
|
+
textStrong: "#000000",
|
|
77
|
+
textSoft: "#3D3E45",
|
|
78
|
+
textMuted: "#5C5D65",
|
|
79
|
+
focus: "#18181B",
|
|
80
|
+
danger: "#D93A3F",
|
|
81
|
+
dangerPressed: "#C93D42",
|
|
82
|
+
dangerText: "#BF272C",
|
|
83
|
+
success: "#2B8A3E",
|
|
84
|
+
warning: "#8A6400",
|
|
85
|
+
info: "#1B70A0",
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const palettes: Readonly<Record<ColorScheme, Palette>> = { dark, light };
|
|
89
|
+
|
|
90
|
+
/** Colours that stay the same in both themes, because they sit on video or carry a fixed meaning. */
|
|
91
|
+
export const fixed = {
|
|
92
|
+
overlay: "rgba(12,14,18,0.75)",
|
|
93
|
+
overlayStrong: "rgba(12,14,18,0.82)",
|
|
94
|
+
overlayPressed: "rgba(40,42,48,0.95)",
|
|
95
|
+
overlayText: "#FFFFFF",
|
|
96
|
+
overlayDanger: "#FF6B6B",
|
|
97
|
+
overlayWarning: "#E2BD3A",
|
|
98
|
+
onDanger: "#FFFFFF",
|
|
99
|
+
hand: "#DCB740",
|
|
100
|
+
handText: "#16140C",
|
|
101
|
+
scrim: "rgba(0,0,0,0.55)",
|
|
102
|
+
liveRing: "rgba(255,255,255,0.9)",
|
|
103
|
+
liveRingShade: "rgba(0,0,0,0.35)",
|
|
104
|
+
switchKnob: "#FFFFFF",
|
|
105
|
+
/** QR codes stay black on white in both themes so every camera reads them. */
|
|
106
|
+
qrLight: "#FFFFFF",
|
|
107
|
+
qrDark: "#000000",
|
|
108
|
+
shadow: "#000000",
|
|
109
|
+
transparent: "transparent",
|
|
110
|
+
/** The selected segment of a compact segmented control. */
|
|
111
|
+
segmentShadow: "0px 1px 2px rgba(0,0,0,0.2)",
|
|
112
|
+
} as const;
|
|
113
|
+
|
|
114
|
+
/** File badges in chat (`.t-pdf` and friends); the same in both themes because the badge carries its own colour. */
|
|
115
|
+
export const fileKindColors = { pdf: "#C42B2B", doc: "#2F5FB3", xls: "#1E7A46", ppt: "#B8481E", other: "#5C5D65" } as const;
|
|
116
|
+
|
|
117
|
+
/** Shades over chat photos: "+N" on the last thumbnail (`.thm`) and a file still uploading (`.chip.up`). */
|
|
118
|
+
export const chatOverlays = { photoMore: "rgba(0,0,0,0.5)", uploading: "rgba(0,0,0,0.45)", ring: "#FFFFFF" } as const;
|
|
119
|
+
|
|
120
|
+
/** The photo viewer is dark in both themes (`.lbw`). */
|
|
121
|
+
export const viewer = {
|
|
122
|
+
backdrop: "rgba(8,8,10,0.94)",
|
|
123
|
+
text: "#ECECEE",
|
|
124
|
+
textMuted: "#A1A2A9",
|
|
125
|
+
button: "rgba(255,255,255,0.08)",
|
|
126
|
+
buttonPressed: "rgba(255,255,255,0.16)",
|
|
127
|
+
} as const;
|
|
128
|
+
|
|
129
|
+
/** Avatar backgrounds, chosen by a hash of the person's name. */
|
|
130
|
+
export const identityColors = ["#315F72", "#5C6650", "#6B5B4F", "#64576B", "#49645D", "#665D42", "#4D5D73", "#6D5158"] as const;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Shadows. In the light theme, controls that sit on the canvas carry a one-pixel `line` ring
|
|
134
|
+
* and floating surfaces add a soft shadow; the dark theme uses the heavier mockup shadows.
|
|
135
|
+
*/
|
|
136
|
+
export type Elevation = {
|
|
137
|
+
readonly popover: string;
|
|
138
|
+
readonly toast: string;
|
|
139
|
+
/** The small tile floating over the other person when two are in the call (`.tile.float`). */
|
|
140
|
+
readonly floatTile: string;
|
|
141
|
+
/** Controls on the canvas (dock buttons, people pill) get a one-pixel ring in light. */
|
|
142
|
+
readonly ringOnCanvas: boolean;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export const elevations: Readonly<Record<ColorScheme, Elevation>> = {
|
|
146
|
+
dark: { popover: "0px 12px 32px rgba(0,0,0,0.5)", toast: "0px 8px 24px rgba(0,0,0,0.4)", floatTile: "0px 0px 0px 1px rgba(255,255,255,0.14), 0px 6px 18px rgba(0,0,0,0.5)", ringOnCanvas: false },
|
|
147
|
+
light: { popover: "0px 0px 0px 1px rgba(0,0,0,0.09), 0px 12px 32px rgba(0,0,0,0.12)", toast: "0px 0px 0px 1px rgba(0,0,0,0.09), 0px 12px 32px rgba(0,0,0,0.12)", floatTile: "0px 0px 0px 1px rgba(0,0,0,0.15), 0px 6px 18px rgba(0,0,0,0.5)", ringOnCanvas: true },
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export type FontWeight = 400 | 500 | 600 | 700;
|
|
151
|
+
|
|
152
|
+
/** Figtree is embedded by the app; these are its PostScript names, which iOS and Android both resolve. */
|
|
153
|
+
export const fontFamilies: Readonly<Record<FontWeight, string>> = {
|
|
154
|
+
400: "Figtree-Regular",
|
|
155
|
+
500: "Figtree-Medium",
|
|
156
|
+
600: "Figtree-SemiBold",
|
|
157
|
+
700: "Figtree-Bold",
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const LINE_HEIGHT = 1.4;
|
|
161
|
+
|
|
162
|
+
function textStyle(fontSize: number, weight: FontWeight) {
|
|
163
|
+
return { fontFamily: fontFamilies[weight], fontSize, lineHeight: fontSize * LINE_HEIGHT } as const;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The call type scale. Text is Figtree at a line height of 1.4, in sentence case. */
|
|
167
|
+
export const type = {
|
|
168
|
+
statusTitle: textStyle(22, 600),
|
|
169
|
+
limboTitle: textStyle(20, 600),
|
|
170
|
+
progress: textStyle(17, 600),
|
|
171
|
+
sheetTitle: textStyle(16, 600),
|
|
172
|
+
phoneRow: textStyle(16, 400),
|
|
173
|
+
cardTitle: textStyle(15, 600),
|
|
174
|
+
wideButton: textStyle(15, 600),
|
|
175
|
+
body: textStyle(14, 400),
|
|
176
|
+
bodyMedium: textStyle(14, 500),
|
|
177
|
+
bodyStrong: textStyle(14, 600),
|
|
178
|
+
button: textStyle(13, 600),
|
|
179
|
+
meta: textStyle(13, 400),
|
|
180
|
+
label: textStyle(12, 500),
|
|
181
|
+
section: textStyle(12, 600),
|
|
182
|
+
caption: textStyle(11, 600),
|
|
183
|
+
} as const;
|
|
184
|
+
|
|
185
|
+
export type TypeStyle = keyof typeof type;
|
|
186
|
+
|
|
187
|
+
export const radii = {
|
|
188
|
+
tag: 6,
|
|
189
|
+
field: 10,
|
|
190
|
+
menuRow: 9,
|
|
191
|
+
menu: 12,
|
|
192
|
+
tile: 12,
|
|
193
|
+
tilePhone: 14,
|
|
194
|
+
card: 16,
|
|
195
|
+
sheet: 24,
|
|
196
|
+
round: 999,
|
|
197
|
+
} as const;
|
|
198
|
+
|
|
199
|
+
/** Four-point grid. */
|
|
200
|
+
export const space = { 1: 4, 2: 8, 3: 12, 4: 16, 5: 20, 6: 24, 8: 32, 10: 40 } as const;
|
|
201
|
+
|
|
202
|
+
export const sizes = {
|
|
203
|
+
control: 44,
|
|
204
|
+
dockPhone: 52,
|
|
205
|
+
headerButton: 40,
|
|
206
|
+
menuRow: 40,
|
|
207
|
+
menuRowPhone: 48,
|
|
208
|
+
toastMinHeight: 48,
|
|
209
|
+
handleWidth: 36,
|
|
210
|
+
handleHeight: 5,
|
|
211
|
+
} as const;
|
|
212
|
+
|
|
213
|
+
/** Durations in milliseconds, from the mockup's CSS transitions. */
|
|
214
|
+
export const durations = {
|
|
215
|
+
press: 150,
|
|
216
|
+
chromeFade: 250,
|
|
217
|
+
menu: 180,
|
|
218
|
+
toastIn: 200,
|
|
219
|
+
toastOut: 160,
|
|
220
|
+
card: 200,
|
|
221
|
+
sheet: 240,
|
|
222
|
+
scrim: 200,
|
|
223
|
+
move: 220,
|
|
224
|
+
enter: 220,
|
|
225
|
+
leave: 160,
|
|
226
|
+
copyMorph: 200,
|
|
227
|
+
copyReset: 2000,
|
|
228
|
+
veil: 300,
|
|
229
|
+
avatarTurn: 300,
|
|
230
|
+
speakingLevel: 90,
|
|
231
|
+
landscapeHide: 4000,
|
|
232
|
+
toastInfo: 5000,
|
|
233
|
+
} as const;
|
|
234
|
+
|
|
235
|
+
/** `--ease` in the mockup: menus, toasts, cards, sheets, the copy morph. */
|
|
236
|
+
const emphasized = Easing.bezier(0.16, 1, 0.3, 1);
|
|
237
|
+
/** `EASE` in the mockup: tiles moving between frames. */
|
|
238
|
+
const move = Easing.bezier(0.2, 0.8, 0.2, 1);
|
|
239
|
+
/** CSS `ease-out`: presses, fades, the scrim. */
|
|
240
|
+
const easeOut = Easing.bezier(0, 0, 0.58, 1);
|
|
241
|
+
/** The avatar's turn to the front. */
|
|
242
|
+
const standard = Easing.bezier(0.4, 0, 0.2, 1);
|
|
243
|
+
|
|
244
|
+
export const easings = { emphasized, move, easeOut, standard, linear: Easing.linear } as const;
|
|
245
|
+
|
|
246
|
+
/** Scale of a pressed control, per control family. */
|
|
247
|
+
export const pressScale = { round: 0.94, pill: 0.97, small: 0.92, big: 0.98 } as const;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { SpaceClientError, type SpaceClient } from "@q9labsai/chalk-client";
|
|
2
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
3
|
+
import { Linking, Platform } from "react-native";
|
|
4
|
+
import { FaceAvatar } from "../avatar/FaceAvatar";
|
|
5
|
+
import { useSpaceClient } from "../context/space-client-context";
|
|
6
|
+
import { usePreferences } from "../frame/preferences";
|
|
7
|
+
import { Icon, type IconName } from "../icons/Icon";
|
|
8
|
+
import type { ToastInput } from "../primitives/toast/toast-store";
|
|
9
|
+
import { useToasts } from "../primitives/toast/ToastStack";
|
|
10
|
+
import { playSound, type SoundName } from "../sounds/sounds";
|
|
11
|
+
import { useTheme } from "../theme/theme";
|
|
12
|
+
import type { Palette } from "../theme/tokens";
|
|
13
|
+
import { callNotices, firstName, type Notice } from "./notices";
|
|
14
|
+
|
|
15
|
+
/** A device the call asks the OS for. */
|
|
16
|
+
export type Permission = "microphone" | "camera";
|
|
17
|
+
|
|
18
|
+
type Toasts = ReturnType<typeof useToasts>;
|
|
19
|
+
|
|
20
|
+
export type CallEventToasts = {
|
|
21
|
+
/** Call before the person turns their own microphone off, so it isn't reported as a host mute. */
|
|
22
|
+
readonly noteOwnMicrophoneChange: () => void;
|
|
23
|
+
/** Says why turning on the microphone or camera failed, with the way forward (F1, K1, K2). */
|
|
24
|
+
readonly reportMediaFailure: (permission: Permission, cause: unknown, retry: () => void) => void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type CallEventToastsOptions = {
|
|
28
|
+
/** Called just before Open Settings leaves the app, so the app can rejoin after iOS restarts it. */
|
|
29
|
+
readonly onOpenSettings?: (permission: Permission) => void;
|
|
30
|
+
/** The app restarted after the person allowed this in Settings; says so once the call is live. */
|
|
31
|
+
readonly resumedAfterSettings?: Permission;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Turns call events into notices and sounds through the one toast stack: people joining and
|
|
36
|
+
* leaving (F5, F6), a host muting you (F8), requests to unmute (F3), a new host (F10), a share
|
|
37
|
+
* ending (F11), recording starting and stopping, and failed microphone or camera changes.
|
|
38
|
+
*/
|
|
39
|
+
export function useCallEventToasts({ onOpenSettings, resumedAfterSettings }: CallEventToastsOptions): CallEventToasts {
|
|
40
|
+
const client = useSpaceClient();
|
|
41
|
+
const toasts = useToasts();
|
|
42
|
+
const { colors } = useTheme();
|
|
43
|
+
const { soundsEnabled } = usePreferences();
|
|
44
|
+
const ownMicrophoneChange = useRef(false);
|
|
45
|
+
const latest = useRef({ colors, soundsEnabled });
|
|
46
|
+
latest.current = { colors, soundsEnabled };
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
let previous = client.getSnapshot();
|
|
50
|
+
return client.subscribe(() => {
|
|
51
|
+
const next = client.getSnapshot();
|
|
52
|
+
if (next === previous) return;
|
|
53
|
+
const notices = callNotices(previous, next, ownMicrophoneChange.current);
|
|
54
|
+
if (previous.media.local.microphone.state !== next.media.local.microphone.state) ownMicrophoneChange.current = false;
|
|
55
|
+
previous = next;
|
|
56
|
+
for (const notice of notices) {
|
|
57
|
+
let id = 0;
|
|
58
|
+
const { input, sound } = noticeToast(notice, { client, toasts, colors: latest.current.colors, dismiss: () => toasts.dismiss(id) });
|
|
59
|
+
id = toasts.show(input);
|
|
60
|
+
if (sound) playSound(sound, latest.current.soundsEnabled);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}, [client, toasts]);
|
|
64
|
+
|
|
65
|
+
useResumedAfterSettings(resumedAfterSettings, toasts);
|
|
66
|
+
|
|
67
|
+
const noteOwnMicrophoneChange = useCallback(() => {
|
|
68
|
+
ownMicrophoneChange.current = true;
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
const reportMediaFailure = useCallback(
|
|
72
|
+
(permission: Permission, cause: unknown, retry: () => void) => {
|
|
73
|
+
const code = cause instanceof SpaceClientError ? cause.code : null;
|
|
74
|
+
const icon: IconName = permission === "microphone" ? "micOff" : "camOff";
|
|
75
|
+
const leading = <Icon color={latest.current.colors.dangerText} name={icon} />;
|
|
76
|
+
playSound("error", latest.current.soundsEnabled);
|
|
77
|
+
if (code === "media.permission_denied") {
|
|
78
|
+
const id = toasts.show({
|
|
79
|
+
kind: "error",
|
|
80
|
+
leading,
|
|
81
|
+
wrap: true,
|
|
82
|
+
dismissible: true,
|
|
83
|
+
testID: `toast.${permission}-denied`,
|
|
84
|
+
message: [{ strong: `Chalk can’t use your ${permission}.` }, Platform.OS === "ios" ? ` Allow it in Settings, then turn your ${permission} back on.` : " Allow it in Settings."],
|
|
85
|
+
actions: [
|
|
86
|
+
{
|
|
87
|
+
label: "Open Settings",
|
|
88
|
+
testID: "toast.open-settings",
|
|
89
|
+
onPress: () => {
|
|
90
|
+
toasts.dismiss(id);
|
|
91
|
+
onOpenSettings?.(permission);
|
|
92
|
+
void Linking.openSettings();
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (code === "media.device_busy") {
|
|
100
|
+
const id = toasts.show({
|
|
101
|
+
kind: "error",
|
|
102
|
+
leading,
|
|
103
|
+
wrap: true,
|
|
104
|
+
dismissible: true,
|
|
105
|
+
testID: `toast.${permission}-busy`,
|
|
106
|
+
message: `Another app is using your ${permission}`,
|
|
107
|
+
actions: [
|
|
108
|
+
{
|
|
109
|
+
label: "Try again",
|
|
110
|
+
testID: "toast.try-again",
|
|
111
|
+
onPress: () => {
|
|
112
|
+
toasts.dismiss(id);
|
|
113
|
+
retry();
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
toasts.show({ kind: "error", leading, dismissible: true, wrap: true, message: cause instanceof Error ? `Couldn’t turn on your ${permission}. ${cause.message}` : `Couldn’t turn on your ${permission}.` });
|
|
121
|
+
},
|
|
122
|
+
[onOpenSettings, toasts],
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return { noteOwnMicrophoneChange, reportMediaFailure };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** After Open Settings on iOS the OS restarts Chalk; once the call is live again, say why it rejoined. */
|
|
129
|
+
function useResumedAfterSettings(permission: Permission | undefined, toasts: Toasts): void {
|
|
130
|
+
const client = useSpaceClient();
|
|
131
|
+
const { colors } = useTheme();
|
|
132
|
+
const shown = useRef(false);
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (!permission) return;
|
|
135
|
+
const check = () => {
|
|
136
|
+
if (shown.current || client.getSnapshot().connection.status !== "live") return;
|
|
137
|
+
shown.current = true;
|
|
138
|
+
toasts.show({ leading: <Icon color={colors.textMuted} name="check" />, message: `You’re back in the call. Chalk can use your ${permission} now.`, testID: "toast.resumed" });
|
|
139
|
+
};
|
|
140
|
+
check();
|
|
141
|
+
return client.subscribe(check);
|
|
142
|
+
}, [client, colors, permission, toasts]);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type NoticeContext = {
|
|
146
|
+
readonly client: SpaceClient;
|
|
147
|
+
readonly toasts: Toasts;
|
|
148
|
+
readonly colors: Palette;
|
|
149
|
+
/** Dismisses this notice, for actions that act on it. */
|
|
150
|
+
readonly dismiss: () => void;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
function noticeToast(notice: Notice, { client, toasts, colors, dismiss }: NoticeContext): { readonly input: ToastInput; readonly sound?: SoundName } {
|
|
154
|
+
const icon = (name: IconName, tone: "muted" | "danger" = "muted") => <Icon color={tone === "danger" ? colors.dangerText : colors.textMuted} name={name} />;
|
|
155
|
+
const avatar = (name: string) => <FaceAvatar name={name} size={28} />;
|
|
156
|
+
switch (notice.kind) {
|
|
157
|
+
case "joined":
|
|
158
|
+
return { input: { leading: avatar(notice.name), message: [{ strong: notice.name }, " joined"], testID: "toast.joined" }, sound: "join" };
|
|
159
|
+
case "left":
|
|
160
|
+
return { input: { leading: avatar(notice.name), message: [{ strong: notice.name }, " left"], testID: "toast.left" }, sound: "leave" };
|
|
161
|
+
case "mutedByHost":
|
|
162
|
+
return {
|
|
163
|
+
input: notice.by ? { leading: avatar(notice.by), message: [{ strong: notice.by }, " muted you. Unmute when you’re ready."], testID: "toast.muted-by-host" } : { leading: icon("micOff"), message: "You were muted. Unmute when you’re ready.", testID: "toast.muted-by-host" },
|
|
164
|
+
sound: "mute",
|
|
165
|
+
};
|
|
166
|
+
case "mediaRequest": {
|
|
167
|
+
const { request } = notice;
|
|
168
|
+
const who = request.actorDisplayName ? firstName(request.actorDisplayName) : "The host";
|
|
169
|
+
const unmute = request.kind === "unmute";
|
|
170
|
+
const accept = () => {
|
|
171
|
+
dismiss();
|
|
172
|
+
client.media.acceptRequest(request.requestId).catch(() => toasts.show({ kind: "error", dismissible: true, message: unmute ? "Couldn’t unmute you." : "Couldn’t turn on your camera." }));
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
input: {
|
|
176
|
+
leading: icon(unmute ? "mic" : "cam"),
|
|
177
|
+
message: unmute ? `${who} asks you to unmute` : `${who} asks you to turn on your camera`,
|
|
178
|
+
testID: "toast.media-request",
|
|
179
|
+
actions: [{ label: unmute ? "Unmute" : "Turn on", variant: "primary", testID: "toast.accept-request", onPress: accept }],
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
case "newHost":
|
|
184
|
+
return { input: { leading: icon("users"), message: [{ strong: notice.previousHost }, " left. You’re now the host."], testID: "toast.new-host" }, sound: "leave" };
|
|
185
|
+
case "shareStopped":
|
|
186
|
+
return { input: { leading: icon("shareOff"), message: [{ strong: notice.name }, " stopped sharing"], testID: "toast.share-stopped" } };
|
|
187
|
+
case "recordingStarted":
|
|
188
|
+
return { input: { leading: icon("rec", "danger"), message: [{ strong: "Recording started." }, " Everyone in the call can see it."], testID: "toast.recording-started" }, sound: "recording" };
|
|
189
|
+
case "recordingStopped":
|
|
190
|
+
return { input: { leading: icon("rec"), message: "Recording stopped", testID: "toast.recording-stopped" } };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Capability, Participant, SpaceSnapshot } from "@q9labsai/chalk-client";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { callNotices } from "./notices";
|
|
4
|
+
|
|
5
|
+
const HOST: readonly Capability[] = ["endEpisode", "muteOthers"];
|
|
6
|
+
|
|
7
|
+
function person(participantId: string, displayName: string, capabilities: readonly Capability[] = [], screenShare: "active" | "inactive" = "inactive"): Participant {
|
|
8
|
+
return {
|
|
9
|
+
participantId,
|
|
10
|
+
displayName,
|
|
11
|
+
role: capabilities.length ? "host" : "guest",
|
|
12
|
+
eligibleRoles: [],
|
|
13
|
+
capabilities,
|
|
14
|
+
handRaised: false,
|
|
15
|
+
media: { microphone: "inactive", camera: "inactive", screenShare },
|
|
16
|
+
presence: { state: "connected", speaking: false, activeSpeaker: false },
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type Shape = {
|
|
21
|
+
readonly status?: SpaceSnapshot["connection"]["status"];
|
|
22
|
+
readonly roster?: readonly Participant[];
|
|
23
|
+
readonly selfCapabilities?: readonly Capability[];
|
|
24
|
+
readonly microphone?: "enabled" | "disabled";
|
|
25
|
+
readonly requests?: SpaceSnapshot["media"]["incomingRequests"];
|
|
26
|
+
readonly recording?: "recording" | "stopped";
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function snapshot({ status = "live", roster = [], selfCapabilities = [], microphone = "disabled", requests = [], recording }: Shape): SpaceSnapshot {
|
|
30
|
+
const local = (state: "enabled" | "disabled") => ({ source: "microphone" as const, state, track: null });
|
|
31
|
+
return {
|
|
32
|
+
connection: { status, episode: null, lastError: null },
|
|
33
|
+
self: { participantId: "me", displayName: "Hasan", role: null, capabilities: selfCapabilities, handRaised: false, can: (capability) => selfCapabilities.includes(capability) },
|
|
34
|
+
participants: { roster: [person("me", "Hasan", selfCapabilities), ...roster], admissionQueue: [] },
|
|
35
|
+
media: {
|
|
36
|
+
devices: { microphones: [], cameras: [], speakers: [] },
|
|
37
|
+
selection: { microphone: null, camera: null, speaker: null },
|
|
38
|
+
local: { microphone: local(microphone), camera: { ...local("disabled"), source: "camera" }, screen: { ...local("disabled"), source: "screen" } },
|
|
39
|
+
remote: [],
|
|
40
|
+
screenShare: { ...local("disabled"), source: "screen" },
|
|
41
|
+
incomingRequests: requests,
|
|
42
|
+
},
|
|
43
|
+
chat: { status: "ready", messages: [], pendingSends: [], readReceipts: [], unreadCount: 0, pagination: { cursor: null, hasOlder: false, historyTruncated: false }, lastError: null },
|
|
44
|
+
reactions: { active: [] },
|
|
45
|
+
recording: { current: recording ? { recordingId: "r1", status: recording, failureCode: null } : null },
|
|
46
|
+
whiteboard: { open: false, engine: { status: "unsubscribed", sceneId: null, revision: null, presenting: false, error: null } },
|
|
47
|
+
offline: { pending: [], decisionNeeded: false, policy: "ask" },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const nora = person("nora", "Nora Lindqvist", HOST);
|
|
52
|
+
const sam = person("sam", "Sam Okafor");
|
|
53
|
+
|
|
54
|
+
describe("callNotices", () => {
|
|
55
|
+
it("says nothing while the roster arrives on join or empties on leave", () => {
|
|
56
|
+
expect(callNotices(snapshot({ status: "joining" }), snapshot({ roster: [nora, sam] }), false)).toEqual([]);
|
|
57
|
+
expect(callNotices(snapshot({ roster: [nora, sam] }), snapshot({ status: "left" }), false)).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("names people who join and leave, but never you", () => {
|
|
61
|
+
expect(callNotices(snapshot({ roster: [nora] }), snapshot({ roster: [nora, sam] }), false)).toEqual([{ kind: "joined", name: "Sam Okafor" }]);
|
|
62
|
+
expect(callNotices(snapshot({ roster: [nora, sam] }), snapshot({ roster: [nora] }), false)).toEqual([{ kind: "left", name: "Sam Okafor" }]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("tells you the host left and you're the host now, instead of a plain leave", () => {
|
|
66
|
+
const notices = callNotices(snapshot({ roster: [nora, sam] }), snapshot({ roster: [sam], selfCapabilities: HOST }), false);
|
|
67
|
+
expect(notices).toEqual([{ kind: "newHost", previousHost: "Nora" }]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("reports a host mute only when you didn't mute yourself", () => {
|
|
71
|
+
const before = snapshot({ roster: [nora, sam], microphone: "enabled" });
|
|
72
|
+
const after = snapshot({ roster: [nora, sam], microphone: "disabled" });
|
|
73
|
+
expect(callNotices(before, after, false)).toEqual([{ kind: "mutedByHost", by: "Nora" }]);
|
|
74
|
+
expect(callNotices(before, after, true)).toEqual([]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("reports each new request to unmute once", () => {
|
|
78
|
+
const request = { requestId: "q1", kind: "unmute" as const, actorParticipantId: "nora", actorDisplayName: "Nora Lindqvist", expiresAt: "2026-10-18T12:00:00Z" };
|
|
79
|
+
expect(callNotices(snapshot({ roster: [nora] }), snapshot({ roster: [nora], requests: [request] }), false)).toEqual([{ kind: "mediaRequest", request }]);
|
|
80
|
+
expect(callNotices(snapshot({ roster: [nora], requests: [request] }), snapshot({ roster: [nora], requests: [request] }), false)).toEqual([]);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("reports when someone else stops sharing", () => {
|
|
84
|
+
const sharing = person("sam", "Sam Okafor", [], "active");
|
|
85
|
+
expect(callNotices(snapshot({ roster: [sharing] }), snapshot({ roster: [sam] }), false)).toEqual([{ kind: "shareStopped", name: "Sam" }]);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("reports recording starting and stopping", () => {
|
|
89
|
+
expect(callNotices(snapshot({}), snapshot({ recording: "recording" }), false)).toEqual([{ kind: "recordingStarted" }]);
|
|
90
|
+
expect(callNotices(snapshot({ recording: "recording" }), snapshot({ recording: "stopped" }), false)).toEqual([{ kind: "recordingStopped" }]);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { IncomingMediaRequest, Participant, SpaceSnapshot } from "@q9labsai/chalk-client";
|
|
2
|
+
|
|
3
|
+
/** A call event worth a notice, read from the difference between two snapshots. */
|
|
4
|
+
export type Notice =
|
|
5
|
+
| { readonly kind: "joined"; readonly name: string }
|
|
6
|
+
| { readonly kind: "left"; readonly name: string }
|
|
7
|
+
| { readonly kind: "mutedByHost"; readonly by: string | null }
|
|
8
|
+
| { readonly kind: "mediaRequest"; readonly request: IncomingMediaRequest }
|
|
9
|
+
| { readonly kind: "newHost"; readonly previousHost: string }
|
|
10
|
+
| { readonly kind: "shareStopped"; readonly name: string }
|
|
11
|
+
| { readonly kind: "recordingStarted" }
|
|
12
|
+
| { readonly kind: "recordingStopped" };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Notices for what changed between `previous` and `next`. Only changes inside a live call count,
|
|
16
|
+
* so the roster arriving on join or emptying on leave says nothing. `ownMicrophoneChange` is true
|
|
17
|
+
* when the person turned their own microphone off since the last snapshot.
|
|
18
|
+
*/
|
|
19
|
+
export function callNotices(previous: SpaceSnapshot, next: SpaceSnapshot, ownMicrophoneChange: boolean): readonly Notice[] {
|
|
20
|
+
if (previous.connection.status !== "live" || next.connection.status !== "live") return [];
|
|
21
|
+
const self = next.self.participantId;
|
|
22
|
+
const before = new Map(previous.participants.roster.map((participant) => [participant.participantId, participant]));
|
|
23
|
+
const after = new Map(next.participants.roster.map((participant) => [participant.participantId, participant]));
|
|
24
|
+
const notices: Notice[] = [];
|
|
25
|
+
|
|
26
|
+
const departed = [...before.values()].filter((participant) => !after.has(participant.participantId) && participant.participantId !== self);
|
|
27
|
+
const becameHost = !previous.self.can("endEpisode") && next.self.can("endEpisode");
|
|
28
|
+
const departedHost = becameHost ? departed.find(isHost) : undefined;
|
|
29
|
+
if (departedHost) notices.push({ kind: "newHost", previousHost: firstName(departedHost.displayName) });
|
|
30
|
+
|
|
31
|
+
for (const participant of after.values()) if (!before.has(participant.participantId) && participant.participantId !== self) notices.push({ kind: "joined", name: participant.displayName });
|
|
32
|
+
for (const participant of departed) if (participant !== departedHost) notices.push({ kind: "left", name: participant.displayName });
|
|
33
|
+
|
|
34
|
+
for (const participant of after.values()) {
|
|
35
|
+
if (participant.participantId === self) continue;
|
|
36
|
+
if (before.get(participant.participantId)?.media.screenShare === "active" && participant.media.screenShare !== "active") notices.push({ kind: "shareStopped", name: firstName(participant.displayName) });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (previous.media.local.microphone.state === "enabled" && next.media.local.microphone.state === "disabled" && !ownMicrophoneChange) {
|
|
40
|
+
const muters = next.participants.roster.filter((participant) => participant.participantId !== self && participant.capabilities.includes("muteOthers"));
|
|
41
|
+
notices.push({ kind: "mutedByHost", by: muters.length === 1 && muters[0] ? firstName(muters[0].displayName) : null });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const known = new Set(previous.media.incomingRequests.map((request) => request.requestId));
|
|
45
|
+
for (const request of next.media.incomingRequests) if (!known.has(request.requestId)) notices.push({ kind: "mediaRequest", request });
|
|
46
|
+
|
|
47
|
+
const wasRecording = previous.recording.current?.status === "recording";
|
|
48
|
+
const isRecording = next.recording.current?.status === "recording";
|
|
49
|
+
if (!wasRecording && isRecording) notices.push({ kind: "recordingStarted" });
|
|
50
|
+
if (wasRecording && !isRecording) notices.push({ kind: "recordingStopped" });
|
|
51
|
+
|
|
52
|
+
return notices;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isHost(participant: Participant): boolean {
|
|
56
|
+
return participant.capabilities.includes("endEpisode");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The mockup names people by their first name in notices that ask something of you. */
|
|
60
|
+
export function firstName(name: string): string {
|
|
61
|
+
return name.trim().split(/\s+/)[0] ?? name;
|
|
62
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
4
|
+
import { SafeAreaProvider } from "react-native-safe-area-context";
|
|
5
|
+
import { DeviceLayoutProvider } from "../frame/device-layout";
|
|
6
|
+
import { PortalHost, PortalProvider } from "../frame/portal";
|
|
7
|
+
import { ToastProvider, ToastStack } from "../primitives/toast/ToastStack";
|
|
8
|
+
import { ThemeProvider } from "../theme/theme";
|
|
9
|
+
import type { ColorScheme } from "../theme/tokens";
|
|
10
|
+
|
|
11
|
+
export type ChalkUIProps = {
|
|
12
|
+
readonly colorScheme: ColorScheme;
|
|
13
|
+
readonly children: ReactNode;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Everything the call's primitives need, for the screens an app draws around `Chalk` (its Home, for
|
|
18
|
+
* example): theme, safe areas, sheets, menus and toasts. Sheets and menus open above `children`.
|
|
19
|
+
*/
|
|
20
|
+
export function ChalkUI({ colorScheme, children }: ChalkUIProps): React.JSX.Element {
|
|
21
|
+
return (
|
|
22
|
+
<GestureHandlerRootView style={styles.root}>
|
|
23
|
+
<SafeAreaProvider>
|
|
24
|
+
<ThemeProvider colorScheme={colorScheme}>
|
|
25
|
+
<DeviceLayoutProvider>
|
|
26
|
+
<PortalProvider>
|
|
27
|
+
<ToastProvider>
|
|
28
|
+
<View style={styles.root}>
|
|
29
|
+
{children}
|
|
30
|
+
<View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
|
|
31
|
+
<PortalHost layer="sheets" />
|
|
32
|
+
</View>
|
|
33
|
+
<View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
|
|
34
|
+
<PortalHost layer="menus" />
|
|
35
|
+
</View>
|
|
36
|
+
<ToastStack />
|
|
37
|
+
</View>
|
|
38
|
+
</ToastProvider>
|
|
39
|
+
</PortalProvider>
|
|
40
|
+
</DeviceLayoutProvider>
|
|
41
|
+
</ThemeProvider>
|
|
42
|
+
</SafeAreaProvider>
|
|
43
|
+
</GestureHandlerRootView>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const styles = StyleSheet.create({
|
|
48
|
+
root: { flex: 1 },
|
|
49
|
+
});
|
package/src/ui.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** The call's look, for the screens an app draws around `Chalk`: Home, joining and the name step. */
|
|
2
|
+
export { ChalkUI } from "./ui/ChalkUI";
|
|
3
|
+
export type { ChalkUIProps } from "./ui/ChalkUI";
|
|
4
|
+
export { useTheme } from "./theme/theme";
|
|
5
|
+
export type { Theme } from "./theme/theme";
|
|
6
|
+
export { fixed, fontFamilies, radii, type } from "./theme/tokens";
|
|
7
|
+
export type { ColorScheme, Palette } from "./theme/tokens";
|
|
8
|
+
export { useDeviceLayout } from "./frame/device-layout";
|
|
9
|
+
export { Icon } from "./icons/Icon";
|
|
10
|
+
export type { IconName } from "./icons/Icon";
|
|
11
|
+
export { ChalkText } from "./primitives/ChalkText";
|
|
12
|
+
export { IconButton } from "./primitives/IconButton";
|
|
13
|
+
export { PillButton } from "./primitives/PillButton";
|
|
14
|
+
export { BottomSheet } from "./primitives/BottomSheet";
|
|
15
|
+
export { SheetGroup, SheetRow } from "./primitives/SheetGroup";
|
|
16
|
+
export { Menu, MenuItem } from "./primitives/Menu";
|
|
17
|
+
export { Switch } from "./primitives/Switch";
|
|
18
|
+
export { SegmentedControl } from "./primitives/SegmentedControl";
|
|
19
|
+
export { CopyButton } from "./primitives/CopyButton";
|
|
20
|
+
export { FaceAvatar } from "./avatar/FaceAvatar";
|
|
21
|
+
export { useToastClearance, useToasts } from "./primitives/toast/ToastStack";
|
|
22
|
+
export { announce } from "./primitives/announce";
|
|
23
|
+
export { usePressAnimation } from "./motion/press";
|
|
24
|
+
export { Limbo } from "./limbo/Limbo";
|
package/dist/android.d.ts
DELETED
package/dist/android.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../src/android.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
|