Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion docs/explanation/data-channels.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,22 @@ This separation allows you to use both channels simultaneously for different pur

## Using Data Channels

Use the [`useDataChannel`](../api/web/functions/useDataChannel) hook to work with data channels. The typical flow is:
Use the `useDataChannel` hook to work with data channels. The hook is available in both the web and mobile SDKs with the same API:

<Tabs groupId="platform">
<TabItem value="web" label="React (Web)">

Use [`useDataChannel`](../api/web/functions/useDataChannel) from `@fishjam-cloud/react-client`.

</TabItem>
<TabItem value="mobile" label="React Native (Mobile)">

Use [`useDataChannel`](../api/mobile/functions/useDataChannel) from `@fishjam-cloud/react-native-client`.

</TabItem>
</Tabs>

The typical flow is:

1. Initialize the data channel after connecting to a room
2. Subscribe to incoming messages
Expand Down
32 changes: 28 additions & 4 deletions docs/how-to/client/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,45 @@ You can also follow more detailed [Expo instructions](https://docs.expo.dev/get-

## Step 1: Install the Package

Install `@fishjam-cloud/react-native-client` with your preferred package manager.
<Tabs groupId="app-type">

<TabItem value="expo" label="Expo (SDK 54+)">

Install `@fishjam-cloud/react-native-client` and `react-native-get-random-values` with your preferred package manager.

```bash npm2yarn
npm install @fishjam-cloud/react-native-client react-native-get-random-values@1.11.0
```

Expo SDK 54+ resolves native dependencies recursively, so `@fishjam-cloud/react-native-webrtc` (a transitive dependency) is autolinked automatically.

</TabItem>
<TabItem value="rn" label="Bare React Native / Expo SDK < 54">

Install `@fishjam-cloud/react-native-client`, `@fishjam-cloud/react-native-webrtc`, and `react-native-get-random-values`:

```bash npm2yarn
npm install @fishjam-cloud/react-native-client
npm install @fishjam-cloud/react-native-client @fishjam-cloud/react-native-webrtc react-native-get-random-values@1.11.0
```

Bare React Native and Expo SDK versions below 54 only autolink direct dependencies.
`@fishjam-cloud/react-native-webrtc` must be in your app's `package.json` for its native code to be linked.

</TabItem>
</Tabs>

## Step 2: Configure App Permissions

Your app needs to have permissions configured in order to use the microphone and camera.

### Android

These permissions are required to stream audio and video with Fishjam on Android:
The following Android permissions are required by Fishjam:

- `android.permission.CAMERA`
- `android.permission.RECORD_AUDIO`
- `android.permission.MODIFY_AUDIO_SETTINGS`
- `android.permission.ACCESS_NETWORK_STATE`

<Tabs groupId="app-type">

Expand All @@ -110,7 +132,8 @@ Add required permissions to the `app.json` file.
"permissions": [
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
"android.permission.MODIFY_AUDIO_SETTINGS"
"android.permission.MODIFY_AUDIO_SETTINGS",
"android.permission.ACCESS_NETWORK_STATE"
]
}
}
Expand All @@ -128,6 +151,7 @@ Add required permissions to the `AndroidManifest.xml` file.
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
...
</manifest>
```
Expand Down
3 changes: 2 additions & 1 deletion docs/how-to/client/migration-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ 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.MODIFY_AUDIO_SETTINGS",
"android.permission.ACCESS_NETWORK_STATE"
]
}
}
Expand Down
159 changes: 153 additions & 6 deletions docs/how-to/features/text-chat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ For a deeper understanding of how data channels work, including channel types an

## Step 1 — Set up the chat hook

Use the [`useDataChannel`](/api/web/functions/useDataChannel) hook to work with data channels. The typical flow is:
Use the [`useDataChannel`](/api/web/functions/useDataChannel) (web) or [`useDataChannel`](/api/mobile/functions/useDataChannel) (mobile) hook to work with data channels. The typical flow is:

1. Initialize the data channel after connecting to a room
2. Subscribe to incoming messages
Expand Down Expand Up @@ -84,9 +84,67 @@ export function useChat() {
```

</TabItem>
<TabItem value="mobile" label="React Native (Mobile)" disabled>
<TabItem value="mobile" label="React Native (Mobile)">

