feat: implement delivery status updates and enhance file size limit for uploads
This commit is contained in:
@@ -249,8 +249,9 @@ enum class AttachmentType(val value: Int) {
|
||||
enum class DeliveryStatus(val value: Int) {
|
||||
WAITING(0), // Ожидает отправки
|
||||
DELIVERED(1), // Доставлено
|
||||
ERROR(2); // Ошибка
|
||||
|
||||
ERROR(2), // Ошибка
|
||||
READ(3); // Прочитано
|
||||
|
||||
companion object {
|
||||
fun fromInt(value: Int) = entries.firstOrNull { it.value == value } ?: WAITING
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ object TransportManager {
|
||||
val downloading: StateFlow<List<TransportState>> = _downloading.asStateFlow()
|
||||
|
||||
private val client = OkHttpClient.Builder()
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
.connectTimeout(60, TimeUnit.SECONDS)
|
||||
.readTimeout(5, TimeUnit.MINUTES) // 5 минут для больших файлов
|
||||
.writeTimeout(5, TimeUnit.MINUTES) // 5 минут для больших файлов
|
||||
.build()
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ object TransportManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузить файл на транспортный сервер
|
||||
* Загрузить файл на транспортный сервер с отслеживанием прогресса
|
||||
* @param id Уникальный ID файла
|
||||
* @param content Содержимое файла (base64 или бинарные данные)
|
||||
* @return Tag для скачивания файла
|
||||
@@ -84,21 +84,43 @@ object TransportManager {
|
||||
suspend fun uploadFile(id: String, content: String): String = withContext(Dispatchers.IO) {
|
||||
val server = getActiveServer()
|
||||
|
||||
|
||||
// Добавляем в список загрузок
|
||||
_uploading.value = _uploading.value + TransportState(id, 0)
|
||||
|
||||
try {
|
||||
// 🔥 КРИТИЧНО: Преобразуем строку в байты (как desktop делает new Blob([content]))
|
||||
val contentBytes = content.toByteArray(Charsets.UTF_8)
|
||||
val totalSize = contentBytes.size.toLong()
|
||||
|
||||
// 🔥 RequestBody с отслеживанием прогресса загрузки
|
||||
val progressRequestBody = object : RequestBody() {
|
||||
override fun contentType() = "application/octet-stream".toMediaType()
|
||||
override fun contentLength() = totalSize
|
||||
|
||||
override fun writeTo(sink: okio.BufferedSink) {
|
||||
val source = okio.Buffer().write(contentBytes)
|
||||
var uploaded = 0L
|
||||
val bufferSize = 8 * 1024L // 8 KB chunks
|
||||
|
||||
while (true) {
|
||||
val read = source.read(sink.buffer, bufferSize)
|
||||
if (read == -1L) break
|
||||
|
||||
uploaded += read
|
||||
sink.flush()
|
||||
|
||||
// Обновляем прогресс
|
||||
val progress = ((uploaded * 100) / totalSize).toInt()
|
||||
_uploading.value = _uploading.value.map {
|
||||
if (it.id == id) it.copy(progress = progress) else it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val requestBody = MultipartBody.Builder()
|
||||
.setType(MultipartBody.FORM)
|
||||
.addFormDataPart(
|
||||
"file",
|
||||
id,
|
||||
contentBytes.toRequestBody("application/octet-stream".toMediaType())
|
||||
)
|
||||
.addFormDataPart("file", id, progressRequestBody)
|
||||
.build()
|
||||
|
||||
val request = Request.Builder()
|
||||
@@ -126,11 +148,9 @@ object TransportManager {
|
||||
val responseBody = response.body?.string()
|
||||
?: throw IOException("Empty response")
|
||||
|
||||
|
||||
// Parse JSON response to get tag
|
||||
val tag = org.json.JSONObject(responseBody).getString("t")
|
||||
|
||||
|
||||
// Обновляем прогресс до 100%
|
||||
_uploading.value = _uploading.value.map {
|
||||
if (it.id == id) it.copy(progress = 100) else it
|
||||
|
||||
Reference in New Issue
Block a user