Files
forkmessager/client-mobile/chats/data/repository/ChatRepositoryImpl.kt
2026-04-14 01:41:51 +03:00

97 lines
3.1 KiB
Kotlin

package chats.data.repository
import chats.data.remote.api.ChatApi
import chats.data.remote.api.SendMessageRequest
import chats.data.remote.dto.ChatDto
import chats.data.remote.dto.MessageDto
import chats.domain.model.Chat
import chats.domain.model.Message
import chats.domain.model.MediaType
import chats.domain.repository.ChatRepository
import core.security.TokenManager
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import javax.inject.Inject
class ChatRepositoryImpl @Inject constructor(
private val api: ChatApi,
private val tokenManager: TokenManager
) : ChatRepository {
override suspend fun getChats(): List<Chat> {
val currentUserId = tokenManager.getUserId() ?: ""
return api.getChats().map { it.toDomain(currentUserId) }
}
override suspend fun getMessages(chatId: String): List<Message> {
return api.getMessages(chatId).map { it.toDomain() }
}
override suspend fun sendMessage(chatId: String, content: String): Message {
val request = SendMessageRequest(content = content, type = "text")
return api.sendMessage(chatId, request).toDomain()
}
override suspend fun addReaction(messageId: String, emoji: String) {
api.addReaction(messageId, emoji)
}
override suspend fun sendTypingStatus(chatId: String) {
api.sendTypingStatus(chatId)
}
override suspend fun markMessagesAsRead(chatId: String, lastMessageId: String) {
api.markMessagesAsRead(chatId, lastMessageId)
}
override suspend fun uploadMedia(file: java.io.File): String {
val requestFile = file.asRequestBody("image/*".toMediaTypeOrNull())
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
return api.uploadFile(body).url
}
}
// Mappers
fun ChatDto.toDomain(currentUserId: String): Chat {
// Если это личный чат и имя пустое, ищем имя собеседника в списке участников
val chatName = name ?: if (type == "personal") {
members.firstOrNull { it.userId != currentUserId }?.user?.displayName ?: "Unknown Chat"
} else "Group Chat"
val chatAvatar = avatar ?: if (type == "personal") {
members.firstOrNull { it.userId != currentUserId }?.user?.avatarUrl
} else null
return Chat(
id = id,
type = type,
name = chatName,
avatar = chatAvatar,
unreadCount = unreadCount,
lastMessage = messages.firstOrNull()?.toDomain()
)
}
fun MessageDto.toDomain(): Message = Message(
id = id,
chatId = chatId,
senderId = senderId,
senderName = sender.displayName,
content = content,
sequenceId = sequenceId,
createdAt = createdAt,
media = media.map { it.url },
mediaUrl = media.firstOrNull()?.url,
mediaType = when (media.firstOrNull()?.type) {
"image" -> MediaType.IMAGE
"video" -> MediaType.VIDEO
"audio" -> MediaType.AUDIO
"file" -> MediaType.FILE
else -> MediaType.TEXT
}
)