Mobile SDK support for data channels will be available in a future release.
```tsx
import {
useConnection,
useDataChannel,
} from "@fishjam-cloud/react-native-client";
import { useCallback, useEffect, useState } from "react";

export function useChat() {
const { peerStatus } = useConnection();
const {
initializeDataChannel,
publishData,
subscribeData,
dataChannelReady,
dataChannelLoading,
dataChannelError,
} = useDataChannel();

const [messages, setMessages] = useState<string[]>([]);

useEffect(() => {
if (peerStatus === "connected") {
initializeDataChannel();
}
}, [peerStatus, initializeDataChannel]);

useEffect(() => {
if (dataChannelLoading || !dataChannelReady) return;

const unsubscribe = subscribeData(
(data: Uint8Array) => {
const message = new TextDecoder().decode(data);
setMessages((prev) => [...prev, message]);
},
{ reliable: true },
);

return unsubscribe;
}, [dataChannelReady, dataChannelLoading, subscribeData]);

const sendMessage = useCallback(
(text: string) => {
if (!dataChannelReady) return;

const encoded = new TextEncoder().encode(text);
publishData(encoded, { reliable: true });
},
[publishData, dataChannelReady],
);

return {
messages,
sendMessage,
ready: dataChannelReady,
loading: dataChannelLoading,
error: dataChannelError,
};
}
```

