@@ -22,7 +22,7 @@ For a deeper understanding of how data channels work, including channel types an
2222
2323## Step 1 — Set up the chat hook
2424
25- Use the [ ` useDataChannel ` ] ( /api/web/functions/useDataChannel ) hook to work with data channels. The typical flow is:
25+ 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:
2626
27271 . Initialize the data channel after connecting to a room
28282 . Subscribe to incoming messages
@@ -84,9 +84,67 @@ export function useChat() {
8484```
8585
8686 </TabItem >
87- <TabItem value = " mobile" label = " React Native (Mobile)" disabled >
87+ <TabItem value = " mobile" label = " React Native (Mobile)" >
8888
89- Mobile SDK support for data channels will be available in a future release.
89+ ``` tsx
90+ import {
91+ useConnection ,
92+ useDataChannel ,
93+ } from " @fishjam-cloud/react-native-client" ;
94+ import { useCallback , useEffect , useState } from " react" ;
95+
96+ export function useChat() {
97+ const { peerStatus } = useConnection ();
98+ const {
99+ initializeDataChannel,
100+ publishData,
101+ subscribeData,
102+ dataChannelReady,
103+ dataChannelLoading,
104+ dataChannelError,
105+ } = useDataChannel ();
106+
107+ const [messages, setMessages] = useState <string []>([]);
108+
109+ useEffect (() => {
110+ if (peerStatus === " connected" ) {
111+ initializeDataChannel ();
112+ }
113+ }, [peerStatus , initializeDataChannel ]);
114+
115+ useEffect (() => {
116+ if (dataChannelLoading || ! dataChannelReady ) return ;
117+
118+ const unsubscribe = subscribeData (
119+ (data : Uint8Array ) => {
120+ const message = new TextDecoder ().decode (data );
121+ setMessages ((prev ) => [... prev , message ]);
122+ },
123+ { reliable: true },
124+ );
125+
126+ return unsubscribe ;
127+ }, [dataChannelReady , dataChannelLoading , subscribeData ]);
128+
129+ const sendMessage = useCallback (
130+ (text : string ) => {
131+ if (! dataChannelReady ) return ;
132+
133+ const encoded = new TextEncoder ().encode (text );
134+ publishData (encoded , { reliable: true });
135+ },
136+ [publishData , dataChannelReady ],
137+ );
138+
139+ return {
140+ messages ,
141+ sendMessage ,
142+ ready: dataChannelReady ,
143+ loading: dataChannelLoading ,
144+ error: dataChannelError ,
145+ };
146+ }
147+ ```
90148
91149 </TabItem >
92150</Tabs >
@@ -185,9 +243,97 @@ function ChatPanel() {
185243```
186244
187245 </TabItem >
188- <TabItem value = " mobile" label = " React Native (Mobile)" disabled >
246+ <TabItem value = " mobile" label = " React Native (Mobile)" >
247+
248+ ``` tsx
249+ import React , { useState , useEffect , useCallback } from " react" ;
250+ import { View , Text , TextInput , FlatList , Pressable } from " react-native" ;
251+ import {
252+ useConnection ,
253+ useDataChannel ,
254+ } from " @fishjam-cloud/react-native-client" ;
255+
256+ function useChat() {
257+ const { peerStatus } = useConnection ();
258+ const {
259+ initializeDataChannel,
260+ publishData,
261+ subscribeData,
262+ dataChannelReady,
263+ } = useDataChannel ();
264+
265+ const [messages, setMessages] = useState <string []>([]);
266+
267+ useEffect (() => {
268+ if (peerStatus === " connected" ) {
269+ initializeDataChannel ();
270+ }
271+ }, [peerStatus , initializeDataChannel ]);
189272
190- Mobile SDK support for data channels will be available in a future release.
273+ useEffect (() => {
274+ if (! dataChannelReady ) return ;
275+
276+ const unsubscribe = subscribeData (
277+ (data : Uint8Array ) => {
278+ const message = new TextDecoder ().decode (data );
279+ setMessages ((prev ) => [... prev , message ]);
280+ },
281+ { reliable: true },
282+ );
283+
284+ return unsubscribe ;
285+ }, [subscribeData , dataChannelReady ]);
286+
287+ const sendMessage = useCallback (
288+ (text : string ) => {
289+ if (! dataChannelReady ) return ;
290+
291+ const encoded = new TextEncoder ().encode (text );
292+ publishData (encoded , { reliable: true });
293+ },
294+ [publishData , dataChannelReady ],
295+ );
296+
297+ return { messages , sendMessage , ready: dataChannelReady };
298+ }
299+
300+ // ---cut---
301+
302+ function ChatPanel() {
303+ const { messages, sendMessage, ready } = useChat ();
304+ const [input, setInput] = useState (" " );
305+
306+ const handleSend = () => {
307+ if (input .trim ()) {
308+ sendMessage (input );
309+ setInput (" " );
310+ }
311+ };
312+
313+ if (! ready ) {
314+ return <Text >Connecting to chat...</Text >;
315+ }
316+
317+ return (
318+ <View >
319+ <FlatList
320+ data = { messages }
321+ keyExtractor = { (_ , i ) => String (i )}
322+ renderItem = { ({ item }) => <Text >{ item } </Text >}
323+ />
324+ <TextInput
325+ value = { input }
326+ onChangeText = { setInput }
327+ placeholder = " Type a message..."
328+ onSubmitEditing = { handleSend }
329+ />
330+ <Pressable onPress = { handleSend } >
331+ <Text >Send</Text >
332+ </Pressable >
333+ </View >
334+ );
335+ }
336+ ```
191337
192338 </TabItem >
193339</Tabs >
@@ -209,4 +355,5 @@ This ensures no chat messages are lost or arrive out of order.
209355
210356- [ Data Channels] ( ../../explanation/data-channels ) — detailed explanation of channel types and broadcast behavior
211357- [ Connecting to a room] ( ../../how-to/client/connecting ) — prerequisite for using data channels
212- - [ ` useDataChannel ` API reference] ( ../../api/web/functions/useDataChannel )
358+ - [ ` useDataChannel ` API reference (Web)] ( ../../api/web/functions/useDataChannel )
359+ - [ ` useDataChannel ` API reference (Mobile)] ( ../../api/mobile/functions/useDataChannel )
0 commit comments