Правки
This commit is contained in:
@@ -6,6 +6,8 @@ import androidx.hilt.work.HiltWorker
|
||||
import androidx.work.*
|
||||
import chats.data.local.dao.ChatDao
|
||||
import chats.data.local.dao.MessageDao
|
||||
import chats.data.remote.dto.*
|
||||
import chats.data.repository.toDomain
|
||||
import chats.domain.model.MessageStatus
|
||||
import core.security.TokenManager
|
||||
import dagger.assisted.Assisted
|
||||
@@ -27,7 +29,8 @@ class ChatSyncWorker @AssistedInject constructor(
|
||||
private val chatDao: ChatDao,
|
||||
private val messageDao: MessageDao,
|
||||
private val chatApi: chats.data.remote.api.ChatApi,
|
||||
private val tokenManager: TokenManager
|
||||
private val tokenManager: TokenManager,
|
||||
private val serverConfig: core.network.ServerConfig
|
||||
) : CoroutineWorker(context, params) {
|
||||
|
||||
companion object {
|
||||
@@ -104,6 +107,9 @@ class ChatSyncWorker @AssistedInject constructor(
|
||||
private suspend fun syncChats() {
|
||||
val remoteChats = chatApi.getChats()
|
||||
val localChats = mutableListOf<chats.data.local.database.ChatEntity>()
|
||||
val currentUserId = tokenManager.getUserId() ?: ""
|
||||
val baseUrl = serverConfig.getBaseUrl().removeSuffix("/api/")
|
||||
val gson = com.google.gson.Gson()
|
||||
|
||||
remoteChats.forEach { dto ->
|
||||
val existingChat = chatDao.getChatByRemoteId(dto.id)
|
||||
@@ -112,6 +118,7 @@ class ChatSyncWorker @AssistedInject constructor(
|
||||
try { java.time.ZonedDateTime.parse(it).toInstant().toEpochMilli() }
|
||||
catch (e: Exception) { null }
|
||||
}
|
||||
val lastMessageDomain = lastMessage?.toDomain(currentUserId, baseUrl)
|
||||
val chatEntity = chats.data.local.database.ChatEntity(
|
||||
localId = existingChat?.localId ?: java.util.UUID.randomUUID().toString(),
|
||||
remoteId = dto.id,
|
||||
@@ -120,11 +127,40 @@ class ChatSyncWorker @AssistedInject constructor(
|
||||
avatar = dto.avatar,
|
||||
unreadCount = dto.unreadCount,
|
||||
lastMessageText = lastMessage?.content,
|
||||
lastMessageTimestamp = timestamp
|
||||
lastMessageTimestamp = timestamp,
|
||||
lastMessageJson = lastMessageDomain?.let { gson.toJson(it) }
|
||||
)
|
||||
localChats.add(chatEntity)
|
||||
}
|
||||
|
||||
// Если сервер не вернул Избранное — создаём/получаем его отдельно
|
||||
val hasFavorites = remoteChats.any { it.type == "favorites" }
|
||||
if (!hasFavorites) {
|
||||
try {
|
||||
val favDto = chatApi.getOrCreateFavorites()
|
||||
val existingChat = chatDao.getChatByRemoteId(favDto.id)
|
||||
val favTimestamp = favDto.messages.firstOrNull()?.createdAt?.let {
|
||||
try { java.time.ZonedDateTime.parse(it).toInstant().toEpochMilli() } catch (e: Exception) { null }
|
||||
}
|
||||
val favLastMessageDomain = favDto.messages.firstOrNull()?.toDomain(currentUserId, baseUrl)
|
||||
val favEntity = chats.data.local.database.ChatEntity(
|
||||
localId = existingChat?.localId ?: java.util.UUID.randomUUID().toString(),
|
||||
remoteId = favDto.id,
|
||||
type = favDto.type,
|
||||
name = favDto.name ?: "Избранное",
|
||||
avatar = favDto.avatar,
|
||||
unreadCount = favDto.unreadCount,
|
||||
lastMessageText = favDto.messages.firstOrNull()?.content,
|
||||
lastMessageTimestamp = favTimestamp,
|
||||
lastMessageJson = favLastMessageDomain?.let { gson.toJson(it) }
|
||||
)
|
||||
localChats.add(favEntity)
|
||||
Log.d("ChatSyncWorker", "Created favorites chat: ${favDto.id}")
|
||||
} catch (e: Exception) {
|
||||
Log.e("ChatSyncWorker", "Failed to get or create favorites", e)
|
||||
}
|
||||
}
|
||||
|
||||
chatDao.insertChats(localChats)
|
||||
Log.d("ChatSyncWorker", "Synced ${localChats.size} chats")
|
||||
}
|
||||
@@ -150,6 +186,7 @@ class ChatSyncWorker @AssistedInject constructor(
|
||||
) {
|
||||
val currentUserId = tokenManager.getUserId() ?: ""
|
||||
val gson = com.google.gson.Gson()
|
||||
val baseUrl = serverConfig.getBaseUrl().removeSuffix("/api/")
|
||||
|
||||
messages.forEach { dto ->
|
||||
val existing = messageDao.getMessageByServerId(dto.id)
|
||||
@@ -161,19 +198,19 @@ class ChatSyncWorker @AssistedInject constructor(
|
||||
chatId = chatId,
|
||||
senderId = dto.senderId ?: dto.sender?.id ?: currentUserId,
|
||||
senderName = dto.sender?.displayName ?: dto.sender?.username ?: "",
|
||||
senderAvatar = dto.sender?.avatarUrl,
|
||||
senderAvatar = dto.sender?.avatarUrl?.let { if (it.startsWith("http")) it else "$baseUrl$it" },
|
||||
content = dto.content,
|
||||
sequenceId = dto.sequenceId?.toLong() ?: 0L,
|
||||
createdAt = dto.createdAt ?: java.time.ZonedDateTime.now().toString(),
|
||||
mediaType = dto.type ?: "TEXT",
|
||||
mediaJson = gson.toJson(dto.media.map {
|
||||
mediaJson = gson.toJson(dto.media.map { mediaItem ->
|
||||
chats.domain.model.Media(
|
||||
id = it.id,
|
||||
type = it.type,
|
||||
url = it.url,
|
||||
filename = it.filename,
|
||||
size = it.size,
|
||||
duration = it.duration
|
||||
id = mediaItem.id,
|
||||
type = mediaItem.type,
|
||||
url = (mediaItem.url as? String ?: "").let { url -> if (url.startsWith("http")) url else "$baseUrl$url" },
|
||||
filename = mediaItem.filename,
|
||||
size = mediaItem.size,
|
||||
duration = mediaItem.duration
|
||||
)
|
||||
}),
|
||||
reactionsJson = gson.toJson(
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.hilt.work.HiltWorker
|
||||
import androidx.work.*
|
||||
import chats.data.local.dao.MessageDao
|
||||
import chats.data.local.database.MessageEntity
|
||||
import chats.data.remote.api.AttachmentRequest
|
||||
import chats.data.remote.api.ChatApi
|
||||
import chats.data.remote.api.SendMessageRequest
|
||||
import chats.domain.model.MessageStatus
|
||||
@@ -99,9 +100,28 @@ class SendMessageWorker @AssistedInject constructor(
|
||||
)
|
||||
|
||||
// Выполняем запрос к API с Idempotency-Key
|
||||
// Десериализуем media из JSON
|
||||
val mediaList = try {
|
||||
val gson = com.google.gson.Gson()
|
||||
val type = object : com.google.gson.reflect.TypeToken<List<chats.domain.model.Media>>() {}.type
|
||||
gson.fromJson<List<chats.domain.model.Media>>(message.mediaJson, type) ?: emptyList()
|
||||
} catch (e: Exception) {
|
||||
emptyList<chats.domain.model.Media>()
|
||||
}
|
||||
|
||||
val attachments = mediaList.map {
|
||||
AttachmentRequest(
|
||||
type = it.type,
|
||||
url = it.url,
|
||||
fileName = it.filename ?: "",
|
||||
fileSize = it.size ?: 0L
|
||||
)
|
||||
}.takeIf { it.isNotEmpty() }
|
||||
|
||||
val request = SendMessageRequest(
|
||||
content = message.content,
|
||||
type = message.mediaType.lowercase(),
|
||||
attachments = attachments,
|
||||
replyToId = message.replyToServerId
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user