Get loaded polls status use case

This commit is contained in:
Maxime NATUREL 2023-01-18 14:53:14 +01:00
parent 3e118f24ad
commit 10be07590d
11 changed files with 88 additions and 41 deletions

View file

@ -35,7 +35,7 @@ interface PollHistoryService {
/** /**
* Get the current status of the loaded polls. * Get the current status of the loaded polls.
*/ */
fun getLoadedPollsStatus(): LoadedPollsStatus suspend fun getLoadedPollsStatus(): LoadedPollsStatus
/** /**
* Sync polls from last loaded polls until now. * Sync polls from last loaded polls until now.

View file

@ -89,7 +89,9 @@ import org.matrix.android.sdk.internal.session.room.peeking.DefaultPeekRoomTask
import org.matrix.android.sdk.internal.session.room.peeking.DefaultResolveRoomStateTask import org.matrix.android.sdk.internal.session.room.peeking.DefaultResolveRoomStateTask
import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask
import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask
import org.matrix.android.sdk.internal.session.room.poll.DefaultGetLoadedPollsStatusTask
import org.matrix.android.sdk.internal.session.room.poll.DefaultLoadMorePollsTask import org.matrix.android.sdk.internal.session.room.poll.DefaultLoadMorePollsTask
import org.matrix.android.sdk.internal.session.room.poll.GetLoadedPollsStatusTask
import org.matrix.android.sdk.internal.session.room.poll.LoadMorePollsTask import org.matrix.android.sdk.internal.session.room.poll.LoadMorePollsTask
import org.matrix.android.sdk.internal.session.room.read.DefaultMarkAllRoomsReadTask import org.matrix.android.sdk.internal.session.room.read.DefaultMarkAllRoomsReadTask
import org.matrix.android.sdk.internal.session.room.read.DefaultSetReadMarkersTask import org.matrix.android.sdk.internal.session.room.read.DefaultSetReadMarkersTask
@ -364,4 +366,7 @@ internal abstract class RoomModule {
@Binds @Binds
abstract fun bindLoadMorePollsTask(task: DefaultLoadMorePollsTask): LoadMorePollsTask abstract fun bindLoadMorePollsTask(task: DefaultLoadMorePollsTask): LoadMorePollsTask
@Binds
abstract fun bindGetLoadedPollsStatusTask(task: DefaultGetLoadedPollsStatusTask): GetLoadedPollsStatusTask
} }

View file

@ -34,6 +34,7 @@ internal class DefaultPollHistoryService @AssistedInject constructor(
@Assisted private val roomId: String, @Assisted private val roomId: String,
private val clock: Clock, private val clock: Clock,
private val loadMorePollsTask: LoadMorePollsTask, private val loadMorePollsTask: LoadMorePollsTask,
private val getLoadedPollsStatusTask: GetLoadedPollsStatusTask,
) : PollHistoryService { ) : PollHistoryService {
@AssistedFactory @AssistedFactory
@ -58,8 +59,12 @@ internal class DefaultPollHistoryService @AssistedInject constructor(
return loadMorePollsTask.execute(params) return loadMorePollsTask.execute(params)
} }
override fun getLoadedPollsStatus(): LoadedPollsStatus { override suspend fun getLoadedPollsStatus(): LoadedPollsStatus {
TODO("Not yet implemented") val params = GetLoadedPollsStatusTask.Params(
roomId = roomId,
currentTimestampMs = clock.epochMillis(),
)
return getLoadedPollsStatusTask.execute(params)
} }
override suspend fun syncPolls() { override suspend fun syncPolls() {

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.session.room.poll
import com.zhuinden.monarchy.Monarchy
import org.matrix.android.sdk.api.session.room.poll.LoadedPollsStatus
import org.matrix.android.sdk.internal.database.model.PollHistoryStatusEntity
import org.matrix.android.sdk.internal.database.query.getOrCreate
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.task.Task
import org.matrix.android.sdk.internal.util.awaitTransaction
import javax.inject.Inject
internal interface GetLoadedPollsStatusTask : Task<GetLoadedPollsStatusTask.Params, LoadedPollsStatus> {
data class Params(
val roomId: String,
val currentTimestampMs: Long,
)
}
internal class DefaultGetLoadedPollsStatusTask @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
) : GetLoadedPollsStatusTask {
override suspend fun execute(params: GetLoadedPollsStatusTask.Params): LoadedPollsStatus {
return monarchy.awaitTransaction { realm ->
val status = PollHistoryStatusEntity.getOrCreate(realm, params.roomId)
LoadedPollsStatus(
canLoadMore = status.isEndOfPollsBackward.not(),
nbSyncedDays = status.getNbSyncedDays(params.currentTimestampMs),
)
}
}
}

View file

@ -48,26 +48,21 @@ class RoomPollsViewModel @AssistedInject constructor(
init { init {
val roomId = initialState.roomId val roomId = initialState.roomId
updateLoadedPollStatus(roomId)
syncPolls(roomId) syncPolls(roomId)
observePolls(roomId) observePolls(roomId)
} }
private fun updateLoadedPollStatus(roomId: String) {
val loadedPollsStatus = getLoadedPollsStatusUseCase.execute(roomId)
setState {
copy(
canLoadMore = loadedPollsStatus.canLoadMore,
nbSyncedDays = loadedPollsStatus.nbSyncedDays,
)
}
}
private fun syncPolls(roomId: String) { private fun syncPolls(roomId: String) {
viewModelScope.launch { viewModelScope.launch {
setState { copy(isSyncing = true) } setState { copy(isSyncing = true) }
val result = runCatching { val result = runCatching {
syncPollsUseCase.execute(roomId) val loadedPollsStatus = syncPollsUseCase.execute(roomId)
setState {
copy(
canLoadMore = loadedPollsStatus.canLoadMore,
nbSyncedDays = loadedPollsStatus.nbSyncedDays,
)
}
} }
if (result.isFailure) { if (result.isFailure) {
_viewEvents.post(RoomPollsViewEvent.LoadingError) _viewEvents.post(RoomPollsViewEvent.LoadingError)

View file

@ -17,5 +17,5 @@
package im.vector.app.features.roomprofile.polls.list.data package im.vector.app.features.roomprofile.polls.list.data
sealed class PollHistoryError : Exception() { sealed class PollHistoryError : Exception() {
object LoadingError : PollHistoryError() object UnknownRoomError : PollHistoryError()
} }

View file

@ -34,13 +34,13 @@ class RoomPollDataSource @Inject constructor(
) { ) {
private val pollsFlow = MutableSharedFlow<List<PollSummary>>(replay = 1) private val pollsFlow = MutableSharedFlow<List<PollSummary>>(replay = 1)
private var fakeLoadCounter = 0
private fun getPollHistoryService(roomId: String): PollHistoryService? { private fun getPollHistoryService(roomId: String): PollHistoryService {
return activeSessionHolder return activeSessionHolder
.getSafeActiveSession() .getSafeActiveSession()
?.getRoom(roomId) ?.getRoom(roomId)
?.pollHistoryService() ?.pollHistoryService()
?: throw PollHistoryError.UnknownRoomError
} }
// TODO // TODO
@ -51,21 +51,12 @@ class RoomPollDataSource @Inject constructor(
return pollsFlow.asSharedFlow() return pollsFlow.asSharedFlow()
} }
fun getLoadedPollsStatus(roomId: String): LoadedPollsStatus { suspend fun getLoadedPollsStatus(roomId: String): LoadedPollsStatus {
Timber.d("roomId=$roomId") return getPollHistoryService(roomId).getLoadedPollsStatus()
// TODO unmock using SDK
return LoadedPollsStatus(
canLoadMore = canLoadMore(),
nbSyncedDays = fakeLoadCounter * 30,
)
}
private fun canLoadMore(): Boolean {
return fakeLoadCounter < 2
} }
suspend fun loadMorePolls(roomId: String): LoadedPollsStatus { suspend fun loadMorePolls(roomId: String): LoadedPollsStatus {
return getPollHistoryService(roomId)?.loadMore() ?: throw PollHistoryError.LoadingError return getPollHistoryService(roomId).loadMore()
} }
suspend fun syncPolls(roomId: String) { suspend fun syncPolls(roomId: String) {

View file

@ -30,7 +30,7 @@ class RoomPollRepository @Inject constructor(
return roomPollDataSource.getPolls(roomId) return roomPollDataSource.getPolls(roomId)
} }
fun getLoadedPollsStatus(roomId: String): LoadedPollsStatus { suspend fun getLoadedPollsStatus(roomId: String): LoadedPollsStatus {
return roomPollDataSource.getLoadedPollsStatus(roomId) return roomPollDataSource.getLoadedPollsStatus(roomId)
} }

View file

@ -24,7 +24,7 @@ class GetLoadedPollsStatusUseCase @Inject constructor(
private val roomPollRepository: RoomPollRepository, private val roomPollRepository: RoomPollRepository,
) { ) {
fun execute(roomId: String): LoadedPollsStatus { suspend fun execute(roomId: String): LoadedPollsStatus {
return roomPollRepository.getLoadedPollsStatus(roomId) return roomPollRepository.getLoadedPollsStatus(roomId)
} }
} }

View file

@ -17,6 +17,7 @@
package im.vector.app.features.roomprofile.polls.list.domain package im.vector.app.features.roomprofile.polls.list.domain
import im.vector.app.features.roomprofile.polls.list.data.RoomPollRepository import im.vector.app.features.roomprofile.polls.list.data.RoomPollRepository
import org.matrix.android.sdk.api.session.room.poll.LoadedPollsStatus
import javax.inject.Inject import javax.inject.Inject
/** /**
@ -24,9 +25,11 @@ import javax.inject.Inject
*/ */
class SyncPollsUseCase @Inject constructor( class SyncPollsUseCase @Inject constructor(
private val roomPollRepository: RoomPollRepository, private val roomPollRepository: RoomPollRepository,
private val getLoadedPollsStatusUseCase: GetLoadedPollsStatusUseCase,
) { ) {
suspend fun execute(roomId: String) { suspend fun execute(roomId: String): LoadedPollsStatus {
roomPollRepository.syncPolls(roomId) roomPollRepository.syncPolls(roomId)
return getLoadedPollsStatusUseCase.execute(roomId)
} }
} }

View file

@ -17,7 +17,6 @@
package im.vector.app.features.roomprofile.polls package im.vector.app.features.roomprofile.polls
import com.airbnb.mvrx.test.MavericksTestRule import com.airbnb.mvrx.test.MavericksTestRule
import im.vector.app.features.roomprofile.polls.list.data.LoadedPollsStatus
import im.vector.app.features.roomprofile.polls.list.domain.GetLoadedPollsStatusUseCase 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.GetPollsUseCase
import im.vector.app.features.roomprofile.polls.list.domain.LoadMorePollsUseCase import im.vector.app.features.roomprofile.polls.list.domain.LoadMorePollsUseCase
@ -34,6 +33,7 @@ import io.mockk.verify
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.matrix.android.sdk.api.session.room.poll.LoadedPollsStatus
private const val A_ROOM_ID = "room-id" private const val A_ROOM_ID = "room-id"
@ -68,7 +68,7 @@ class RoomPollsViewModelTest {
val expectedViewState = initialState.copy( val expectedViewState = initialState.copy(
polls = polls, polls = polls,
canLoadMore = loadedPollsStatus.canLoadMore, canLoadMore = loadedPollsStatus.canLoadMore,
nbSyncedDays = loadedPollsStatus.nbLoadedDays, nbSyncedDays = loadedPollsStatus.nbSyncedDays,
) )
// When // When
@ -116,7 +116,7 @@ class RoomPollsViewModelTest {
val stateAfterInit = initialState.copy( val stateAfterInit = initialState.copy(
polls = polls, polls = polls,
canLoadMore = loadedPollsStatus.canLoadMore, canLoadMore = loadedPollsStatus.canLoadMore,
nbSyncedDays = loadedPollsStatus.nbLoadedDays, nbSyncedDays = loadedPollsStatus.nbSyncedDays,
) )
// When // When
@ -128,7 +128,7 @@ class RoomPollsViewModelTest {
.assertStatesChanges( .assertStatesChanges(
stateAfterInit, stateAfterInit,
{ copy(isLoadingMore = true) }, { copy(isLoadingMore = true) },
{ copy(canLoadMore = newLoadedPollsStatus.canLoadMore, nbSyncedDays = newLoadedPollsStatus.nbLoadedDays) }, { copy(canLoadMore = newLoadedPollsStatus.canLoadMore, nbSyncedDays = newLoadedPollsStatus.nbSyncedDays) },
{ copy(isLoadingMore = false) }, { copy(isLoadingMore = false) },
) )
.finish() .finish()
@ -148,20 +148,20 @@ class RoomPollsViewModelTest {
} }
private fun givenLoadMoreWithSuccess(): LoadedPollsStatus { private fun givenLoadMoreWithSuccess(): LoadedPollsStatus {
val loadedPollsStatus = givenALoadedPollsStatus(canLoadMore = false, nbLoadedDays = 20) val loadedPollsStatus = givenALoadedPollsStatus(canLoadMore = false, nbSyncedDays = 20)
coEvery { fakeLoadMorePollsUseCase.execute(A_ROOM_ID) } returns loadedPollsStatus coEvery { fakeLoadMorePollsUseCase.execute(A_ROOM_ID) } returns loadedPollsStatus
return loadedPollsStatus return loadedPollsStatus
} }
private fun givenGetLoadedPollsStatusSuccess(): LoadedPollsStatus { private fun givenGetLoadedPollsStatusSuccess(): LoadedPollsStatus {
val loadedPollsStatus = givenALoadedPollsStatus() val loadedPollsStatus = givenALoadedPollsStatus()
every { fakeGetLoadedPollsStatusUseCase.execute(A_ROOM_ID) } returns loadedPollsStatus coEvery { fakeGetLoadedPollsStatusUseCase.execute(A_ROOM_ID) } returns loadedPollsStatus
return loadedPollsStatus return loadedPollsStatus
} }
private fun givenALoadedPollsStatus(canLoadMore: Boolean = true, nbLoadedDays: Int = 10) = private fun givenALoadedPollsStatus(canLoadMore: Boolean = true, nbSyncedDays: Int = 10) =
LoadedPollsStatus( LoadedPollsStatus(
canLoadMore = canLoadMore, canLoadMore = canLoadMore,
nbLoadedDays = nbLoadedDays, nbSyncedDays = nbSyncedDays,
) )
} }