feat: implement delivery status updates and enhance file size limit for uploads

This commit is contained in:
2026-02-06 03:17:22 +05:00
parent 0bd8cb39ab
commit dcc719ec56
7 changed files with 115 additions and 23 deletions

View File

@@ -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
}

View File

@@ -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