temp progress on binary correct including
This commit is contained in:
@@ -7,6 +7,8 @@ import dev.inmo.micro_utils.ktor.common.encodeHex
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.createRouting
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.updateRouting
|
||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.removeRoute
|
||||
import dev.inmo.postssystem.features.common.common.FileBasedInputProvider
|
||||
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
|
||||
import dev.inmo.postssystem.features.content.common.*
|
||||
import dev.inmo.postssystem.features.posts.common.PostId
|
||||
import dev.inmo.postssystem.features.posts.common.RegisteredPost
|
||||
@@ -20,9 +22,15 @@ import kotlinx.serialization.builtins.*
|
||||
|
||||
class ClientWritePostsService(
|
||||
private val baseUrl: String,
|
||||
private val unifiedRequester: UnifiedRequester
|
||||
unifiedRequester: UnifiedRequester
|
||||
) : WritePostsService {
|
||||
private val root = buildStandardUrl(baseUrl, postsRootPath)
|
||||
private val unifiedRequester = UnifiedRequester(
|
||||
unifiedRequester.client,
|
||||
unifiedRequester.serialFormat.createWithSerializerModuleExtension {
|
||||
contextual()
|
||||
}
|
||||
)
|
||||
|
||||
private val contentEitherSerializer = EitherSerializer(ContentId.serializer(), ContentSerializer)
|
||||
private val contentsEitherSerializer = ListSerializer(contentEitherSerializer)
|
||||
@@ -36,83 +44,59 @@ class ClientWritePostsService(
|
||||
root,
|
||||
removeRoute
|
||||
)
|
||||
private val tempUploadFullPath = buildStandardUrl(
|
||||
baseUrl,
|
||||
postsCreateTempPathPart
|
||||
)
|
||||
|
||||
private suspend fun prepareContent(content: Content): Content? {
|
||||
return (content as? BinaryContent) ?.let {
|
||||
when (val provider = it.inputProvider) {
|
||||
is FileBasedInputProvider -> {
|
||||
val fileId = unifiedRequester.tempUpload(
|
||||
tempUploadFullPath,
|
||||
provider.file
|
||||
)
|
||||
it.copy(inputProvider = TempFileIdentifierInputProvider(fileId))
|
||||
}
|
||||
is TempFileIdentifierInputProvider -> it
|
||||
else -> return@prepareContent null
|
||||
}
|
||||
} ?: content
|
||||
}
|
||||
|
||||
override suspend fun create(newPost: FullNewPost): RegisteredPost? {
|
||||
return if (newPost.content.any { it is BinaryContent }) {
|
||||
val answer = unifiedRequester.client.post<ByteArray>(createFullPath) {
|
||||
formData {
|
||||
newPost.content.forEachIndexed { i, content ->
|
||||
when (content) {
|
||||
is BinaryContent -> append(
|
||||
i.toString(),
|
||||
InputProvider(block = content.inputProvider::invoke),
|
||||
headers {
|
||||
append(HttpHeaders.ContentType, content.mimeType.raw)
|
||||
append(HttpHeaders.ContentDisposition, "filename=\"${content.filename.name}\"")
|
||||
}.build()
|
||||
)
|
||||
else -> append(
|
||||
i.toString(),
|
||||
unifiedRequester.serialFormat.encodeHex(ContentSerializer, content)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unifiedRequester.serialFormat.decodeFromByteArray(RegisteredPost.serializer().nullable, answer)
|
||||
} else {
|
||||
unifiedRequester.unipost(
|
||||
createFullPath,
|
||||
contentsSerializer to newPost.content,
|
||||
RegisteredPost.serializer().nullable
|
||||
)
|
||||
val mappedContent = newPost.content.mapNotNull {
|
||||
prepareContent(it)
|
||||
}
|
||||
val mappedPost = newPost.copy(
|
||||
content = mappedContent
|
||||
)
|
||||
return unifiedRequester.unipost(
|
||||
createFullPath,
|
||||
contentsSerializer to mappedPost.content,
|
||||
RegisteredPost.serializer().nullable
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun update(
|
||||
postId: PostId,
|
||||
content: List<Either<ContentId, Content>>
|
||||
): RegisteredPost? {
|
||||
return if (content.any { it.optionalT2.data is BinaryContent }) {
|
||||
val answer = unifiedRequester.client.post<ByteArray>(createFullPath) {
|
||||
formData {
|
||||
content.forEachIndexed { i, eitherContent ->
|
||||
eitherContent.onFirst {
|
||||
append(
|
||||
i.toString(),
|
||||
unifiedRequester.serialFormat.encodeHex(contentEitherSerializer, it.either())
|
||||
)
|
||||
}.onSecond {
|
||||
when (it) {
|
||||
is BinaryContent -> append(
|
||||
i.toString(),
|
||||
InputProvider(block = it.inputProvider::invoke),
|
||||
headers {
|
||||
append(HttpHeaders.ContentType, it.mimeType.raw)
|
||||
append(HttpHeaders.ContentDisposition, "filename=\"${it.filename.name}\"")
|
||||
}.build()
|
||||
)
|
||||
else -> append(
|
||||
i.toString(),
|
||||
unifiedRequester.serialFormat.encodeHex(contentEitherSerializer, it.either())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unifiedRequester.serialFormat.decodeFromByteArray(RegisteredPost.serializer().nullable, answer)
|
||||
} else {
|
||||
unifiedRequester.unipost(
|
||||
buildStandardUrl(
|
||||
root,
|
||||
updateRouting,
|
||||
postsPostIdParameter to unifiedRequester.encodeUrlQueryValue(PostId.serializer(), postId)
|
||||
),
|
||||
contentsEitherSerializer to content,
|
||||
RegisteredPost.serializer().nullable
|
||||
)
|
||||
val mappedContent = content.mapNotNull {
|
||||
it.mapOnSecond { content ->
|
||||
prepareContent(content) ?.either() ?: return@mapNotNull null
|
||||
} ?: it
|
||||
}
|
||||
return unifiedRequester.unipost(
|
||||
buildStandardUrl(
|
||||
root,
|
||||
updateRouting,
|
||||
postsPostIdParameter to unifiedRequester.encodeUrlQueryValue(PostId.serializer(), postId)
|
||||
),
|
||||
contentsEitherSerializer to mappedContent,
|
||||
RegisteredPost.serializer().nullable
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun remove(postId: PostId) = unifiedRequester.unipost(
|
||||
|
@@ -0,0 +1,15 @@
|
||||
package dev.inmo.postssystem.services.posts.client
|
||||
|
||||
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
|
||||
import dev.inmo.postssystem.features.files.common.FileId
|
||||
import io.ktor.utils.io.core.Input
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal data class TempFileIdentifierInputProvider(
|
||||
private val tempFile: FileId
|
||||
) : SimpleInputProvider {
|
||||
override fun invoke(): Input {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package dev.inmo.postssystem.services.posts.client
|
||||
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
|
||||
import dev.inmo.postssystem.features.files.common.FileId
|
||||
|
||||
internal expect suspend fun UnifiedRequester.tempUpload(
|
||||
fullTempUploadDraftPath: String,
|
||||
file: MPPFile,
|
||||
onUpload: (Long, Long) -> Unit = { _, _ -> }
|
||||
): FileId
|
||||
|
@@ -0,0 +1,8 @@
|
||||
package dev.inmo.postssystem.services.posts.client.ui.create
|
||||
|
||||
import dev.inmo.postssystem.features.common.common.UIModel
|
||||
import dev.inmo.postssystem.features.content.common.Content
|
||||
|
||||
interface PostCreateUIModel : UIModel<PostCreateUIState> {
|
||||
suspend fun create(content: List<Content>)
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package dev.inmo.postssystem.services.posts.client.ui.create
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed class PostCreateUIState {
|
||||
@Serializable
|
||||
object Init : PostCreateUIState()
|
||||
@Serializable
|
||||
object Uploading : PostCreateUIState()
|
||||
@Serializable
|
||||
object Completed : PostCreateUIState()
|
||||
|
||||
}
|
Reference in New Issue
Block a user