@@ -23,6 +23,7 @@ import androidx.compose.runtime.mutableStateOf
2323import androidx.compose.runtime.setValue
2424import androidx.lifecycle.SavedStateHandle
2525import androidx.lifecycle.viewModelScope
26+ import androidx.work.WorkManager
2627import com.wire.android.R
2728import com.wire.android.appLogger
2829import com.wire.android.ui.common.bottomsheet.conversation.ConversationSheetContent
@@ -33,11 +34,14 @@ import com.wire.android.ui.home.conversations.details.participants.GroupConversa
3334import com.wire.android.ui.home.conversations.details.participants.usecase.ObserveParticipantsForConversationUseCase
3435import com.wire.android.ui.home.conversationslist.model.DialogState
3536import com.wire.android.ui.home.conversationslist.model.GroupDialogState
37+ import com.wire.android.ui.home.conversationslist.model.LeaveGroupDialogState
3638import com.wire.android.ui.home.conversationslist.showLegalHoldIndicator
3739import com.wire.android.ui.navArgs
3840import com.wire.android.util.dispatchers.DispatcherProvider
3941import com.wire.android.util.ui.UIText
4042import com.wire.android.util.uiText
43+ import com.wire.android.workmanager.worker.ConversationDeletionLocallyStatus
44+ import com.wire.android.workmanager.worker.enqueueConversationDeletionLocally
4145import com.wire.kalium.logic.CoreFailure
4246import com.wire.kalium.logic.data.conversation.Conversation
4347import com.wire.kalium.logic.data.conversation.ConversationDetails
@@ -62,7 +66,7 @@ import com.wire.kalium.logic.feature.team.DeleteTeamConversationUseCase
6266import com.wire.kalium.logic.feature.team.GetUpdatedSelfTeamUseCase
6367import com.wire.kalium.logic.feature.team.Result
6468import com.wire.kalium.logic.feature.user.GetDefaultProtocolUseCase
65- import com.wire.kalium.logic.feature.user.ObserveSelfUserUseCase
69+ import com.wire.kalium.logic.feature.user.GetSelfUserUseCase
6670import com.wire.kalium.logic.feature.user.IsMLSEnabledUseCase
6771import com.wire.kalium.logic.functional.getOrNull
6872import dagger.hilt.android.lifecycle.HiltViewModel
@@ -73,8 +77,6 @@ import kotlinx.coroutines.flow.StateFlow
7377import kotlinx.coroutines.flow.combine
7478import kotlinx.coroutines.flow.distinctUntilChanged
7579import kotlinx.coroutines.flow.filterIsInstance
76- import kotlinx.coroutines.flow.first
77- import kotlinx.coroutines.flow.firstOrNull
7880import kotlinx.coroutines.flow.flowOn
7981import kotlinx.coroutines.flow.map
8082import kotlinx.coroutines.flow.shareIn
@@ -91,7 +93,7 @@ class GroupConversationDetailsViewModel @Inject constructor(
9193 private val observeConversationMembers : ObserveParticipantsForConversationUseCase ,
9294 private val updateConversationAccessRole : UpdateConversationAccessRoleUseCase ,
9395 private val getSelfTeam : GetUpdatedSelfTeamUseCase ,
94- private val observerSelfUser : ObserveSelfUserUseCase ,
96+ private val getSelfUser : GetSelfUserUseCase ,
9597 private val deleteTeamConversation : DeleteTeamConversationUseCase ,
9698 private val removeMemberFromConversation : RemoveMemberFromConversationUseCase ,
9799 private val updateConversationMutedStatus : UpdateConversationMutedStatusUseCase ,
@@ -102,6 +104,7 @@ class GroupConversationDetailsViewModel @Inject constructor(
102104 override val savedStateHandle : SavedStateHandle ,
103105 private val isMLSEnabled : IsMLSEnabledUseCase ,
104106 private val getDefaultProtocol : GetDefaultProtocolUseCase ,
107+ private val workManager : WorkManager ,
105108 refreshUsersWithoutMetadata : RefreshUsersWithoutMetadataUseCase ,
106109) : GroupConversationParticipantsViewModel(
107110 savedStateHandle, observeConversationMembers, refreshUsersWithoutMetadata
@@ -136,15 +139,15 @@ class GroupConversationDetailsViewModel @Inject constructor(
136139 .shareIn(this , SharingStarted .WhileSubscribed (), 1 )
137140
138141 val selfTeam = getSelfTeam().getOrNull()
139- val selfUser = observerSelfUser().first ()
142+ val selfUser = getSelfUser ()
140143 val isMLSTeam = getDefaultProtocol() == SupportedProtocol .MLS
141144
142145 combine(
143146 groupDetailsFlow,
144147 observeSelfDeletionTimerSettingsForConversation(conversationId, considerSelfUserSettings = false ),
145148 ) { groupDetails, selfDeletionTimer ->
146149 val isSelfInOwnerTeam = selfTeam?.id != null && selfTeam.id == groupDetails.conversation.teamId?.value
147- val isSelfExternalMember = selfUser.userType == UserType .EXTERNAL
150+ val isSelfExternalMember = selfUser? .userType == UserType .EXTERNAL
148151 val isSelfAnAdmin = groupDetails.selfRole == Conversation .Member .Role .Admin
149152 val isMLSConversation = groupDetails.conversation.protocol is Conversation .ProtocolInfo .MLS
150153
@@ -154,7 +157,7 @@ class GroupConversationDetailsViewModel @Inject constructor(
154157 mutingConversationState = groupDetails.conversation.mutedStatus,
155158 conversationTypeDetail = ConversationTypeDetail .Group (
156159 conversationId = conversationId,
157- isFromTheSameTeam = groupDetails.conversation.teamId == observerSelfUser().firstOrNull ()?.teamId
160+ isFromTheSameTeam = groupDetails.conversation.teamId == getSelfUser ()?.teamId
158161 ),
159162 isTeamConversation = groupDetails.conversation.teamId?.value != null ,
160163 selfRole = groupDetails.selfRole,
@@ -190,21 +193,27 @@ class GroupConversationDetailsViewModel @Inject constructor(
190193 }
191194
192195 fun leaveGroup (
193- leaveGroupState : GroupDialogState ,
196+ leaveGroupState : LeaveGroupDialogState ,
194197 onSuccess : () -> Unit ,
195198 onFailure : (UIText ) -> Unit
196199 ) {
197200 viewModelScope.launch {
198201 requestInProgress = true
199202 val response = withContext(dispatcher.io()) {
200- val selfUser = observerSelfUser().first()
201- removeMemberFromConversation(
202- leaveGroupState.conversationId, selfUser.id
203- )
203+ getSelfUser()?.let { selfUser ->
204+ removeMemberFromConversation(leaveGroupState.conversationId, selfUser.id)
205+ }
204206 }
205207 when (response) {
206208 is RemoveMemberFromConversationUseCase .Result .Failure -> onFailure(response.cause.uiText())
207- RemoveMemberFromConversationUseCase .Result .Success -> onSuccess()
209+ RemoveMemberFromConversationUseCase .Result .Success -> {
210+ if (leaveGroupState.shouldDelete) {
211+ deleteGroupLocally(leaveGroupState, onSuccess, onFailure)
212+ } else {
213+ onSuccess()
214+ }
215+ }
216+ null -> {}
208217 }
209218 requestInProgress = false
210219 }
@@ -226,6 +235,29 @@ class GroupConversationDetailsViewModel @Inject constructor(
226235 }
227236 }
228237
238+ fun deleteGroupLocally (
239+ groupDialogState : GroupDialogState ,
240+ onSuccess : () -> Unit ,
241+ onFailure : (UIText ) -> Unit
242+ ) {
243+ viewModelScope.launch {
244+ workManager.enqueueConversationDeletionLocally(groupDialogState.conversationId)
245+ .collect { status ->
246+ when (status) {
247+ ConversationDeletionLocallyStatus .SUCCEEDED -> onSuccess()
248+
249+ ConversationDeletionLocallyStatus .FAILED ->
250+ onFailure(UIText .StringResource (R .string.delete_group_conversation_error))
251+
252+ ConversationDeletionLocallyStatus .RUNNING ,
253+ ConversationDeletionLocallyStatus .IDLE -> {
254+ // nop
255+ }
256+ }
257+ }
258+ }
259+ }
260+
229261 fun onServicesUpdate (enableServices : Boolean ) {
230262 updateState(groupOptionsState.value.copy(loadingServicesOption = true , isServicesAllowed = enableServices))
231263 when (enableServices) {
0 commit comments