Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.paging.ExperimentalPagingApi
import dev.dimension.flare.data.datasource.microblog.paging.CacheableRemoteLoader
import dev.dimension.flare.data.datasource.microblog.paging.PagingRequest
import dev.dimension.flare.data.datasource.microblog.paging.PagingResult
import dev.dimension.flare.data.datasource.microblog.paging.RefreshBehavior
import dev.dimension.flare.data.network.mastodon.MastodonService
import dev.dimension.flare.model.MicroBlogKey
import dev.dimension.flare.ui.model.UiTimelineV2
Expand All @@ -19,6 +20,9 @@ internal class HomeTimelineRemoteMediator(
override val supportPrepend: Boolean
get() = true

override val refreshBehavior: RefreshBehavior
get() = RefreshBehavior.MergeTop

override suspend fun load(
pageSize: Int,
request: PagingRequest,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.paging.ExperimentalPagingApi
import dev.dimension.flare.data.datasource.microblog.paging.CacheableRemoteLoader
import dev.dimension.flare.data.datasource.microblog.paging.PagingRequest
import dev.dimension.flare.data.datasource.microblog.paging.PagingResult
import dev.dimension.flare.data.datasource.microblog.paging.RefreshBehavior
import dev.dimension.flare.data.network.mastodon.MastodonService
import dev.dimension.flare.model.MicroBlogKey
import dev.dimension.flare.ui.model.UiTimelineV2
Expand All @@ -20,6 +21,9 @@ internal class ListTimelineRemoteMediator(
override val supportPrepend: Boolean
get() = true

override val refreshBehavior: RefreshBehavior
get() = RefreshBehavior.MergeTop

override suspend fun load(
pageSize: Int,
request: PagingRequest,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.dimension.flare.data.database.cache.connect
import dev.dimension.flare.data.datasource.microblog.paging.CacheableRemoteLoader
import dev.dimension.flare.data.datasource.microblog.paging.PagingRequest
import dev.dimension.flare.data.datasource.microblog.paging.PagingResult
import dev.dimension.flare.data.datasource.microblog.paging.RefreshBehavior
import dev.dimension.flare.data.datasource.microblog.paging.ReportableRemoteLoader
import dev.dimension.flare.ui.model.UiTimelineV2
import kotlinx.coroutines.async
Expand Down Expand Up @@ -52,7 +53,7 @@ internal class MixedRemoteMediator(
reportError?.invoke(it)
PagingResult(endOfPaginationReached = true)
}.let {
SubResponse(subRequest.mediator, it)
SubResponse(subRequest.mediator, subRequest.request, it)
}
}
}.awaitAll()
Expand All @@ -72,7 +73,7 @@ internal class MixedRemoteMediator(

database.connect {
response.forEach {
saveSubResponse(request, it)
saveSubResponse(it)
}
}

Expand Down Expand Up @@ -114,16 +115,23 @@ internal class MixedRemoteMediator(
?.prevKey
?.let(PagingRequest::Prepend)

is PagingRequest.Refresh -> PagingRequest.Refresh
is PagingRequest.Refresh ->
if (mediator.refreshBehavior == RefreshBehavior.MergeTop && mediator.supportPrepend) {
database
.pagingTimelineDao()
.getPagingKey(subKey(mediator))
?.prevKey
?.let(PagingRequest::Prepend)
?: PagingRequest.Refresh
} else {
PagingRequest.Refresh
}
}?.let {
SubRequest(mediator, it)
}

private suspend fun saveSubResponse(
request: PagingRequest,
subResponse: SubResponse,
) {
val (mediator, result) = subResponse
private suspend fun saveSubResponse(subResponse: SubResponse) {
val (mediator, request, result) = subResponse
if (request is PagingRequest.Prepend && result.previousKey != null) {
database.pagingTimelineDao().updatePagingKeyPrevKey(
pagingKey = subKey(mediator),
Expand Down Expand Up @@ -157,6 +165,7 @@ internal class MixedRemoteMediator(

private data class SubResponse(
val mediator: CacheableRemoteLoader<UiTimelineV2>,
val request: PagingRequest,
val result: PagingResult<UiTimelineV2>,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,7 @@ internal abstract class BasePagingRemoteMediator<T : Any, R : Any>(
request = request,
)
database.connect {
if (loadType == LoadType.REFRESH) {
database.pagingTimelineDao().deletePagingKey(pagingKey)
database.pagingTimelineDao().insertPagingKey(
DbPagingKey(
pagingKey = pagingKey,
nextKey = result.nextKey,
prevKey = result.previousKey,
),
)
} else if (loadType == LoadType.PREPEND && result.previousKey != null) {
database.pagingTimelineDao().updatePagingKeyPrevKey(
pagingKey = pagingKey,
prevKey = result.previousKey,
)
} else if (loadType == LoadType.APPEND && result.nextKey != null) {
database.pagingTimelineDao().updatePagingKeyNextKey(
pagingKey = pagingKey,
nextKey = result.nextKey,
)
}
updatePagingKeys(loadType, request, result)
onSaveCache(request, result.data)
}
return MediatorResult.Success(
Expand All @@ -100,6 +81,33 @@ internal abstract class BasePagingRemoteMediator<T : Any, R : Any>(
request: PagingRequest,
): PagingResult<R>

protected open suspend fun updatePagingKeys(
loadType: LoadType,
request: PagingRequest,
result: PagingResult<R>,
) {
if (loadType == LoadType.REFRESH) {
database.pagingTimelineDao().deletePagingKey(pagingKey)
database.pagingTimelineDao().insertPagingKey(
DbPagingKey(
pagingKey = pagingKey,
nextKey = result.nextKey,
prevKey = result.previousKey,
),
)
} else if (loadType == LoadType.PREPEND && result.previousKey != null) {
database.pagingTimelineDao().updatePagingKeyPrevKey(
pagingKey = pagingKey,
prevKey = result.previousKey,
)
} else if (loadType == LoadType.APPEND && result.nextKey != null) {
database.pagingTimelineDao().updatePagingKeyNextKey(
pagingKey = pagingKey,
nextKey = result.nextKey,
)
}
}

protected abstract suspend fun onSaveCache(
request: PagingRequest,
data: List<R>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package dev.dimension.flare.data.datasource.microblog.paging

internal enum class RefreshBehavior {
Replace,
MergeTop,
}

internal interface CacheableRemoteLoader<T : Any> : RemoteLoader<T> {
val pagingKey: String
val supportPrepend: Boolean
get() = false
val refreshBehavior: RefreshBehavior
get() = RefreshBehavior.Replace
}

internal interface ReportableRemoteLoader {
Expand Down
Loading
Loading