Skip to content
Open
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
28 changes: 24 additions & 4 deletions examples/mobile-client/fishjam-chat/app/room/[roomName].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '@fishjam-cloud/react-native-client';
import { router, useLocalSearchParams } from 'expo-router';
import React, { useCallback, useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import { Platform, StyleSheet, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import { InCallButton, VideosGrid } from '../../components';
Expand All @@ -28,9 +28,20 @@ export default function RoomScreen() {
startStreaming,
stopStreaming,
stream: screenShareStream,
presentBroadcastPicker,
} = useScreenShare();

const handleDisconnect = useCallback(async () => {
if (screenShareStream && Platform.OS === 'ios') {
// iOS: must end the broadcast via the system sheet first to avoid
// the "Screen sharing stopped" error dialog. Tap leave again after.
try {
await presentBroadcastPicker();
return;
} catch (e) {
Comment thread
MiloszFilimowski marked this conversation as resolved.
console.error('Error presenting broadcast picker:', e);
}
}
try {
if (screenShareStream) {
await stopStreaming();
Expand All @@ -40,19 +51,28 @@ export default function RoomScreen() {
console.error('Error leaving room:', e);
}
router.replace('/(tabs)/room');
}, [leaveRoom, screenShareStream, stopStreaming]);
}, [leaveRoom, presentBroadcastPicker, screenShareStream, stopStreaming]);

const handleToggleScreenShare = useCallback(async () => {
try {
if (screenShareStream) {
await stopStreaming();
if (Platform.OS === 'ios') {
await presentBroadcastPicker();
} else {
await stopStreaming();
}
Comment thread
MiloszFilimowski marked this conversation as resolved.
} else {
await startStreaming();
}
} catch (e) {
console.error('Error toggling screen share:', e);
}
}, [screenShareStream, startStreaming, stopStreaming]);
}, [
presentBroadcastPicker,
screenShareStream,
startStreaming,
stopStreaming,
]);

useForegroundService({
channelName: 'Fishjam Chat Notifications',
Expand Down
2 changes: 2 additions & 0 deletions packages/mobile-client/src/overrides/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '@fishjam-cloud/react-client';
import type { CallKitAction, CallKitConfig, MediaStream as RNMediaStream } from '@fishjam-cloud/react-native-webrtc';
import {
presentBroadcastPicker,
useCallKit as useCallKitRNWebRTC,
useCallKitEvent as useCallKitEventRNWebRTC,
useCallKitService as useCallKitServiceRNWebRTC,
Expand Down Expand Up @@ -78,6 +79,7 @@ export function useScreenShare(): UseScreenShareResult {
audioTrack: result.audioTrack as UseScreenShareResult['audioTrack'],
currentTracksMiddleware: result.currentTracksMiddleware as TracksMiddleware | null,
setTracksMiddleware,
presentBroadcastPicker,
};
}

Expand Down
8 changes: 8 additions & 0 deletions packages/mobile-client/src/overrides/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ export type UseScreenShareResult = Omit<
audioTrack: RNMediaStreamTrack | null;
currentTracksMiddleware: TracksMiddleware | null;
setTracksMiddleware: (middleware: TracksMiddleware | null) => Promise<void>;
/**
* iOS only. Presents the system `RPSystemBroadcastPickerView`. When a
* broadcast is active, this opens the system "Stop Broadcast" sheet so
* the user can end it cleanly (via `broadcastFinished()`) and avoid the
* "Screen sharing stopped" error dialog that `stopStreaming` triggers
* by force-closing the host-side socket. No-op on non-iOS.
*/
presentBroadcastPicker: () => Promise<void>;
};

export type UseCustomSourceResult = Omit<ReturnType<typeof useCustomSourceReactClient>, 'stream' | 'setStream'> & {
Expand Down
Loading