Files
rider-pro-android-app/app/src/main/java/com/aiosman/riderpro/data/MomentService.kt

138 lines
3.9 KiB
Kotlin
Raw Normal View History

2024-07-29 00:01:09 +08:00
package com.aiosman.riderpro.data
2024-07-23 15:25:00 +08:00
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.aiosman.riderpro.model.MomentItem
2024-07-29 00:01:09 +08:00
import com.aiosman.riderpro.test.TestDatabase
2024-07-23 15:25:00 +08:00
import java.io.IOException
2024-07-29 16:50:07 +08:00
import kotlin.math.min
interface MomentService {
suspend fun getMomentById(id: Int): MomentItem
suspend fun likeMoment(id: Int)
suspend fun getMoments(
pageNumber: Int,
author: Int? = null,
timelineId: Int? = null
): ListContainer<MomentItem>
}
2024-07-23 15:25:00 +08:00
class MomentPagingSource(
private val remoteDataSource: MomentRemoteDataSource,
2024-07-29 16:50:07 +08:00
private val author: Int? = null,
private val timelineId: Int? = null
2024-07-23 15:25:00 +08:00
) : PagingSource<Int, MomentItem>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MomentItem> {
return try {
val currentPage = params.key ?: 1
val moments = remoteDataSource.getMoments(
2024-07-29 16:50:07 +08:00
pageNumber = currentPage,
author = author,
timelineId = timelineId
2024-07-23 15:25:00 +08:00
)
LoadResult.Page(
data = moments.list,
prevKey = if (currentPage == 1) null else currentPage - 1,
nextKey = if (moments.list.isEmpty()) null else moments.page + 1
)
} catch (exception: IOException) {
return LoadResult.Error(exception)
}
}
override fun getRefreshKey(state: PagingState<Int, MomentItem>): Int? {
return state.anchorPosition
}
}
class MomentRemoteDataSource(
private val momentService: MomentService,
) {
2024-07-29 16:50:07 +08:00
suspend fun getMoments(
pageNumber: Int,
author: Int?,
timelineId: Int?
): ListContainer<MomentItem> {
return momentService.getMoments(pageNumber, author, timelineId)
2024-07-23 15:25:00 +08:00
}
}
class TestMomentServiceImpl() : MomentService {
2024-07-29 16:50:07 +08:00
val testMomentBackend = TestMomentBackend()
override suspend fun getMoments(
pageNumber: Int,
author: Int?,
timelineId: Int?
): ListContainer<MomentItem> {
return testMomentBackend.fetchMomentItems(pageNumber, author, timelineId)
2024-07-23 15:25:00 +08:00
}
2024-07-28 15:07:08 +08:00
override suspend fun getMomentById(id: Int): MomentItem {
2024-07-29 16:50:07 +08:00
return testMomentBackend.getMomentById(id)
2024-07-28 15:07:08 +08:00
}
2024-07-29 00:01:09 +08:00
2024-07-29 16:50:07 +08:00
2024-07-29 00:01:09 +08:00
override suspend fun likeMoment(id: Int) {
2024-07-29 16:50:07 +08:00
testMomentBackend.likeMoment(id)
2024-07-29 00:01:09 +08:00
}
2024-07-23 15:25:00 +08:00
}
class TestMomentBackend(
private val loadDelay: Long = 500,
) {
val DataBatchSize = 5
2024-07-29 16:50:07 +08:00
suspend fun fetchMomentItems(
pageNumber: Int,
author: Int? = null,
timelineId: Int?
): ListContainer<MomentItem> {
var rawList = TestDatabase.momentData
if (author != null) {
rawList = rawList.filter { it.authorId == author }
}
if (timelineId != null) {
val followIdList = TestDatabase.followList.filter {
it.first == timelineId
}.map { it.second }
rawList = rawList.filter { it.authorId in followIdList }
}
val from = (pageNumber - 1) * DataBatchSize
val to = (pageNumber) * DataBatchSize
if (from >= rawList.size) {
return ListContainer(
total = rawList.size,
page = pageNumber,
pageSize = DataBatchSize,
list = emptyList()
)
}
val currentSublist = rawList.subList(from, min(to, rawList.size))
2024-07-23 15:25:00 +08:00
// delay
kotlinx.coroutines.delay(loadDelay)
return ListContainer(
2024-07-29 16:50:07 +08:00
total = rawList.size,
2024-07-23 15:25:00 +08:00
page = pageNumber,
pageSize = DataBatchSize,
list = currentSublist
)
}
2024-07-29 16:50:07 +08:00
suspend fun getMomentById(id: Int): MomentItem {
return TestDatabase.momentData[id]
}
suspend fun likeMoment(id: Int) {
val oldMoment = TestDatabase.momentData.first {
it.id == id
}
val newMoment = oldMoment.copy(likeCount = oldMoment.likeCount + 1)
TestDatabase.updateMomentById(id, newMoment)
}
2024-07-23 15:25:00 +08:00
}