97 lines
3.1 KiB
Kotlin
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
|
|
}
|
|
)
|