How we can get Leave host event in react native video sdk

import React, {useState, useRef, useEffect} from ‘react’
import {
View,
Alert,
StyleSheet,
BackHandler,
TouchableOpacity,
ActivityIndicator,
EmitterSubscription,
Text,
} from ‘react-native’
import {
useZoom,
ZoomVideoSdkUser,
EventType,
VideoAspect,
ZoomView,
} from ‘@zoom/react-native-videosdk’
import Icon from ‘react-native-vector-icons/MaterialIcons’
import {useNavigation, useFocusEffect} from ‘@react-navigation/native’
import {useDispatch, useSelector} from ‘react-redux’
import {resetZoomSession} from ‘…/…/store/actions/homeActions’
import {navigate} from ‘…/…/navigation/navigation-helpers’
import {
selectedZoomSession,
selectHomeError,
} from ‘…/…/store/selector/homeSelectors’
import {showErrorMessage} from ‘…/…/app-base/utils’

const CustomZoomSessionHandler = ({route, onSessionJoin, onSessionLeave}) => {
const {appointment} = route.params
const dispatch = useDispatch()
const zoom = useZoom()
const listeners = useRef<EmitterSubscription>()
const [sessionEnded, setSessionEnded] = useState(false)
const [isLoading, setIsLoading] = useState(true)
const [isInSession, setIsInSession] = useState(false)
const [isAudioMuted, setIsAudioMuted] = useState(true)
const [isVideoMuted, setIsVideoMuted] = useState(true)
const [users, setUsersInSession] = useState()

const zoomSessionData = useSelector(selectedZoomSession)
const error = useSelector(selectHomeError)

const clearListeners = () => {
listeners.current.forEach((listener) => listener.remove())
listeners.current =
}

useFocusEffect(
React.useCallback(() => {
const joinZoomSession = async () => {
if (zoomSessionData && !error && !isInSession && !sessionEnded) {
try {
setIsLoading(true)
const {session, token} = zoomSessionData
await zoom.joinSession({
sessionName: session,
sessionPassword: ‘’,
token,
userName: appointment.patientName,
audioOptions: {
connect: true,
mute: true,
autoAdjustSpeakerVolume: false,
},
videoOptions: {localVideoOn: true},
sessionIdleTimeoutMins: 0,
})
} catch (joinError) {
setIsLoading(false)
dispatch(resetZoomSession())
}

      // Listener for session join
      listeners.current.push(
        zoom.addListener(EventType.onSessionJoin, async () => {
          const localUser = new ZoomVideoSdkUser(
            await zoom.session.getMySelf(),
          )
          const remoteUsers = await zoom.session.getRemoteUsers()
          setUsersInSession([
            localUser,
            ...remoteUsers.map((user) => new ZoomVideoSdkUser(user)),
          ])
          setIsInSession(true)
          setIsLoading(false) // Stop loading when session is joined
          onSessionJoin && onSessionJoin([localUser, ...remoteUsers])

          const isMuted = await localUser.audioStatus.isMuted()
          const videoOn = await localUser.videoStatus.isOn()
          setIsAudioMuted(isMuted)
          setIsVideoMuted(!videoOn)
        }),
      )

      // Listener for user join
      listeners.current.push(
        zoom.addListener(EventType.onUserJoin, async (event) => {
          const {joinedUsers, remoteUsers} = event
          const allUsers = [...joinedUsers, ...remoteUsers]
          const uniqueUsers = Array.from(
            new Map(
              allUsers.map((user) => [
                user.userId,
                new ZoomVideoSdkUser(user),
              ]),
            ).values(),
          )
          setUsersInSession(uniqueUsers)

          if (!isInSession) {
            setIsInSession(true)
            setIsLoading(false)
            onSessionJoin && onSessionJoin(uniqueUsers)
          }
        }),
      )

      // Listener for session leave
      listeners.current.push(
        zoom.addListener(EventType.onSessionLeave, () => {
          leaveSession(false)
        }),
      )
    }
  }

  // Join session if session data and no error
  if (zoomSessionData && !error && !isInSession) {
    joinZoomSession()
  } else if (error) {
    showErrorMessage(error ?? '')
    dispatch(resetZoomSession())
    navigate('Tab', {screen: 'Home'})
  }

  if (isInSession) {
    setIsLoading(false)
  }

  const backHandler = BackHandler.addEventListener(
    'hardwareBackPress',
    handleBackPress,
  )

  return () => {
    backHandler.remove()
    clearListeners() // Ensure listeners are cleared when unmounting
  }
}, [zoomSessionData, error, sessionEnded, isInSession, zoom]),

)

const handleBackPress = () => {
Alert.alert(
‘Leave Session’,
‘Are you sure you want to leave the session?’,
[
{text: ‘Cancel’, style: ‘cancel’},
{text: ‘Yes’, onPress: () => leaveSession()},
],
{cancelable: true},
)
return true
}

const leaveSession = async (notifyLeave = true) => {
if (!isInSession) return

try {
  await zoom.leaveSession(false)
  clearListeners()
  setIsInSession(false)
  setUsersInSession([])
  setSessionEnded(true)

  if (notifyLeave) {
    onSessionLeave && onSessionLeave()
  }

  dispatch(resetZoomSession())
  navigate('Tab', {screen: 'Home'})
} catch (error) {
  console.error('Error leaving session:', error)
}

}

const toggleAudio = async () => {
const mySelf = await zoom.session.getMySelf()
const muted = await mySelf.audioStatus.isMuted()
if (muted) {
await zoom.audioHelper.unmuteAudio(mySelf.userId)
setIsAudioMuted(false)
} else {
await zoom.audioHelper.muteAudio(mySelf.userId)
setIsAudioMuted(true)
}
}

const toggleVideo = async () => {
const mySelf = await zoom.session.getMySelf()
const videoOn = await mySelf.videoStatus.isOn()
if (videoOn) {
await zoom.videoHelper.stopVideo()
setIsVideoMuted(true)
} else {
await zoom.videoHelper.startVideo()
setIsVideoMuted(false)
}
}

return (

{isLoading ? (



) : isInSession ? (

{/* Render co-host (Full screen) */}
{users
.filter((user) => user.isHost)
.map((user) => (


{user.userName}



))}

      {/* Render host (Small bottom-right corner) */}
      {users
        .filter((user) => !user.isHost)
        .map((user) => (
          <View key={user.userId} style={styles.hostContainer}>
            <View style={styles.userNameContainer}>
              <Text style={styles.userNameText}>{user.userName}</Text>
            </View>
            <ZoomView
              style={styles.hostView}
              userId={user.userId}
              videoAspect={VideoAspect.PanAndScan}
            />
          </View>
        ))}

      {/* Control icons */}
      <ControlIcons
        isAudioMuted={isAudioMuted}
        isVideoMuted={isVideoMuted}
        onToggleAudio={toggleAudio}
        onToggleVideo={toggleVideo}
        onLeaveSession={leaveSession}
      />
    </View>
  ) : null}
</View>

)
}

