It is a video call screen . It needs token and channel name to work which needs to be passed to init call engine. I am storing these in a data class which is used as a mutable state.
Screen State Data class
@Keep data class CallScreenState( val callerId: Int? = null, val recieverId: Int? = null, val chatRoom: ChatRoom.Data? = null, val rtcToken: AgoraTokenResponse.TokenData? = null ) And in viewmodel initializing state by this code :
var callScreenState by mutableStateOf(CallScreenState()) and in viewmodel on success response of chat room and token api the state is updated with this code.
callScreenState = callScreenState.copy( chatRoom = chatRoom.data,//from response rtcToken = token.data //from response ) From here it is expected to recompose the screen with new updated value of chatRoom and rtcToken.
And in composable
val screenState = remember { viewModel.callScreenState } this screen state is used to pass values to the init engine
val mEngine = remember { initEngine( context, object : IRtcEngineEventHandler() { override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) { Timber.e("hhp-CallScreen onJoinChannelSuccess channel:$channel,uid:$uid,elapsed:$elapsed") } override fun onUserJoined(uid: Int, elapsed: Int) { Timber.e("hhp-CallScreen onUserJoined:$uid") val desiredUserList = remoteUserMap.toMutableMap() desiredUserList[uid] = null remoteUserMap = desiredUserList.toMap() as HashMap<Int, TextureView?> } override fun onUserOffline(uid: Int, reason: Int) { Timber.e("hhp-CallScreen onUserOffline:$uid") val desiredUserList = remoteUserMap.toMutableMap() desiredUserList.remove(uid) remoteUserMap = desiredUserList.toMap() as HashMap<Int, TextureView?> } override fun onNetworkQuality(uid: Int, txQuality: Int, rxQuality: Int) { Timber.e("hhp-CallScreen onNetworkQuality $uid $txQuality $rxQuality") } }, screenState.chatRoom?.channelName ?: "", //Not recomposing when value changes in viewmodel viewModel.userRole, token = screenState.rtcToken?.token ?: "" //Not recomposing when value changes in viewmodel ) } This is the initEngine function creation
fun initEngine( current: Context, eventHandler: IRtcEngineEventHandler, channelName: String, userRole: String, token: String ): RtcEngine = RtcEngine.create(current, BuildConfig.AGORA_APPID, eventHandler).apply { enableVideo() setChannelProfile(1) if (userRole == "Broadcaster") { setClientRole(1) } else { setClientRole(0) } //Expected to be recomposed when screen state value updated with new values joinChannel(token, channelName, "", 0) } I understand at the very beginging, channel name and token inside the screen state is empty that is before the api call . Once api for getting token and chat room gives succes , the screen state updated from viewmodel and i expect the initEngine fun to be called again as it should recompose. But it is not. Am I Missing something ? How to make it recompose whenver the channelname value inside screen sctate changes?