DefaultAppendRemoteMediator.kt
package com.louisfn.somovie.data.repository.paging
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import com.louisfn.somovie.core.logger.Logger
import com.louisfn.somovie.data.database.datasource.RemoteKeyLocalDataSource
import com.louisfn.somovie.data.database.entity.RemoteKeyEntity
internal abstract class DefaultAppendRemoteMediator<Key : Any, Value : Any> constructor(
private val remoteKeyLocalDataSource: RemoteKeyLocalDataSource,
private val remoteKeyType: RemoteKeyEntity.Type,
private val cacheTimeout: Long,
) : RemoteMediator<Key, Value>() {
override suspend fun initialize() =
if (remoteKeyLocalDataSource.isExpired(remoteKeyType, cacheTimeout)) {
InitializeAction.LAUNCH_INITIAL_REFRESH
} else {
InitializeAction.SKIP_INITIAL_REFRESH
}
@Suppress("ReturnCount")
override suspend fun load(loadType: LoadType, state: PagingState<Key, Value>): MediatorResult {
return try {
val remoteKey = remoteKeyLocalDataSource.getRemoteKey(remoteKeyType)
val key = when (loadType) {
LoadType.REFRESH -> null
LoadType.PREPEND -> return MediatorResult.Success(true)
LoadType.APPEND -> checkNotNull(remoteKey).nextKey
?: return MediatorResult.Success(true)
}
val result = fetchNewData(key)
remoteKeyLocalDataSource.updateNextKey(
type = remoteKeyType,
nextKey = result.nextKey,
reset = loadType == LoadType.REFRESH,
)
MediatorResult.Success(endOfPaginationReached = result.endOfPaginationReached)
} catch (e: Exception) {
Logger.e(e)
MediatorResult.Error(e)
}
}
abstract suspend fun fetchNewData(key: String?): Result
data class Result(
val nextKey: String,
val endOfPaginationReached: Boolean,
)
}