const ControlIcons = ({
isAudioMuted,
isVideoMuted,
onToggleAudio,
onToggleVideo,
onLeaveSession,
}) => {
const handleLeaveSession = () => {
Alert.alert(
‘Leave Session’,
‘Are you certain you want to end the call? If so, the teleconsultation between you and the doctor will be terminated immediately and may not be able to be recalled.’,
[
{text: ‘Cancel’, style: ‘cancel’},
{text: ‘Confirm’, onPress: () => onLeaveSession()},
],
{cancelable: true},
)
}

return (


<Icon name={isAudioMuted ? ‘mic-off’ : ‘mic’} size={30} color=“#fff” />


<Icon
name={isVideoMuted ? ‘videocam-off’ : ‘videocam’}
size={30}
color=“#fff
/>





)
}

export default CustomZoomSessionHandler

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
backgroundColor: ‘#000’,
},
loadingContainer: {
…StyleSheet.absoluteFillObject,
alignItems: ‘center’,
justifyContent: ‘center’,
backgroundColor: ‘#000’,
},
hostContainer: {
position: ‘absolute’,
width: ‘30%’, // Adjust the width of the host view
height: ‘30%’, // Adjust the height of the host view
bottom: 20, // Add some spacing from the bottom
right: 20, // Add some spacing from the right
borderRadius: 10,
overflow: ‘hidden’,
backgroundColor: ‘rgba(0, 0, 0, 0.5)’,
},
coHostContainer: {
flex: 1, // Co-host view takes the entire screen
backgroundColor: ‘#000’,
},
hostView: {
flex: 1, // Host view content scales within the allocated container
},
coHostView: {
width: ‘100%’,
height: ‘100%’, // Co-host view covers the entire screen
},
userNameContainer: {
position: ‘absolute’,
top: 0, // Position the name at the top of the view
width: ‘100%’,
padding: 5,
backgroundColor: ‘rgba(0, 0, 0, 0.7)’,
alignItems: ‘center’,
zIndex: 1, // Ensure it appears above the video feed
},
userNameText: {
color: ‘#fff’,
fontSize: 14,
fontWeight: ‘bold’,
},
iconContainer: {
flexDirection: ‘row’,
justifyContent: ‘space-evenly’,
position: ‘absolute’,
bottom: 20,
width: ‘100%’,
backgroundColor: ‘rgba(0, 0, 0, 0.6)’,
paddingVertical: 10,
},
})
use this code and help me where i use wrong code. @ekaansh.zoom

Hi @shreenivas.kokil the forum isn’t the best place to get help debugging your code implementation. We’re happy to help you with general questions. If you need dedicated support, please consider signing up for Premier Developer Support.