From 663d4ff4804c24d70f5d24c0a57f1cb3b4663a0c Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Fri, 8 Mar 2024 12:49:38 +0200 Subject: [PATCH] Add loading for removing session --- .../feature/people/PeopleDataSource.kt | 5 +-- .../ActiveSessionsViewModel.kt | 37 ++++++++++++++++++- .../auth/model/ActiveSessionListItem.kt | 3 +- .../auth/view/ActiveSessionInfoView.kt | 10 +++-- .../res/layout/view_active_session_info.xml | 10 +++++ 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt b/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt index bd0b1f183..7a2a90a27 100644 --- a/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt +++ b/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt @@ -6,7 +6,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.withContext import org.futo.circles.core.feature.room.knoks.KnockRequestsDataSource import org.futo.circles.core.feature.select_users.SearchUserDataSource @@ -28,9 +27,7 @@ class PeopleDataSource @Inject constructor( private fun getKnockRequestCountFlow(): Flow<Int> = knockRequestsDataSource.getKnockRequestsListItemsLiveData(peopleCategoryDataSource.getProfileRoomId()) - ?.map { - it.size - }?.asFlow() ?: flowOf() + .map { it.size }.asFlow() private fun getProfileSpaceInvitesCountFlow() = getSpacesLiveData(listOf(Membership.INVITE)).map { it.size }.asFlow() diff --git a/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt b/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt index 882340381..3e43ea8df 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/active_sessions/ActiveSessionsViewModel.kt @@ -1,8 +1,13 @@ package org.futo.circles.auth.feature.active_sessions +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData import dagger.hilt.android.lifecycle.HiltViewModel +import org.futo.circles.auth.model.ActiveSession +import org.futo.circles.auth.model.ActiveSessionListItem +import org.futo.circles.auth.model.SessionHeader import org.futo.circles.core.base.SingleEventLiveData import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.launchBg @@ -13,18 +18,39 @@ class ActiveSessionsViewModel @Inject constructor( private val dataSource: ActiveSessionsDataSource ) : ViewModel() { - val activeSessionsLiveData = dataSource.getActiveSessionsFlow().asLiveData() val removeSessionLiveData = SingleEventLiveData<Response<Unit?>>() val resetKeysLiveData = SingleEventLiveData<Response<Unit?>>() val startReAuthEventLiveData = dataSource.startReAuthEventLiveData + private val loadingItemsIdsList = MutableLiveData<Set<String>>(emptySet()) + + val activeSessionsLiveData = MediatorLiveData<List<ActiveSessionListItem>>().also { + it.addSource(loadingItemsIdsList) { loadingItemsValue -> + val currentList = it.value ?: emptyList() + it.postValue( + currentList.map { item -> + when (item) { + is ActiveSession -> item.copy(isLoading = loadingItemsValue.contains(item.id)) + is SessionHeader -> item + } + } + ) + } + it.addSource(dataSource.getActiveSessionsFlow().asLiveData()) { value -> + it.postValue(value) + } + } + + fun onSessionClicked(deviceId: String) { dataSource.toggleOptionsVisibilityFor(deviceId) } fun removeSession(deviceId: String) { launchBg { + toggleItemLoading(deviceId) val deactivateResult = dataSource.removeSession(deviceId) + toggleItemLoading(deviceId) removeSessionLiveData.postValue(deactivateResult) } } @@ -35,4 +61,13 @@ class ActiveSessionsViewModel @Inject constructor( resetKeysLiveData.postValue(resetKeysResult) } } + + private fun toggleItemLoading(id: String) { + val currentSet = loadingItemsIdsList.value?.toMutableSet() ?: return + val newLoadingSet = currentSet.apply { + if (this.contains(id)) remove(id) + else add(id) + } + loadingItemsIdsList.postValue(newLoadingSet) + } } \ No newline at end of file diff --git a/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt b/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt index 555d5483f..079abecff 100644 --- a/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt +++ b/auth/src/main/java/org/futo/circles/auth/model/ActiveSessionListItem.kt @@ -18,7 +18,8 @@ data class ActiveSession( val cryptoDeviceInfo: CryptoDeviceInfo, val canVerify: Boolean, val isResetKeysVisible: Boolean, - val isOptionsVisible: Boolean + val isOptionsVisible: Boolean, + val isLoading: Boolean = false ) : ActiveSessionListItem() { override val id: String = cryptoDeviceInfo.deviceId diff --git a/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt b/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt index e63080807..a7463cf0b 100644 --- a/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt +++ b/auth/src/main/java/org/futo/circles/auth/view/ActiveSessionInfoView.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import androidx.constraintlayout.widget.ConstraintLayout import org.futo.circles.auth.databinding.ViewActiveSessionInfoBinding import org.futo.circles.auth.feature.active_sessions.list.ActiveSessionClickListener +import org.futo.circles.auth.model.ActiveSession import org.futo.circles.core.extensions.setIsVisible class ActiveSessionInfoView( @@ -32,17 +33,18 @@ class ActiveSessionInfoView( } fun setData( - activeSession: org.futo.circles.auth.model.ActiveSession, + activeSession: ActiveSession, listener: ActiveSessionClickListener ) { deviceId = activeSession.id activeSessionClickListener = listener with(binding) { + vLoading.setIsVisible(activeSession.isLoading) tvFingerprint.text = activeSession.cryptoDeviceInfo.fingerprint() ?: "" tvPublicKey.text = activeSession.cryptoDeviceInfo.identityKey() ?: "" - btnVerify.setIsVisible(activeSession.canVerify) - btnRemove.setIsVisible(!activeSession.isCurrentSession()) - btnResetKeys.setIsVisible(activeSession.isResetKeysVisible) + btnVerify.setIsVisible(activeSession.canVerify && !activeSession.isLoading) + btnRemove.setIsVisible(!activeSession.isCurrentSession() && !activeSession.isLoading) + btnResetKeys.setIsVisible(activeSession.isResetKeysVisible && !activeSession.isLoading) } } } \ No newline at end of file diff --git a/auth/src/main/res/layout/view_active_session_info.xml b/auth/src/main/res/layout/view_active_session_info.xml index 18adfc80e..d0b08721c 100644 --- a/auth/src/main/res/layout/view_active_session_info.xml +++ b/auth/src/main/res/layout/view_active_session_info.xml @@ -97,4 +97,14 @@ app:layout_constraintStart_toEndOf="@id/btnRemove" app:layout_constraintTop_toBottomOf="@+id/tvPublicKey" /> + <ProgressBar + android:id="@+id/vLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvPublicKey" /> + </merge> \ No newline at end of file -- GitLab