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 bd0b1f1831d8b78a169b26fadb159d6a9798ba24..7a2a90a277ec57fb32999218c9d67a2453831ae2 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 882340381ff3c82e886376dd36c745cd95e8c3be..3e43ea8df1b5352f394cf619e5bdbcc15f18bb83 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 555d5483fd8b0ad9ae7b2a2aa426be6c349c1325..079abecffe94073f409b059b411af5645d3322a3 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 e63080807e3b14bf47626653d21d3cf1a20d0e97..a7463cf0b5b0b392415499d5f43142e29ee91c9e 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 18adfc80e412a1f098233b3af8ead7590278755e..d0b08721cf66730fa665ca01cc83ec880a78b2e8 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