更新
This commit is contained in:
@@ -2,28 +2,109 @@ package com.aiosman.riderpro.data
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import com.aiosman.riderpro.AppStore
|
||||
import com.aiosman.riderpro.R
|
||||
import com.aiosman.riderpro.model.MomentItem
|
||||
import com.aiosman.riderpro.data.api.ApiClient
|
||||
import com.aiosman.riderpro.model.MomentEntity
|
||||
import com.aiosman.riderpro.test.TestDatabase
|
||||
import java.io.IOException
|
||||
import kotlin.math.min
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
|
||||
data class Moment(
|
||||
@SerializedName("id")
|
||||
val id: Long,
|
||||
@SerializedName("textContent")
|
||||
val textContent: String,
|
||||
@SerializedName("images")
|
||||
val images: List<Image>,
|
||||
@SerializedName("user")
|
||||
val user: User,
|
||||
@SerializedName("likeCount")
|
||||
val likeCount: Long,
|
||||
@SerializedName("isLiked")
|
||||
val isLiked: Boolean,
|
||||
@SerializedName("favoriteCount")
|
||||
val favoriteCount: Long,
|
||||
@SerializedName("isFavorite")
|
||||
val isFavorite: Boolean,
|
||||
@SerializedName("shareCount")
|
||||
val isCommented: Boolean,
|
||||
@SerializedName("commentCount")
|
||||
val commentCount: Long,
|
||||
@SerializedName("time")
|
||||
val time: String
|
||||
) {
|
||||
fun toMomentItem(): MomentEntity {
|
||||
return MomentEntity(
|
||||
id = id.toInt(),
|
||||
avatar = ApiClient.BASE_SERVER + user.avatar,
|
||||
nickname = user.nickName,
|
||||
location = "Worldwide",
|
||||
time = time,
|
||||
followStatus = false,
|
||||
momentTextContent = textContent,
|
||||
momentPicture = R.drawable.default_moment_img,
|
||||
likeCount = likeCount.toInt(),
|
||||
commentCount = commentCount.toInt(),
|
||||
shareCount = 0,
|
||||
favoriteCount = favoriteCount.toInt(),
|
||||
images = images.map { ApiClient.BASE_SERVER + it.url + "?token=${AppStore.token}" },
|
||||
authorId = user.id.toInt(),
|
||||
liked = isLiked,
|
||||
isFavorite = isFavorite
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Image(
|
||||
@SerializedName("id")
|
||||
val id: Long,
|
||||
@SerializedName("url")
|
||||
val url: String,
|
||||
@SerializedName("thumbnail")
|
||||
val thumbnail: String
|
||||
)
|
||||
|
||||
data class User(
|
||||
@SerializedName("id")
|
||||
val id: Long,
|
||||
@SerializedName("nickName")
|
||||
val nickName: String,
|
||||
@SerializedName("avatar")
|
||||
val avatar: String
|
||||
)
|
||||
data class UploadImage(
|
||||
val file: File,
|
||||
val filename: String,
|
||||
val url: String,
|
||||
val ext: String
|
||||
)
|
||||
interface MomentService {
|
||||
suspend fun getMomentById(id: Int): MomentItem
|
||||
suspend fun getMomentById(id: Int): MomentEntity
|
||||
suspend fun likeMoment(id: Int)
|
||||
suspend fun dislikeMoment(id: Int)
|
||||
suspend fun getMoments(
|
||||
pageNumber: Int,
|
||||
author: Int? = null,
|
||||
timelineId: Int? = null
|
||||
): ListContainer<MomentItem>
|
||||
): ListContainer<MomentEntity>
|
||||
|
||||
suspend fun createMoment(
|
||||
content: String,
|
||||
authorId: Int,
|
||||
imageUriList: List<String>,
|
||||
images: List<UploadImage>,
|
||||
relPostId: Int? = null
|
||||
): MomentItem
|
||||
): MomentEntity
|
||||
suspend fun favoriteMoment(id: Int)
|
||||
suspend fun unfavoriteMoment(id: Int)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +112,8 @@ class MomentPagingSource(
|
||||
private val remoteDataSource: MomentRemoteDataSource,
|
||||
private val author: Int? = null,
|
||||
private val timelineId: Int? = null
|
||||
) : PagingSource<Int, MomentItem>() {
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MomentItem> {
|
||||
) : PagingSource<Int, MomentEntity>() {
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MomentEntity> {
|
||||
return try {
|
||||
val currentPage = params.key ?: 1
|
||||
val moments = remoteDataSource.getMoments(
|
||||
@@ -51,7 +132,7 @@ class MomentPagingSource(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRefreshKey(state: PagingState<Int, MomentItem>): Int? {
|
||||
override fun getRefreshKey(state: PagingState<Int, MomentEntity>): Int? {
|
||||
return state.anchorPosition
|
||||
}
|
||||
|
||||
@@ -64,7 +145,7 @@ class MomentRemoteDataSource(
|
||||
pageNumber: Int,
|
||||
author: Int?,
|
||||
timelineId: Int?
|
||||
): ListContainer<MomentItem> {
|
||||
): ListContainer<MomentEntity> {
|
||||
return momentService.getMoments(pageNumber, author, timelineId)
|
||||
}
|
||||
}
|
||||
@@ -77,11 +158,11 @@ class TestMomentServiceImpl() : MomentService {
|
||||
pageNumber: Int,
|
||||
author: Int?,
|
||||
timelineId: Int?
|
||||
): ListContainer<MomentItem> {
|
||||
): ListContainer<MomentEntity> {
|
||||
return testMomentBackend.fetchMomentItems(pageNumber, author, timelineId)
|
||||
}
|
||||
|
||||
override suspend fun getMomentById(id: Int): MomentItem {
|
||||
override suspend fun getMomentById(id: Int): MomentEntity {
|
||||
return testMomentBackend.getMomentById(id)
|
||||
}
|
||||
|
||||
@@ -97,10 +178,18 @@ class TestMomentServiceImpl() : MomentService {
|
||||
override suspend fun createMoment(
|
||||
content: String,
|
||||
authorId: Int,
|
||||
imageUriList: List<String>,
|
||||
images: List<UploadImage>,
|
||||
relPostId: Int?
|
||||
): MomentItem {
|
||||
return testMomentBackend.createMoment(content, authorId, imageUriList, relPostId)
|
||||
): MomentEntity {
|
||||
return testMomentBackend.createMoment(content, authorId, images, relPostId)
|
||||
}
|
||||
|
||||
override suspend fun favoriteMoment(id: Int) {
|
||||
testMomentBackend.favoriteMoment(id)
|
||||
}
|
||||
|
||||
override suspend fun unfavoriteMoment(id: Int) {
|
||||
testMomentBackend.unfavoriteMoment(id)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -113,110 +202,63 @@ class TestMomentBackend(
|
||||
pageNumber: Int,
|
||||
author: Int? = null,
|
||||
timelineId: Int?
|
||||
): ListContainer<MomentItem> {
|
||||
var rawList = TestDatabase.momentData
|
||||
rawList = rawList.sortedBy { it.id }.reversed()
|
||||
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 || it.authorId == 1 }
|
||||
}
|
||||
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))
|
||||
currentSublist.forEach {
|
||||
val myLikeIdList =
|
||||
TestDatabase.likeMomentList.filter { it.second == 1 }.map { it.first }
|
||||
if (myLikeIdList.contains(it.id)) {
|
||||
it.liked = true
|
||||
}
|
||||
if (it.relPostId != null) {
|
||||
it.relMoment = rawList.first { it1 -> it1.id == it.relPostId }
|
||||
}
|
||||
}
|
||||
|
||||
// delay
|
||||
kotlinx.coroutines.delay(loadDelay)
|
||||
): ListContainer<MomentEntity> {
|
||||
val resp = ApiClient.api.getPosts(
|
||||
pageSize = DataBatchSize,
|
||||
page = pageNumber,
|
||||
timelineId = timelineId,
|
||||
authorId = author
|
||||
)
|
||||
val body = resp.body() ?: throw ServiceException("Failed to get moments")
|
||||
return ListContainer(
|
||||
total = rawList.size,
|
||||
total = body.total,
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
list = currentSublist
|
||||
list = body.list.map { it.toMomentItem() }
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getMomentById(id: Int): MomentItem {
|
||||
var moment = TestDatabase.momentData.first {
|
||||
it.id == id
|
||||
}
|
||||
val isLike = TestDatabase.likeMomentList.any {
|
||||
it.first == id && it.second == 1
|
||||
}
|
||||
moment = moment.copy(liked = isLike)
|
||||
return moment
|
||||
suspend fun getMomentById(id: Int): MomentEntity {
|
||||
var resp = ApiClient.api.getPost(id)
|
||||
var body = resp.body()?.data ?: throw ServiceException("Failed to get moment")
|
||||
return body.toMomentItem()
|
||||
}
|
||||
|
||||
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)
|
||||
TestDatabase.likeMomentList += Pair(id, 1)
|
||||
ApiClient.api.likePost(id)
|
||||
}
|
||||
|
||||
suspend fun dislikeMoment(id: Int) {
|
||||
val oldMoment = TestDatabase.momentData.first {
|
||||
it.id == id
|
||||
}
|
||||
val newMoment = oldMoment.copy(likeCount = oldMoment.likeCount - 1)
|
||||
TestDatabase.updateMomentById(id, newMoment)
|
||||
TestDatabase.likeMomentList = TestDatabase.likeMomentList.filter {
|
||||
it.first != id
|
||||
}
|
||||
ApiClient.api.dislikePost(id)
|
||||
}
|
||||
|
||||
fun createMultipartBody(file: File, name: String): MultipartBody.Part {
|
||||
val requestFile = RequestBody.create("image/*".toMediaTypeOrNull(), file)
|
||||
return MultipartBody.Part.createFormData(name, file.name, requestFile)
|
||||
}
|
||||
|
||||
suspend fun createMoment(
|
||||
content: String,
|
||||
authorId: Int,
|
||||
imageUriList: List<String>,
|
||||
imageUriList: List<UploadImage>,
|
||||
relPostId: Int?
|
||||
): MomentItem {
|
||||
TestDatabase.momentIdCounter += 1
|
||||
val person = TestDatabase.accountData.first {
|
||||
it.id == authorId
|
||||
): MomentEntity {
|
||||
val textContent = content.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val imageList = imageUriList.map { item ->
|
||||
val file = item.file
|
||||
createMultipartBody(file, "image")
|
||||
}
|
||||
val newMoment = MomentItem(
|
||||
id = TestDatabase.momentIdCounter,
|
||||
avatar = person.avatar,
|
||||
nickname = person.nickName,
|
||||
location = person.country,
|
||||
time = "2023.02.02 11:23",
|
||||
followStatus = false,
|
||||
momentTextContent = content,
|
||||
momentPicture = R.drawable.default_moment_img,
|
||||
likeCount = 0,
|
||||
commentCount = 0,
|
||||
shareCount = 0,
|
||||
favoriteCount = 0,
|
||||
images = imageUriList,
|
||||
authorId = person.id,
|
||||
relPostId = relPostId
|
||||
)
|
||||
TestDatabase.momentData += newMoment
|
||||
return newMoment
|
||||
val response = ApiClient.api.createPost(imageList, textContent = textContent)
|
||||
val body = response.body()?.data ?: throw ServiceException("Failed to create moment")
|
||||
return body.toMomentItem()
|
||||
|
||||
}
|
||||
|
||||
suspend fun favoriteMoment(id: Int) {
|
||||
ApiClient.api.favoritePost(id)
|
||||
}
|
||||
suspend fun unfavoriteMoment(id: Int) {
|
||||
ApiClient.api.unfavoritePost(id)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user