Starting to implement LoadMorePollsTask with update of poll history status

This commit is contained in:
Maxime NATUREL 2023-01-16 16:07:29 +01:00
parent 1ab6faf2d2
commit 9d92128631
5 changed files with 131 additions and 3 deletions

View file

@ -0,0 +1,31 @@
/*
* 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.database.query
import io.realm.Realm
import io.realm.kotlin.createObject
import io.realm.kotlin.where
import org.matrix.android.sdk.internal.database.model.PollHistoryStatusEntity
import org.matrix.android.sdk.internal.database.model.PollHistoryStatusEntityFields
internal fun PollHistoryStatusEntity.Companion.get(realm: Realm, roomId: String): PollHistoryStatusEntity? {
return realm.where<PollHistoryStatusEntity>().equalTo(PollHistoryStatusEntityFields.ROOM_ID, roomId).findFirst()
}
internal fun PollHistoryStatusEntity.Companion.getOrCreate(realm: Realm, roomId: String): PollHistoryStatusEntity {
return get(realm, roomId) ?: realm.createObject(roomId)
}

View file

@ -89,6 +89,8 @@ 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.PeekRoomTask
import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask
import org.matrix.android.sdk.internal.session.room.poll.DefaultLoadMorePollsTask
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.DefaultSetReadMarkersTask
import org.matrix.android.sdk.internal.session.room.read.MarkAllRoomsReadTask
@ -359,4 +361,7 @@ internal abstract class RoomModule {
@Binds
abstract fun bindFetchPollResponseEventsTask(task: DefaultFetchPollResponseEventsTask): FetchPollResponseEventsTask
@Binds
abstract fun bindLoadMorePollsTask(task: DefaultLoadMorePollsTask): LoadMorePollsTask
}

View file

@ -23,13 +23,17 @@ import dagger.assisted.AssistedInject
import org.matrix.android.sdk.api.session.room.model.PollResponseAggregatedSummary
import org.matrix.android.sdk.api.session.room.poll.LoadedPollsStatus
import org.matrix.android.sdk.api.session.room.poll.PollHistoryService
import org.matrix.android.sdk.internal.util.time.Clock
import timber.log.Timber
private const val LOADING_PERIOD_IN_DAYS = 30
private const val EVENTS_PAGE_SIZE = 200
// TODO add unit tests
internal class DefaultPollHistoryService @AssistedInject constructor(
@Assisted private val roomId: String,
private val clock: Clock,
private val loadMorePollsTask: LoadMorePollsTask,
) : PollHistoryService {
@AssistedFactory
@ -45,7 +49,14 @@ internal class DefaultPollHistoryService @AssistedInject constructor(
get() = LOADING_PERIOD_IN_DAYS
override suspend fun loadMore(): LoadedPollsStatus {
TODO("Not yet implemented")
// TODO when to set currentTimestampMs and who is responsible for it?
val params = LoadMorePollsTask.Params(
roomId = roomId,
currentTimestampMs = clock.epochMillis(),
loadingPeriodInDays = loadingPeriodInDays,
eventsPageSize = EVENTS_PAGE_SIZE,
)
return loadMorePollsTask.execute(params)
}
override fun canLoadMore(): Boolean {

View file

@ -0,0 +1,67 @@
/*
* 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 LoadMorePollsTask : Task<LoadMorePollsTask.Params, LoadedPollsStatus> {
data class Params(
val roomId: String,
val currentTimestampMs: Long,
val loadingPeriodInDays: Int,
val eventsPageSize: Int,
)
}
private const val MILLISECONDS_PER_DAY = 24 * 60 * 60_000
internal class DefaultLoadMorePollsTask @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
) : LoadMorePollsTask {
override suspend fun execute(params: LoadMorePollsTask.Params): LoadedPollsStatus {
updatePollHistoryStatus(params)
return LoadedPollsStatus(
canLoadMore = true,
nbLoadedDays = 10,
)
}
private suspend fun updatePollHistoryStatus(params: LoadMorePollsTask.Params) {
monarchy.awaitTransaction { realm ->
val status = PollHistoryStatusEntity.getOrCreate(realm, params.roomId)
val currentTargetTimestamp = status.currentTimestampTargetBackwardMs
val loadingPeriodMs = MILLISECONDS_PER_DAY * params.loadingPeriodInDays
if (currentTargetTimestamp == null) {
// first load, compute the target timestamp
status.currentTimestampTargetBackwardMs = params.currentTimestampMs - loadingPeriodMs
} else if (status.currentTimestampTargetBackwardReached) {
// previous load has finished, update the target timestamp
status.currentTimestampTargetBackwardMs = currentTargetTimestamp - loadingPeriodMs
status.currentTimestampTargetBackwardReached = false
}
}
}
}

View file

@ -16,23 +16,35 @@
package im.vector.app.features.roomprofile.polls.list.data
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState
import im.vector.app.features.roomprofile.polls.list.ui.PollSummary
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.poll.PollHistoryService
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RoomPollDataSource @Inject constructor() {
class RoomPollDataSource @Inject constructor(
private val activeSessionHolder: ActiveSessionHolder,
) {
private val pollsFlow = MutableSharedFlow<List<PollSummary>>(replay = 1)
private val polls = mutableListOf<PollSummary>()
private var fakeLoadCounter = 0
private fun getPollHistoryService(roomId: String): PollHistoryService? {
return activeSessionHolder
.getSafeActiveSession()
?.getRoom(roomId)
?.pollHistoryService()
}
// TODO
// unmock using SDK service + add unit tests
// after unmock, expose domain layer model (entity) and do the mapping to PollSummary in the UI layer
@ -54,8 +66,10 @@ class RoomPollDataSource @Inject constructor() {
}
suspend fun loadMorePolls(roomId: String): LoadedPollsStatus {
getPollHistoryService(roomId)?.loadMore()
// TODO
// unmock using SDK service + add unit tests
// remove mocked data + add unit tests
delay(3000)
fakeLoadCounter++
when (fakeLoadCounter) {