From 745f4ad432db43b713b060229cd17d6182743021 Mon Sep 17 00:00:00 2001 From: Milosz Filimowski Date: Mon, 9 Feb 2026 09:51:48 +0100 Subject: [PATCH 1/3] update background calls --- docs/how-to/client/background-streaming.mdx | 104 ++++++++++++++++++-- docs/how-to/client/installation.mdx | 10 +- docs/how-to/client/migration-guide.mdx | 37 +------ 3 files changed, 103 insertions(+), 48 deletions(-) diff --git a/docs/how-to/client/background-streaming.mdx b/docs/how-to/client/background-streaming.mdx index 423f9a5..f719bda 100644 --- a/docs/how-to/client/background-streaming.mdx +++ b/docs/how-to/client/background-streaming.mdx @@ -96,23 +96,113 @@ granted and only then allow to start a service. ::: ```tsx -import { useCamera, useMicrophone } from "@fishjam-cloud/react-native-client"; +import { + useForegroundService, + useCamera, + useMicrophone, +} from "@fishjam-cloud/react-native-client"; const { isCameraOn } = useCamera(); const { isMicrophoneOn } = useMicrophone(); + +useForegroundService({ // [!code highlight] + channelId: "io.fishjam.example.fishjamchat.foregroundservice.channel", + channelName: "Fishjam Chat Notifications", + notificationTitle: "Your video call is ongoing", + notificationContent: "Tap to return to the call.", + enableCamera: isCameraOn, + enableMicrophone: isMicrophoneOn, +}); ``` -On iOS, background calls are achieved through CallKit integration. To enable background streaming on iOS: +On iOS, background calls are achieved through CallKit integration. You can use the CallKit hooks to manage VoIP calls that continue running in the background. -1. Enable VoIP background mode by setting `enableVoIPBackgroundMode: true` in the plugin configuration or adding the VoIP background mode to your `Info.plist` -2. The SDK will automatically handle CallKit integration for maintaining background audio/video sessions +### Manual CallKit Management -:::note -CallKit integration is handled automatically by the SDK when VoIP background mode is enabled. The call will appear in the iOS call history and can be managed through the native phone interface. -::: +Use the [`useCallKit`](../../api/mobile/variables/useCallKit) hook for fine-grained control over CallKit sessions: + +```tsx +import { useCallKit } from "@fishjam-cloud/react-native-client"; + +const { startCallKitSession, endCallKitSession } = useCallKit(); + +// Start CallKit session when joining a room +const handleJoinRoom = async () => { + await startCallKitSession({ + displayName: "John Doe", + isVideo: true, + }); + // ... join room logic +}; + +// End CallKit session when leaving +const handleLeaveRoom = async () => { + await endCallKitSession(); + // ... leave room logic +}; +``` + +### Automatic CallKit Management + +Use the [`useCallKitService`](../../api/mobile/variables/useCallKitService) hook for automatic session lifecycle management: + +```tsx +import React from "react"; +import { useCallKitService } from "@fishjam-cloud/react-native-client"; +import { View } from "react-native"; + +function CallScreen({ username }: { username: string }) { + // CallKit session automatically starts when component mounts + // and ends when component unmounts + useCallKitService({ + displayName: username, + isVideo: true, + }); + + return ...; +} +``` + +### Listening to CallKit Events + +Use the [`useCallKitEvent`](../../api/mobile/variables/useCallKitEvent) hook to respond to user interactions with the native CallKit interface: + +```tsx +import { + useCallKitEvent, + useCamera, + useMicrophone, + useConnection, +} from "@fishjam-cloud/react-native-client"; + +const { toggleCamera } = useCamera(); +const { startMicrophone, stopMicrophone } = useMicrophone(); +const { leaveRoom } = useConnection(); + +// Listen for mute toggle from CallKit UI +useCallKitEvent("muted", (isMuted: boolean) => { + if (isMuted) { + stopMicrophone(); + } else { + startMicrophone(); + } +}); + +// Listen for hold state changes +useCallKitEvent("held", (isOnHold: boolean) => { + console.log("Call hold state:", isOnHold); + // Handle hold state in your app +}); + +// Listen for call end from CallKit UI +useCallKitEvent("ended", () => { + // Handle call termination + leaveRoom(); +}); +``` diff --git a/docs/how-to/client/installation.mdx b/docs/how-to/client/installation.mdx index 415560d..14cf23d 100644 --- a/docs/how-to/client/installation.mdx +++ b/docs/how-to/client/installation.mdx @@ -89,13 +89,11 @@ Your app needs to have permissions configured in order to use the microphone and ### Android -Permissions below are required to stream audio and video with Fishjam on Android. +These permissions are required to stream audio and video with Fishjam on Android: - `android.permission.CAMERA` - `android.permission.RECORD_AUDIO` - `android.permission.MODIFY_AUDIO_SETTINGS` -- `android.permission.ACCESS_NETWORK_STATE` -- `android.permission.ACCESS_WIFI_STATE` @@ -112,9 +110,7 @@ Add required permissions to the `app.json` file. "permissions": [ "android.permission.CAMERA", "android.permission.RECORD_AUDIO", - "android.permission.MODIFY_AUDIO_SETTINGS", - "android.permission.ACCESS_NETWORK_STATE", - "android.permission.ACCESS_WIFI_STATE" + "android.permission.MODIFY_AUDIO_SETTINGS" ] } } @@ -131,7 +127,7 @@ Add required permissions to the `AndroidManifest.xml` file. ... - + ... ``` diff --git a/docs/how-to/client/migration-guide.mdx b/docs/how-to/client/migration-guide.mdx index ccee676..871d4a6 100644 --- a/docs/how-to/client/migration-guide.mdx +++ b/docs/how-to/client/migration-guide.mdx @@ -1,9 +1,9 @@ --- -sidebar_position: 0 -sidebar_label: "Migration Guide 📱" +sidebar_position: 14 +sidebar_label: "0.25.x Migration Guide 📱" --- -# Migration Guide Mobile +# 0.25.x Migration Guide Mobile # Upgrading @fishjam-cloud/react-native-client from 0.24 to 0.25 @@ -442,34 +442,3 @@ const [micPermission, requestMicPermission] = useMicrophonePermissions(); ### After Permissions are now handled automatically by the SDK. When you call initializeDevices(), the SDK will automatically request camera and microphone permissions if they haven't been granted yet. - -### CallKit Hooks - -### Before - -```tsx -// @noErrors -import { - useCallKit, - useCallKitService, - useCallKitEvent, -} from "@fishjam-cloud/react-native-client"; - -// Manual CallKit control -const { startCallKitSession, endCallKitSession } = useCallKit(); - -// Automatic CallKit service -useCallKitService({ - displayName: "User Name", - isVideo: true, -}); - -// CallKit events -useCallKitEvent("muted", (isMuted) => { - // Handle mute event -}); -``` - -### After - -CallKit integration is now handled automatically by the SDK when VoIP background mode is enabled. You no longer need to manually manage CallKit sessions. From 99bac0a62cffdcb3d7100122a2e0798717c061dc Mon Sep 17 00:00:00 2001 From: Milosz Filimowski Date: Mon, 9 Feb 2026 10:03:18 +0100 Subject: [PATCH 2/3] improve docs --- docs/how-to/client/background-streaming.mdx | 30 ++++++++++++++++----- docs/how-to/client/connecting.mdx | 2 +- docs/how-to/client/screensharing.mdx | 8 ------ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/how-to/client/background-streaming.mdx b/docs/how-to/client/background-streaming.mdx index f719bda..0b2cbc9 100644 --- a/docs/how-to/client/background-streaming.mdx +++ b/docs/how-to/client/background-streaming.mdx @@ -53,14 +53,28 @@ You need to modify `app.json` file and add our plugin: **Android Configuration** -You need to add the following service to `AndroidManifest.xml`: +Add the following permissions and services to `AndroidManifest.xml`: ```xml title='AndroidManifest.xml' ... + + + + ... - + + + ``` @@ -105,13 +119,15 @@ import { const { isCameraOn } = useCamera(); const { isMicrophoneOn } = useMicrophone(); -useForegroundService({ // [!code highlight] +useForegroundService({ + // [!code highlight] channelId: "io.fishjam.example.fishjamchat.foregroundservice.channel", channelName: "Fishjam Chat Notifications", notificationTitle: "Your video call is ongoing", notificationContent: "Tap to return to the call.", enableCamera: isCameraOn, enableMicrophone: isMicrophoneOn, + // enableScreenSharing: true, }); ``` @@ -183,17 +199,17 @@ const { startMicrophone, stopMicrophone } = useMicrophone(); const { leaveRoom } = useConnection(); // Listen for mute toggle from CallKit UI -useCallKitEvent("muted", (isMuted: boolean) => { +useCallKitEvent("muted", (isMuted?: boolean) => { if (isMuted) { stopMicrophone(); - } else { + } else if (!isMuted) { startMicrophone(); } }); // Listen for hold state changes -useCallKitEvent("held", (isOnHold: boolean) => { - console.log("Call hold state:", isOnHold); +useCallKitEvent("held", (isHeld?: boolean) => { + console.log("Call hold state:", isHeld); // Handle hold state in your app }); diff --git a/docs/how-to/client/connecting.mdx b/docs/how-to/client/connecting.mdx index fc08847..f112ec6 100644 --- a/docs/how-to/client/connecting.mdx +++ b/docs/how-to/client/connecting.mdx @@ -170,4 +170,4 @@ Now that you're connected to a room, you can explore additional features: - [List Other Peers](./list-other-peers) - Display video from other participants - [Data Channels](../../explanation/data-channels) - Send and receive arbitrary data between peers (e.g., text chat) - [Picture in Picture](./picture-in-picture) - Allow users to watch video in a floating window (Mobile) -- [Background Streaming](./background-streaming) - Keep calls active when the app is backgrounded (Mobile) +- [Background Calls](./background-streaming) - Keep calls active when the app is backgrounded (Mobile) diff --git a/docs/how-to/client/screensharing.mdx b/docs/how-to/client/screensharing.mdx index 184cc68..1c400c4 100644 --- a/docs/how-to/client/screensharing.mdx +++ b/docs/how-to/client/screensharing.mdx @@ -210,14 +210,6 @@ Configuring screen sharing on iOS is a little complicated. -:::tip[Background streaming during screen sharing] - -If you want to continue screen sharing when the app goes to the background, you need to enable VoIP background mode by setting `enableVoIPBackgroundMode: true` in the plugin configuration or adding the VoIP background mode to your `Info.plist`. - -See the [background calls documentation](./background-streaming) for detailed instructions and code examples. - -::: - ## Usage You can use [`useScreenShare`](../../api/mobile/variables/useScreenShare) hook to enable screen sharing. From 134c4121935ac423733416e0f98c8e1f573610a0 Mon Sep 17 00:00:00 2001 From: Milosz Filimowski Date: Mon, 9 Feb 2026 10:18:05 +0100 Subject: [PATCH 3/3] implement copilot suggestions --- docs/how-to/client/background-streaming.mdx | 5 ++--- docs/how-to/client/migration-guide.mdx | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/how-to/client/background-streaming.mdx b/docs/how-to/client/background-streaming.mdx index 0b2cbc9..eb6e47d 100644 --- a/docs/how-to/client/background-streaming.mdx +++ b/docs/how-to/client/background-streaming.mdx @@ -194,15 +194,14 @@ import { useConnection, } from "@fishjam-cloud/react-native-client"; -const { toggleCamera } = useCamera(); const { startMicrophone, stopMicrophone } = useMicrophone(); const { leaveRoom } = useConnection(); // Listen for mute toggle from CallKit UI useCallKitEvent("muted", (isMuted?: boolean) => { - if (isMuted) { + if (isMuted === true) { stopMicrophone(); - } else if (!isMuted) { + } else if (isMuted === false) { startMicrophone(); } }); diff --git a/docs/how-to/client/migration-guide.mdx b/docs/how-to/client/migration-guide.mdx index 871d4a6..270813b 100644 --- a/docs/how-to/client/migration-guide.mdx +++ b/docs/how-to/client/migration-guide.mdx @@ -24,9 +24,7 @@ Add the following WebRTC permissions to your Android configuration in `app.json` "permissions": [ "android.permission.CAMERA", "android.permission.RECORD_AUDIO", - "android.permission.MODIFY_AUDIO_SETTINGS", - "android.permission.ACCESS_NETWORK_STATE", - "android.permission.ACCESS_WIFI_STATE" + "android.permission.MODIFY_AUDIO_SETTINGS" ] } }