Skip to content

Commit

Permalink
feat(calling): end call on member leave or conversation deleted (WPB-…
Browse files Browse the repository at this point in the history
…2955) (RC) (#1915)

* feat(calling): end call on member leave or conversation deleted

* chore: detekt

* chore: kalium reference
  • Loading branch information
ohassine authored Jul 7, 2023
1 parent 98ed1e2 commit ea5876b
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.feature.user.webSocketStatus.ObservePersistentWebSocketConnectionStatusUseCase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
Expand All @@ -35,6 +36,13 @@ class GlobalObserversManager @Inject constructor(

fun observe() {
scope.launch { setUpNotifications() }
scope.launch {
coreLogic.getGlobalScope().observeValidAccounts().distinctUntilChanged().collectLatest {
if (it.isNotEmpty()) {
coreLogic.getSessionScope(it.first().first.id).calls.endCallOnConversationChange()
}
}
}
}

private suspend fun setUpNotifications() {
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import com.wire.kalium.logic.feature.asset.ScheduleNewAssetMessageUseCase
import com.wire.kalium.logic.feature.auth.AddAuthenticatedUserUseCase
import com.wire.kalium.logic.feature.auth.LogoutUseCase
import com.wire.kalium.logic.feature.auth.autoVersioningAuth.AutoVersionAuthScopeUseCase
import com.wire.kalium.logic.feature.call.usecase.EndCallOnConversationChangeUseCase
import com.wire.kalium.logic.feature.call.usecase.EndCallUseCase
import com.wire.kalium.logic.feature.call.usecase.FlipToBackCameraUseCase
import com.wire.kalium.logic.feature.call.usecase.FlipToFrontCameraUseCase
Expand Down Expand Up @@ -624,6 +625,14 @@ class UseCaseModule {
fun provideEndCallUseCase(@KaliumCoreLogic coreLogic: CoreLogic, @CurrentAccount currentAccount: UserId): EndCallUseCase =
coreLogic.getSessionScope(currentAccount).calls.endCall

@ViewModelScoped
@Provides
fun provideEndCallOnConversationChangeUseCase(
@KaliumCoreLogic coreLogic: CoreLogic,
@CurrentAccount currentAccount: UserId
): EndCallOnConversationChangeUseCase =
coreLogic.getSessionScope(currentAccount).calls.endCallOnConversationChange

@ViewModelScoped
@Provides
fun provideMuteCallUseCase(@KaliumCoreLogic coreLogic: CoreLogic, @CurrentAccount currentAccount: UserId): MuteCallUseCase =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.wire.android.navigation.NavigationItem
import com.wire.android.navigation.NavigationManager
import com.wire.android.navigation.SavedStateViewModel
import com.wire.kalium.logic.data.conversation.Conversation
import com.wire.kalium.logic.data.conversation.ConversationDetails
import com.wire.kalium.logic.data.id.QualifiedID
import com.wire.kalium.logic.data.id.QualifiedIdMapper
import com.wire.kalium.logic.data.sync.SyncState
Expand All @@ -40,9 +41,12 @@ import com.wire.kalium.logic.feature.call.usecase.EndCallUseCase
import com.wire.kalium.logic.feature.call.usecase.IsEligibleToStartCallUseCase
import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase
import com.wire.kalium.logic.feature.call.usecase.ObserveOngoingCallsUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseCase
import com.wire.kalium.logic.sync.ObserveSyncStateUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
Expand All @@ -59,7 +63,8 @@ class ConversationCallViewModel @Inject constructor(
private val answerCall: AnswerCallUseCase,
private val endCall: EndCallUseCase,
private val observeSyncState: ObserveSyncStateUseCase,
private val isConferenceCallingEnabled: IsEligibleToStartCallUseCase
private val isConferenceCallingEnabled: IsEligibleToStartCallUseCase,
private val observeConversationDetails: ObserveConversationDetailsUseCase
) : SavedStateViewModel(savedStateHandle) {

val conversationId: QualifiedID = qualifiedIdMapper.fromStringToQualifiedID(
Expand All @@ -75,12 +80,21 @@ class ConversationCallViewModel @Inject constructor(
}

private fun listenOngoingCall() = viewModelScope.launch {
observeOngoingCalls()
.collect {
val hasOngoingCall = it.any { call -> call.conversationId == conversationId }

conversationCallViewState = conversationCallViewState.copy(hasOngoingCall = hasOngoingCall)
combine(observeOngoingCalls(), observeConversationDetails(conversationId)) { calls, conversationDetailsResult ->
val hasOngoingCall = calls.any { call -> call.conversationId == conversationId }
// valid conversation is a conversation where the user is a member and it's not deleted
val validConversation = when (conversationDetailsResult) {
is ObserveConversationDetailsUseCase.Result.Success -> {
!(conversationDetailsResult.conversationDetails is ConversationDetails.Group &&
!(conversationDetailsResult.conversationDetails as ConversationDetails.Group).isSelfUserMember)
}

is ObserveConversationDetailsUseCase.Result.Failure -> false
}
hasOngoingCall && validConversation
}.collectLatest {
conversationCallViewState = conversationCallViewState.copy(hasOngoingCall = it)
}
}

private fun observeEstablishedCall() = viewModelScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ private fun ConversationDetails.toConversationItem(
conversation.mutedStatus,
unreadEventCount
),
hasOnGoingCall = hasOngoingCall,
hasOnGoingCall = hasOngoingCall && this.isSelfUserMember,
isSelfUserCreator = isSelfUserCreator,
isSelfUserMember = isSelfUserMember,
teamId = conversation.teamId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.wire.kalium.logic.feature.call.usecase.EndCallUseCase
import com.wire.kalium.logic.feature.call.usecase.IsEligibleToStartCallUseCase
import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase
import com.wire.kalium.logic.feature.call.usecase.ObserveOngoingCallsUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseCase
import com.wire.kalium.logic.sync.ObserveSyncStateUseCase
import io.mockk.MockKAnnotations
import io.mockk.coEvery
Expand Down Expand Up @@ -69,6 +70,9 @@ class ConversationCallViewModelTest {
@MockK
private lateinit var qualifiedIdMapper: QualifiedIdMapper

@MockK
private lateinit var observeConversationDetails: ObserveConversationDetailsUseCase

private lateinit var conversationCallViewModel: ConversationCallViewModel

@BeforeEach
Expand All @@ -90,7 +94,8 @@ class ConversationCallViewModelTest {
answerCall = joinCall,
endCall = endCall,
observeSyncState = observeSyncState,
isConferenceCallingEnabled = isConferenceCallingEnabled
isConferenceCallingEnabled = isConferenceCallingEnabled,
observeConversationDetails = observeConversationDetails
)
}

Expand Down
2 changes: 1 addition & 1 deletion kalium
Submodule kalium updated 32 files
+1 βˆ’2 logic/src/commonMain/kotlin/com/wire/kalium/logic/CoreLogic.kt
+23 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/auth/login/DomainLookupResult.kt
+11 βˆ’1 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/auth/login/SSOLoginRepository.kt
+8 βˆ’3 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt
+1 βˆ’1 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/appVersioning/ObserveIfAppUpdateRequiredUseCase.kt
+18 βˆ’9 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/AuthenticationScope.kt
+52 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/DomainLookupUseCase.kt
+1 βˆ’0 .../src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/autoVersioningAuth/AutoVersionAuthScopeUseCase.kt
+52 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/sso/FetchSSOSettingsUseCase.kt
+1 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/sso/SSOLoginScope.kt
+17 βˆ’7 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt
+53 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCase.kt
+2 βˆ’1 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt
+3 βˆ’1 logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/ConversationEventReceiver.kt
+3 βˆ’2 ...src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandler.kt
+28 βˆ’13 logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandler.kt
+35 βˆ’1 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/auth/login/SSOLoginRepositoryTest.kt
+142 βˆ’0 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/auth/DomainLookupUseCaseTest.kt
+112 βˆ’0 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/auth/sso/FetchSSOSettingsUseCaseTest.kt
+191 βˆ’0 .../src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt
+175 βˆ’3 ...rc/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandlerTest.kt
+32 βˆ’0 network/src/commonMain/kotlin/com/wire/kalium/network/api/base/unauthenticated/DomainLookupApi.kt
+1 βˆ’1 network/src/commonMain/kotlin/com/wire/kalium/network/api/base/unauthenticated/SSOSettingsResponse.kt
+40 βˆ’0 network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/unauthenticated/DomainLookupApiV0.kt
+4 βˆ’1 ...kotlin/com/wire/kalium/network/api/v0/unauthenticated/networkContainer/UnauthenticatedNetworkContainerV0.kt
+25 βˆ’0 network/src/commonMain/kotlin/com/wire/kalium/network/api/v2/unauthenticated/DomainLookupApiV2.kt
+4 βˆ’1 ...kotlin/com/wire/kalium/network/api/v2/unauthenticated/networkContainer/UnauthenticatedNetworkContainerV2.kt
+25 βˆ’0 network/src/commonMain/kotlin/com/wire/kalium/network/api/v3/unauthenticated/DomainLookupApiV3.kt
+4 βˆ’1 ...kotlin/com/wire/kalium/network/api/v3/unauthenticated/networkContainer/UnauthenticatedNetworkContainerV3.kt
+25 βˆ’0 network/src/commonMain/kotlin/com/wire/kalium/network/api/v4/unauthenticated/DomainLookupApiV4.kt
+4 βˆ’1 ...kotlin/com/wire/kalium/network/api/v4/unauthenticated/networkContainer/UnauthenticatedNetworkContainerV4.kt
+2 βˆ’0 network/src/commonMain/kotlin/com/wire/kalium/network/networkContainer/UnauthenticatedNetworkContainer.kt

0 comments on commit ea5876b

Please sign in to comment.