Handle sync when landing on the screen
This commit is contained in:
parent
ec65564800
commit
c91761240a
@ -3209,6 +3209,7 @@
|
||||
<item quantity="one">"There are no past polls for the past day.\nLoad more polls to view polls for previous days."</item>
|
||||
<item quantity="other">"There are no past polls for the past %1$d days.\nLoad more polls to view polls for previous days."</item>
|
||||
</plurals>
|
||||
<string name="room_polls_wait_for_display">Displaying polls</string>
|
||||
<string name="room_polls_load_more">Load more polls</string>
|
||||
|
||||
<!-- Location -->
|
||||
|
@ -26,6 +26,7 @@ import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.roomprofile.polls.list.domain.GetLoadedPollsStatusUseCase
|
||||
import im.vector.app.features.roomprofile.polls.list.domain.GetPollsUseCase
|
||||
import im.vector.app.features.roomprofile.polls.list.domain.LoadMorePollsUseCase
|
||||
import im.vector.app.features.roomprofile.polls.list.domain.SyncPollsUseCase
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
@ -35,6 +36,7 @@ class RoomPollsViewModel @AssistedInject constructor(
|
||||
private val getPollsUseCase: GetPollsUseCase,
|
||||
private val getLoadedPollsStatusUseCase: GetLoadedPollsStatusUseCase,
|
||||
private val loadMorePollsUseCase: LoadMorePollsUseCase,
|
||||
private val syncPollsUseCase: SyncPollsUseCase,
|
||||
) : VectorViewModel<RoomPollsViewState, RoomPollsAction, RoomPollsViewEvent>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
@ -46,9 +48,8 @@ class RoomPollsViewModel @AssistedInject constructor(
|
||||
|
||||
init {
|
||||
updateLoadedPollStatus(initialState.roomId)
|
||||
syncPolls(initialState.roomId)
|
||||
observePolls()
|
||||
// TODO
|
||||
// call use case to sync polls until now = initial loading
|
||||
}
|
||||
|
||||
private fun updateLoadedPollStatus(roomId: String) {
|
||||
@ -61,6 +62,14 @@ class RoomPollsViewModel @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun syncPolls(roomId: String) {
|
||||
viewModelScope.launch {
|
||||
setState { copy(isSyncing = true) }
|
||||
syncPollsUseCase.execute(roomId)
|
||||
setState { copy(isSyncing = false) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun observePolls() = withState { viewState ->
|
||||
getPollsUseCase.execute(viewState.roomId)
|
||||
.onEach { setState { copy(polls = it) } }
|
||||
|
@ -20,13 +20,13 @@ import com.airbnb.mvrx.MavericksState
|
||||
import im.vector.app.features.roomprofile.RoomProfileArgs
|
||||
import im.vector.app.features.roomprofile.polls.list.ui.PollSummary
|
||||
|
||||
// TODO parameter to know whether initial loading is in progress
|
||||
data class RoomPollsViewState(
|
||||
val roomId: String,
|
||||
val polls: List<PollSummary> = emptyList(),
|
||||
val isLoadingMore: Boolean = false,
|
||||
val canLoadMore: Boolean = true,
|
||||
val nbLoadedDays: Int = 0,
|
||||
val isSyncing: Boolean = false,
|
||||
) : MavericksState {
|
||||
|
||||
constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId)
|
||||
|
@ -158,4 +158,11 @@ class RoomPollDataSource @Inject constructor() {
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun syncPolls(roomId: String) {
|
||||
Timber.d("roomId=$roomId")
|
||||
// TODO
|
||||
// unmock using SDK service + add unit tests
|
||||
delay(3000)
|
||||
}
|
||||
}
|
||||
|
@ -37,4 +37,8 @@ class RoomPollRepository @Inject constructor(
|
||||
suspend fun loadMorePolls(roomId: String): LoadedPollsStatus {
|
||||
return roomPollDataSource.loadMorePolls(roomId)
|
||||
}
|
||||
|
||||
suspend fun syncPolls(roomId: String) {
|
||||
return roomPollDataSource.syncPolls(roomId)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.roomprofile.polls.list.domain
|
||||
|
||||
import im.vector.app.features.roomprofile.polls.list.data.RoomPollRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Sync the polls of a given room from last manual loading (see LoadMorePollsUseCase) until now.
|
||||
*/
|
||||
class SyncPollsUseCase @Inject constructor(
|
||||
private val roomPollRepository: RoomPollRepository,
|
||||
) {
|
||||
|
||||
suspend fun execute(roomId: String) {
|
||||
roomPollRepository.syncPolls(roomId)
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ class RoomPollsController @Inject constructor(
|
||||
|
||||
override fun buildModels(viewState: RoomPollsViewState?) {
|
||||
val polls = viewState?.polls
|
||||
if (polls.isNullOrEmpty()) {
|
||||
if (polls.isNullOrEmpty() || viewState.isSyncing) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ import im.vector.app.features.roomprofile.polls.RoomPollsViewState
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO add and render blocking loader view
|
||||
// TODO handle errors during load more or sync
|
||||
abstract class RoomPollsListFragment :
|
||||
VectorBaseFragment<FragmentRoomPollsListBinding>(),
|
||||
RoomPollsController.Listener {
|
||||
@ -93,7 +93,14 @@ abstract class RoomPollsListFragment :
|
||||
RoomPollsType.ACTIVE -> viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)
|
||||
RoomPollsType.ENDED -> viewState.polls.filterIsInstance(PollSummary.EndedPoll::class.java)
|
||||
}
|
||||
renderList(viewState.copy(polls = filteredPolls))
|
||||
val updatedViewState = viewState.copy(polls = filteredPolls)
|
||||
renderList(updatedViewState)
|
||||
renderSyncingView(updatedViewState)
|
||||
}
|
||||
|
||||
private fun renderSyncingView(viewState: RoomPollsViewState) {
|
||||
views.roomPollsSyncingTitle.isVisible = viewState.isSyncing
|
||||
views.roomPollsSyncingProgress.isVisible = viewState.isSyncing
|
||||
}
|
||||
|
||||
private fun renderList(viewState: RoomPollsViewState) {
|
||||
@ -102,9 +109,10 @@ abstract class RoomPollsListFragment :
|
||||
canLoadMore = viewState.canLoadMore,
|
||||
nbLoadedDays = viewState.nbLoadedDays,
|
||||
)
|
||||
views.roomPollsEmptyTitle.isVisible = viewState.polls.isEmpty()
|
||||
views.roomPollsLoadMoreWhenEmpty.isVisible = viewState.polls.isEmpty()
|
||||
views.roomPollsLoadMoreWhenEmptyProgress.isVisible = viewState.polls.isEmpty() && viewState.isLoadingMore
|
||||
views.roomPollsEmptyTitle.isVisible = viewState.polls.isEmpty() && !viewState.isSyncing
|
||||
views.roomPollsLoadMoreWhenEmpty.isVisible = viewState.polls.isEmpty() && viewState.canLoadMore && !viewState.isSyncing
|
||||
views.roomPollsLoadMoreWhenEmptyProgress.isVisible = viewState.polls.isEmpty() && viewState.canLoadMore &&
|
||||
viewState.isLoadingMore && !viewState.isSyncing
|
||||
views.roomPollsLoadMoreWhenEmptyProgress.isEnabled = !viewState.isLoadingMore
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,34 @@
|
||||
tools:itemCount="5"
|
||||
tools:listitem="@layout/item_poll" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/roomPollsSyncingProgress"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:indeterminateTint="?vctr_content_secondary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/roomPollsSyncingTitle"
|
||||
app:layout_constraintEnd_toStartOf="@id/roomPollsSyncingTitle"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/roomPollsSyncingTitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomPollsSyncingTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="9dp"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:gravity="center"
|
||||
android:text="@string/room_polls_wait_for_display"
|
||||
android:textAppearance="@style/TextAppearance.Vector.Body"
|
||||
android:textColor="?vctr_content_secondary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/roomPollsSyncingProgress"
|
||||
app:layout_constraintTop_toTopOf="@id/roomPollsTitleGuideline" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomPollsEmptyTitle"
|
||||
android:layout_width="0dp"
|
||||
@ -30,9 +58,8 @@
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/roomPollsEmptyGuideline"
|
||||
tools:text="@string/room_polls_active_no_item"
|
||||
tools:visibility="visible" />
|
||||
app:layout_constraintTop_toTopOf="@id/roomPollsTitleGuideline"
|
||||
tools:text="@string/room_polls_active_no_item" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/roomPollsLoadMoreWhenEmpty"
|
||||
@ -45,8 +72,7 @@
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/roomPollsEmptyTitle"
|
||||
tools:visibility="visible" />
|
||||
app:layout_constraintTop_toBottomOf="@id/roomPollsEmptyTitle" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/roomPollsLoadMoreWhenEmptyProgress"
|
||||
@ -57,11 +83,10 @@
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/roomPollsLoadMoreWhenEmpty"
|
||||
app:layout_constraintStart_toEndOf="@id/roomPollsLoadMoreWhenEmpty"
|
||||
app:layout_constraintTop_toTopOf="@id/roomPollsLoadMoreWhenEmpty"
|
||||
tools:visibility="visible" />
|
||||
app:layout_constraintTop_toTopOf="@id/roomPollsLoadMoreWhenEmpty" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/roomPollsEmptyGuideline"
|
||||
android:id="@+id/roomPollsTitleGuideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
Loading…
x
Reference in New Issue
Block a user