From 87dcf1840403b8dae9aed6a7e37062908dd884df Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Thu, 7 Mar 2024 18:00:34 +0200 Subject: [PATCH] Add loading for knock requests --- .../room/knoks/KnockRequestViewModel.kt | 33 +++++++++++++++++-- .../room/knoks/KnockRequestsDataSource.kt | 3 +- .../room/knoks/KnockRequestsDialogFragment.kt | 2 +- .../room/knoks/list/KnockRequestViewHolder.kt | 1 + .../core/model/KnockRequestListItem.kt | 3 +- .../res/layout/list_item_knock_request.xml | 22 +++++++++++++ 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt index fc6c48a17..d979e513c 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestViewModel.kt @@ -1,5 +1,7 @@ package org.futo.circles.core.feature.room.knoks +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel @@ -20,18 +22,45 @@ class KnockRequestViewModel @Inject constructor( private val roomId: String = savedStateHandle.getOrThrow("roomId") - val knockRequestsLiveData = knockRequestsDataSource.getKnockRequestsListItemsLiveData(roomId) val inviteResultLiveData = SingleEventLiveData<Response<Unit?>>() + private val loadingItemsIdsList = MutableLiveData<Set<String>>(emptySet()) + + val knockRequestsLiveData = MediatorLiveData<List<KnockRequestListItem>>().also { + it.addSource(loadingItemsIdsList) { loadingItemsValue -> + val currentList = it.value ?: emptyList() + it.postValue(currentList.map { item -> + item.copy(isLoading = loadingItemsValue.contains(item.id)) + }) + } + it.addSource(knockRequestsDataSource.getKnockRequestsListItemsLiveData(roomId)) { value -> + it.postValue(value) + } + } fun inviteUser(user: KnockRequestListItem) { launchBg { + toggleItemLoading(user.id) val result = manageInviteRequestsDataSource.inviteUser(roomId, user.requesterId) inviteResultLiveData.postValue(result) + toggleItemLoading(user.id) } } fun kickUser(user: KnockRequestListItem) { - launchBg { manageInviteRequestsDataSource.kickUser(roomId, user.requesterId) } + launchBg { + toggleItemLoading(user.id) + manageInviteRequestsDataSource.kickUser(roomId, user.requesterId) + toggleItemLoading(user.id) + } + } + + 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) } } diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt index 9df217009..47767ddaa 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDataSource.kt @@ -1,6 +1,7 @@ package org.futo.circles.core.feature.room.knoks import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow import androidx.lifecycle.asLiveData import androidx.lifecycle.map @@ -27,7 +28,7 @@ class KnockRequestsDataSource @Inject constructor() { fun getKnockRequestsListItemsLiveData(roomId: String) = getKnockRequestLiveData(roomId)?.map { it.map { user -> user.toKnockRequestListItem(roomId) } - } + } ?: MutableLiveData(emptyList()) fun getKnockRequestCountLiveDataForCurrentUserInRoom(roomId: String): LiveData<Int> { val session = MatrixSessionProvider.getSessionOrThrow() diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt index 03b2e2784..35eaf04c8 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/KnockRequestsDialogFragment.kt @@ -50,7 +50,7 @@ class KnockRequestsDialogFragment : private fun setupObservers() { viewModel.inviteResultLiveData.observeResponse(this) - viewModel.knockRequestsLiveData?.observeData(this) { + viewModel.knockRequestsLiveData.observeData(this) { knocksListAdapter.submitList(it) } } diff --git a/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt b/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt index c0634a697..d9c6d2105 100644 --- a/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt +++ b/core/src/main/java/org/futo/circles/core/feature/room/knoks/list/KnockRequestViewHolder.kt @@ -25,6 +25,7 @@ class KnockRequestViewHolder( } fun bind(data: KnockRequestListItem) { + binding.lLoading.setIsVisible(data.isLoading) binding.tvReason.apply { setIsVisible(!data.message.isNullOrBlank()) text = data.message diff --git a/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt b/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt index 4b7becdc8..e3efa753e 100644 --- a/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt +++ b/core/src/main/java/org/futo/circles/core/model/KnockRequestListItem.kt @@ -6,7 +6,8 @@ data class KnockRequestListItem( val requesterId: String, val requesterName: String, val requesterAvatarUrl: String?, - val message: String? + val message: String?, + val isLoading: Boolean = false ) : IdEntity<String> { override val id: String = requesterId } diff --git a/core/src/main/res/layout/list_item_knock_request.xml b/core/src/main/res/layout/list_item_knock_request.xml index 60906170f..8770de68a 100644 --- a/core/src/main/res/layout/list_item_knock_request.xml +++ b/core/src/main/res/layout/list_item_knock_request.xml @@ -60,5 +60,27 @@ MessageMessageMessageMessageMessageMessageMessageMessageMessageMessageMessage" app:layout_constraintStart_toEndOf="@id/btnInvite" app:layout_constraintTop_toTopOf="@id/btnInvite" /> + <FrameLayout + android:id="@+id/lLoading" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="?android:colorBackground" + android:clickable="true" + android:focusable="true" + android:outlineProvider="none" + android:translationZ="100dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvReason"> + + <ProgressBar + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + </FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file -- GitLab