</TabItem>
</Tabs>
Expand Down Expand Up @@ -185,9 +243,97 @@ function ChatPanel() {
```

</TabItem>
<TabItem value="mobile" label="React Native (Mobile)" disabled>
<TabItem value="mobile" label="React Native (Mobile)">

```tsx
import React, { useState, useEffect, useCallback } from "react";
import { View, Text, TextInput, FlatList, Pressable } from "react-native";
import {
useConnection,
useDataChannel,
} from "@fishjam-cloud/react-native-client";

function useChat() {
const { peerStatus } = useConnection();
const {
initializeDataChannel,
publishData,
subscribeData,
dataChannelReady,
} = useDataChannel();

const [messages, setMessages] = useState<string[]>([]);

useEffect(() => {
if (peerStatus === "connected") {
initializeDataChannel();
}
}, [peerStatus, initializeDataChannel]);

Mobile SDK support for data channels will be available in a future release.
useEffect(() => {
if (!dataChannelReady) return;

const unsubscribe = subscribeData(
(data: Uint8Array) => {
const message = new TextDecoder().decode(data);
setMessages((prev) => [...prev, message]);
},
{ reliable: true },
);

return unsubscribe;
}, [subscribeData, dataChannelReady]);

const sendMessage = useCallback(
(text: string) => {
if (!dataChannelReady) return;

const encoded = new TextEncoder().encode(text);
publishData(encoded, { reliable: true });
},
[publishData, dataChannelReady],
);

return { messages, sendMessage, ready: dataChannelReady };
}

// ---cut---

function ChatPanel() {
const { messages, sendMessage, ready } = useChat();
const [input, setInput] = useState("");

const handleSend = () => {
if (input.trim()) {
sendMessage(input);
setInput("");
}
};

if (!ready) {
return <Text>Connecting to chat...</Text>;
}

return (
<View>
<FlatList
data={messages}
keyExtractor={(_, i) => String(i)}
renderItem={({ item }) => <Text>{item}</Text>}
/>
<TextInput
value={input}
onChangeText={setInput}
placeholder="Type a message..."
onSubmitEditing={handleSend}
/>
<Pressable onPress={handleSend}>
<Text>Send</Text>
</Pressable>
</View>
);
}
```

</TabItem>
</Tabs>
Expand All @@ -209,4 +355,5 @@ This ensures no chat messages are lost or arrive out of order.

- [Data Channels](../../explanation/data-channels) — detailed explanation of channel types and broadcast behavior
- [Connecting to a room](../../how-to/client/connecting) — prerequisite for using data channels
- [`useDataChannel` API reference](../../api/web/functions/useDataChannel)
- [`useDataChannel` API reference (Web)](../../api/web/functions/useDataChannel)
- [`useDataChannel` API reference (Mobile)](../../api/mobile/functions/useDataChannel)
3 changes: 2 additions & 1 deletion docs/tutorials/react-native-quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Add required permissions to the `app.json` file:
"permissions": [
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
"android.permission.MODIFY_AUDIO_SETTINGS"
"android.permission.MODIFY_AUDIO_SETTINGS",
"android.permission.ACCESS_NETWORK_STATE"
]
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-client-sdk
Submodule web-client-sdk updated 28 files
+1 −0 examples/mobile-client/text-chat/.env.example
+39 −0 examples/mobile-client/text-chat/.gitignore
+3 −0 examples/mobile-client/text-chat/.prettierrc
+19 −0 examples/mobile-client/text-chat/App.tsx
+141 −0 examples/mobile-client/text-chat/README.md
+41 −0 examples/mobile-client/text-chat/app.json
+10 −0 examples/mobile-client/text-chat/eslint.config.js
+54 −0 examples/mobile-client/text-chat/hooks/useConnectFishjam.ts
+5 −0 examples/mobile-client/text-chat/index.ts
+38 −0 examples/mobile-client/text-chat/navigation/RootNavigation.tsx
+34 −0 examples/mobile-client/text-chat/package.json
+296 −0 examples/mobile-client/text-chat/screens/chat/index.tsx
+90 −0 examples/mobile-client/text-chat/screens/home/index.tsx
+7 −0 examples/mobile-client/text-chat/tsconfig.json
+6 −13 packages/mobile-client/package.json
+4 −0 packages/mobile-client/src/index.ts
+1 −0 packages/mobile-client/src/webrtc-polyfill.ts
+1 −1 packages/protobufs/fishjam/agent_notifications.ts
+1 −1 packages/protobufs/fishjam/media_events/peer/peer.ts
+1 −1 packages/protobufs/fishjam/media_events/server/server.ts
+1 −1 packages/protobufs/fishjam/media_events/shared.ts
+1 −1 packages/protobufs/fishjam/notifications/shared.ts
+1 −1 packages/protobufs/fishjam/peer_notifications.ts
+1 −1 packages/protobufs/fishjam/server_notifications.ts
+2 −3 packages/react-client/src/utils/fishjamUrl.ts
+22 −1 packages/ts-client/src/FishjamClient.ts
+3 −4 packages/ts-client/src/livestream.ts
+37 −2 yarn.lock
17 changes: 16 additions & 1 deletion versioned_docs/version-0.25.0/explanation/data-channels.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,22 @@ This separation allows you to use both channels simultaneously for different pur

## Using Data Channels

Use the [`useDataChannel`](../api/web/functions/useDataChannel) hook to work with data channels. The typical flow is:
Use the `useDataChannel` hook to work with data channels. The hook is available in both the web and mobile SDKs with the same API:

<Tabs groupId="platform">
<TabItem value="web" label="React (Web)">

Use [`useDataChannel`](../api/web/functions/useDataChannel) from `@fishjam-cloud/react-client`.

</TabItem>
<TabItem value="mobile" label="React Native (Mobile)">

Use [`useDataChannel`](../api/mobile/functions/useDataChannel) from `@fishjam-cloud/react-native-client`.

</TabItem>
</Tabs>

The typical flow is:

1. Initialize the data channel after connecting to a room
2. Subscribe to incoming messages
Expand Down
32 changes: 28 additions & 4 deletions versioned_docs/version-0.25.0/how-to/client/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,45 @@ You can also follow more detailed [Expo instructions](https://docs.expo.dev/get-

## Step 1: Install the Package

Install `@fishjam-cloud/react-native-client` with your preferred package manager.
<Tabs groupId="app-type">

<TabItem value="expo" label="Expo (SDK 54+)">

Install `@fishjam-cloud/react-native-client` and `react-native-get-random-values` with your preferred package manager.

```bash npm2yarn
npm install @fishjam-cloud/react-native-client react-native-get-random-values@1.11.0
```

Expo SDK 54+ resolves native dependencies recursively, so `@fishjam-cloud/react-native-webrtc` (a transitive dependency) is autolinked automatically.

</TabItem>
<TabItem value="rn" label="Bare React Native / Expo SDK < 54">

Install `@fishjam-cloud/react-native-client`, `@fishjam-cloud/react-native-webrtc`, and `react-native-get-random-values`:

```bash npm2yarn
npm install @fishjam-cloud/react-native-client
npm install @fishjam-cloud/react-native-client @fishjam-cloud/react-native-webrtc react-native-get-random-values@1.11.0
```

Bare React Native and Expo SDK versions below 54 only autolink direct dependencies.
`@fishjam-cloud/react-native-webrtc` must be in your app's `package.json` for its native code to be linked.

</TabItem>
</Tabs>

## Step 2: Configure App Permissions

Your app needs to have permissions configured in order to use the microphone and camera.

### Android

These permissions are required to stream audio and video with Fishjam on Android:
The following Android permissions are required by Fishjam:

- `android.permission.CAMERA`
- `android.permission.RECORD_AUDIO`
- `android.permission.MODIFY_AUDIO_SETTINGS`
- `android.permission.ACCESS_NETWORK_STATE`

<Tabs groupId="app-type">

Expand All @@ -110,7 +132,8 @@ Add required permissions to the `app.json` file.
"permissions": [
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
"android.permission.MODIFY_AUDIO_SETTINGS"
"android.permission.MODIFY_AUDIO_SETTINGS",
"android.permission.ACCESS_NETWORK_STATE"
]
}
}
Expand All @@ -128,6 +151,7 @@ Add required permissions to the `AndroidManifest.xml` file.
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
...
</manifest>
```
Expand Down
Loading