android: add message api contracts and repository usecases
Some checks are pending
CI / test (push) Has started running
Some checks are pending
CI / test (push) Has started running
This commit is contained in:
@@ -71,3 +71,10 @@
|
|||||||
- Added `MessageDao` with observe/pagination/upsert/delete APIs.
|
- Added `MessageDao` with observe/pagination/upsert/delete APIs.
|
||||||
- Updated `MessengerDatabase` schema to include message tables and DAO.
|
- Updated `MessengerDatabase` schema to include message tables and DAO.
|
||||||
- Added Hilt DI provider for `MessageDao`.
|
- Added Hilt DI provider for `MessageDao`.
|
||||||
|
|
||||||
|
### Step 12 - Sprint A / 2) Message API + repository
|
||||||
|
- Added message REST API client for history/send/edit/delete endpoints.
|
||||||
|
- Added message DTOs and mappers (`MessageReadDto -> MessageEntity -> MessageItem`).
|
||||||
|
- Added `MessageRepository` contracts/use-cases for observe/sync/pagination/send/edit/delete.
|
||||||
|
- Implemented `NetworkMessageRepository` with cache-first observation and optimistic text send.
|
||||||
|
- Wired message API and repository into Hilt modules.
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package ru.daemonlord.messenger.data.message.api
|
||||||
|
|
||||||
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.DELETE
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.POST
|
||||||
|
import retrofit2.http.PUT
|
||||||
|
import retrofit2.http.Path
|
||||||
|
import retrofit2.http.Query
|
||||||
|
import ru.daemonlord.messenger.data.message.dto.MessageCreateRequestDto
|
||||||
|
import ru.daemonlord.messenger.data.message.dto.MessageReadDto
|
||||||
|
import ru.daemonlord.messenger.data.message.dto.MessageUpdateRequestDto
|
||||||
|
|
||||||
|
interface MessageApiService {
|
||||||
|
@GET("/api/v1/messages/{chat_id}")
|
||||||
|
suspend fun getMessages(
|
||||||
|
@Path("chat_id") chatId: Long,
|
||||||
|
@Query("limit") limit: Int = 50,
|
||||||
|
@Query("before_id") beforeId: Long? = null,
|
||||||
|
): List<MessageReadDto>
|
||||||
|
|
||||||
|
@POST("/api/v1/messages")
|
||||||
|
suspend fun sendMessage(
|
||||||
|
@Body request: MessageCreateRequestDto,
|
||||||
|
): MessageReadDto
|
||||||
|
|
||||||
|
@PUT("/api/v1/messages/{message_id}")
|
||||||
|
suspend fun editMessage(
|
||||||
|
@Path("message_id") messageId: Long,
|
||||||
|
@Body request: MessageUpdateRequestDto,
|
||||||
|
): MessageReadDto
|
||||||
|
|
||||||
|
@DELETE("/api/v1/messages/{message_id}")
|
||||||
|
suspend fun deleteMessage(
|
||||||
|
@Path("message_id") messageId: Long,
|
||||||
|
@Query("for_all") forAll: Boolean = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package ru.daemonlord.messenger.data.message.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MessageReadDto(
|
||||||
|
val id: Long,
|
||||||
|
@SerialName("chat_id")
|
||||||
|
val chatId: Long,
|
||||||
|
@SerialName("sender_id")
|
||||||
|
val senderId: Long,
|
||||||
|
@SerialName("reply_to_message_id")
|
||||||
|
val replyToMessageId: Long? = null,
|
||||||
|
val type: String,
|
||||||
|
val text: String? = null,
|
||||||
|
@SerialName("delivery_status")
|
||||||
|
val deliveryStatus: String? = null,
|
||||||
|
@SerialName("created_at")
|
||||||
|
val createdAt: String,
|
||||||
|
@SerialName("updated_at")
|
||||||
|
val updatedAt: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MessageCreateRequestDto(
|
||||||
|
@SerialName("chat_id")
|
||||||
|
val chatId: Long,
|
||||||
|
val type: String,
|
||||||
|
val text: String,
|
||||||
|
@SerialName("client_message_id")
|
||||||
|
val clientMessageId: String,
|
||||||
|
@SerialName("reply_to_message_id")
|
||||||
|
val replyToMessageId: Long? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MessageUpdateRequestDto(
|
||||||
|
val text: String,
|
||||||
|
)
|
||||||
@@ -52,6 +52,25 @@ interface MessageDao {
|
|||||||
@Query("DELETE FROM messages WHERE id = :messageId")
|
@Query("DELETE FROM messages WHERE id = :messageId")
|
||||||
suspend fun deleteMessage(messageId: Long)
|
suspend fun deleteMessage(messageId: Long)
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"""
|
||||||
|
UPDATE messages
|
||||||
|
SET text = :text,
|
||||||
|
updated_at = :updatedAt
|
||||||
|
WHERE id = :messageId
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
suspend fun updateMessageText(messageId: Long, text: String?, updatedAt: String?)
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"""
|
||||||
|
UPDATE messages
|
||||||
|
SET status = :status
|
||||||
|
WHERE id = :messageId
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
suspend fun updateMessageStatus(messageId: Long, status: String?)
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
suspend fun clearAndReplaceMessages(
|
suspend fun clearAndReplaceMessages(
|
||||||
chatId: Long,
|
chatId: Long,
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package ru.daemonlord.messenger.data.message.mapper
|
||||||
|
|
||||||
|
import ru.daemonlord.messenger.data.message.dto.MessageReadDto
|
||||||
|
import ru.daemonlord.messenger.data.message.local.entity.MessageEntity
|
||||||
|
import ru.daemonlord.messenger.domain.message.model.MessageItem
|
||||||
|
|
||||||
|
fun MessageReadDto.toEntity(): MessageEntity {
|
||||||
|
return MessageEntity(
|
||||||
|
id = id,
|
||||||
|
chatId = chatId,
|
||||||
|
senderId = senderId,
|
||||||
|
senderDisplayName = null,
|
||||||
|
senderUsername = null,
|
||||||
|
senderAvatarUrl = null,
|
||||||
|
replyToMessageId = replyToMessageId,
|
||||||
|
type = type,
|
||||||
|
text = text,
|
||||||
|
status = deliveryStatus,
|
||||||
|
createdAt = createdAt,
|
||||||
|
updatedAt = updatedAt,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MessageEntity.toDomain(currentUserId: Long?): MessageItem {
|
||||||
|
return MessageItem(
|
||||||
|
id = id,
|
||||||
|
chatId = chatId,
|
||||||
|
senderId = senderId,
|
||||||
|
senderDisplayName = senderDisplayName,
|
||||||
|
type = type,
|
||||||
|
text = text,
|
||||||
|
createdAt = createdAt,
|
||||||
|
updatedAt = updatedAt,
|
||||||
|
isOutgoing = currentUserId != null && currentUserId == senderId,
|
||||||
|
status = status,
|
||||||
|
replyToMessageId = replyToMessageId,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package ru.daemonlord.messenger.data.message.repository
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import ru.daemonlord.messenger.data.chat.local.dao.ChatDao
|
||||||
|
import ru.daemonlord.messenger.data.message.api.MessageApiService
|
||||||
|
import ru.daemonlord.messenger.data.message.local.dao.MessageDao
|
||||||
|
import ru.daemonlord.messenger.data.message.local.entity.MessageEntity
|
||||||
|
import ru.daemonlord.messenger.data.message.mapper.toDomain
|
||||||
|
import ru.daemonlord.messenger.data.message.mapper.toEntity
|
||||||
|
import ru.daemonlord.messenger.di.IoDispatcher
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppError
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.model.MessageItem
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import ru.daemonlord.messenger.data.message.dto.MessageCreateRequestDto
|
||||||
|
import ru.daemonlord.messenger.data.message.dto.MessageUpdateRequestDto
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.UUID
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class NetworkMessageRepository @Inject constructor(
|
||||||
|
private val messageApiService: MessageApiService,
|
||||||
|
private val messageDao: MessageDao,
|
||||||
|
private val chatDao: ChatDao,
|
||||||
|
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
|
||||||
|
) : MessageRepository {
|
||||||
|
|
||||||
|
private val currentUserId: Long? = null
|
||||||
|
|
||||||
|
override fun observeMessages(chatId: Long): Flow<List<MessageItem>> {
|
||||||
|
return messageDao.observeRecentMessages(chatId = chatId).map { entities ->
|
||||||
|
entities.map { it.toDomain(currentUserId = currentUserId) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun syncRecentMessages(chatId: Long): AppResult<Unit> = withContext(ioDispatcher) {
|
||||||
|
try {
|
||||||
|
val remoteMessages = messageApiService.getMessages(chatId = chatId)
|
||||||
|
val messageEntities = remoteMessages.map { it.toEntity() }
|
||||||
|
messageDao.clearAndReplaceMessages(
|
||||||
|
chatId = chatId,
|
||||||
|
messages = messageEntities,
|
||||||
|
attachments = emptyList(),
|
||||||
|
)
|
||||||
|
AppResult.Success(Unit)
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
AppResult.Error(error.toAppError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun loadMoreMessages(chatId: Long, beforeMessageId: Long): AppResult<Unit> = withContext(ioDispatcher) {
|
||||||
|
try {
|
||||||
|
val page = messageApiService.getMessages(
|
||||||
|
chatId = chatId,
|
||||||
|
beforeId = beforeMessageId,
|
||||||
|
)
|
||||||
|
if (page.isNotEmpty()) {
|
||||||
|
messageDao.upsertMessages(page.map { it.toEntity() })
|
||||||
|
}
|
||||||
|
AppResult.Success(Unit)
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
AppResult.Error(error.toAppError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun sendTextMessage(
|
||||||
|
chatId: Long,
|
||||||
|
text: String,
|
||||||
|
replyToMessageId: Long?,
|
||||||
|
): AppResult<Unit> = withContext(ioDispatcher) {
|
||||||
|
val tempId = -System.currentTimeMillis()
|
||||||
|
val tempMessage = MessageEntity(
|
||||||
|
id = tempId,
|
||||||
|
chatId = chatId,
|
||||||
|
senderId = currentUserId ?: 0L,
|
||||||
|
senderDisplayName = null,
|
||||||
|
senderUsername = null,
|
||||||
|
senderAvatarUrl = null,
|
||||||
|
replyToMessageId = replyToMessageId,
|
||||||
|
type = "text",
|
||||||
|
text = text,
|
||||||
|
status = "pending",
|
||||||
|
createdAt = java.time.Instant.now().toString(),
|
||||||
|
updatedAt = null,
|
||||||
|
)
|
||||||
|
messageDao.upsertMessages(listOf(tempMessage))
|
||||||
|
chatDao.updateLastMessage(
|
||||||
|
chatId = chatId,
|
||||||
|
lastMessageText = text,
|
||||||
|
lastMessageType = "text",
|
||||||
|
lastMessageCreatedAt = tempMessage.createdAt,
|
||||||
|
updatedSortAt = tempMessage.createdAt,
|
||||||
|
)
|
||||||
|
try {
|
||||||
|
val sent = messageApiService.sendMessage(
|
||||||
|
request = MessageCreateRequestDto(
|
||||||
|
chatId = chatId,
|
||||||
|
type = "text",
|
||||||
|
text = text,
|
||||||
|
clientMessageId = UUID.randomUUID().toString(),
|
||||||
|
replyToMessageId = replyToMessageId,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
messageDao.deleteMessage(tempId)
|
||||||
|
messageDao.upsertMessages(listOf(sent.toEntity()))
|
||||||
|
chatDao.updateLastMessage(
|
||||||
|
chatId = chatId,
|
||||||
|
lastMessageText = sent.text,
|
||||||
|
lastMessageType = sent.type,
|
||||||
|
lastMessageCreatedAt = sent.createdAt,
|
||||||
|
updatedSortAt = sent.createdAt,
|
||||||
|
)
|
||||||
|
AppResult.Success(Unit)
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
messageDao.deleteMessage(tempId)
|
||||||
|
AppResult.Error(error.toAppError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun editMessage(messageId: Long, newText: String): AppResult<Unit> = withContext(ioDispatcher) {
|
||||||
|
try {
|
||||||
|
val updated = messageApiService.editMessage(
|
||||||
|
messageId = messageId,
|
||||||
|
request = MessageUpdateRequestDto(text = newText),
|
||||||
|
)
|
||||||
|
messageDao.upsertMessages(listOf(updated.toEntity()))
|
||||||
|
AppResult.Success(Unit)
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
AppResult.Error(error.toAppError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteMessage(messageId: Long, forAll: Boolean): AppResult<Unit> = withContext(ioDispatcher) {
|
||||||
|
try {
|
||||||
|
messageApiService.deleteMessage(
|
||||||
|
messageId = messageId,
|
||||||
|
forAll = forAll,
|
||||||
|
)
|
||||||
|
messageDao.deleteMessage(messageId)
|
||||||
|
AppResult.Success(Unit)
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
AppResult.Error(error.toAppError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Throwable.toAppError(): AppError {
|
||||||
|
return when (this) {
|
||||||
|
is IOException -> AppError.Network
|
||||||
|
is HttpException -> if (code() == 401 || code() == 403) {
|
||||||
|
AppError.Unauthorized
|
||||||
|
} else {
|
||||||
|
AppError.Server(message = message())
|
||||||
|
}
|
||||||
|
else -> AppError.Unknown(cause = this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import ru.daemonlord.messenger.core.network.AuthHeaderInterceptor
|
|||||||
import ru.daemonlord.messenger.core.network.TokenRefreshAuthenticator
|
import ru.daemonlord.messenger.core.network.TokenRefreshAuthenticator
|
||||||
import ru.daemonlord.messenger.data.auth.api.AuthApiService
|
import ru.daemonlord.messenger.data.auth.api.AuthApiService
|
||||||
import ru.daemonlord.messenger.data.chat.api.ChatApiService
|
import ru.daemonlord.messenger.data.chat.api.ChatApiService
|
||||||
|
import ru.daemonlord.messenger.data.message.api.MessageApiService
|
||||||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@@ -123,4 +124,10 @@ object NetworkModule {
|
|||||||
fun provideChatApiService(retrofit: Retrofit): ChatApiService {
|
fun provideChatApiService(retrofit: Retrofit): ChatApiService {
|
||||||
return retrofit.create(ChatApiService::class.java)
|
return retrofit.create(ChatApiService::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideMessageApiService(retrofit: Retrofit): MessageApiService {
|
||||||
|
return retrofit.create(MessageApiService::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import dagger.hilt.InstallIn
|
|||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import ru.daemonlord.messenger.data.auth.repository.NetworkAuthRepository
|
import ru.daemonlord.messenger.data.auth.repository.NetworkAuthRepository
|
||||||
import ru.daemonlord.messenger.data.chat.repository.NetworkChatRepository
|
import ru.daemonlord.messenger.data.chat.repository.NetworkChatRepository
|
||||||
|
import ru.daemonlord.messenger.data.message.repository.NetworkMessageRepository
|
||||||
import ru.daemonlord.messenger.domain.auth.repository.AuthRepository
|
import ru.daemonlord.messenger.domain.auth.repository.AuthRepository
|
||||||
import ru.daemonlord.messenger.domain.chat.repository.ChatRepository
|
import ru.daemonlord.messenger.domain.chat.repository.ChatRepository
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@@ -25,4 +27,10 @@ abstract class RepositoryModule {
|
|||||||
abstract fun bindChatRepository(
|
abstract fun bindChatRepository(
|
||||||
repository: NetworkChatRepository,
|
repository: NetworkChatRepository,
|
||||||
): ChatRepository
|
): ChatRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
abstract fun bindMessageRepository(
|
||||||
|
repository: NetworkMessageRepository,
|
||||||
|
): MessageRepository
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.repository
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.model.MessageItem
|
||||||
|
|
||||||
|
interface MessageRepository {
|
||||||
|
fun observeMessages(chatId: Long): Flow<List<MessageItem>>
|
||||||
|
suspend fun syncRecentMessages(chatId: Long): AppResult<Unit>
|
||||||
|
suspend fun loadMoreMessages(chatId: Long, beforeMessageId: Long): AppResult<Unit>
|
||||||
|
suspend fun sendTextMessage(chatId: Long, text: String, replyToMessageId: Long? = null): AppResult<Unit>
|
||||||
|
suspend fun editMessage(messageId: Long, newText: String): AppResult<Unit>
|
||||||
|
suspend fun deleteMessage(messageId: Long, forAll: Boolean): AppResult<Unit>
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.usecase
|
||||||
|
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class DeleteMessageUseCase @Inject constructor(
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke(messageId: Long, forAll: Boolean): AppResult<Unit> {
|
||||||
|
return messageRepository.deleteMessage(messageId = messageId, forAll = forAll)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.usecase
|
||||||
|
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EditMessageUseCase @Inject constructor(
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke(messageId: Long, newText: String): AppResult<Unit> {
|
||||||
|
return messageRepository.editMessage(messageId = messageId, newText = newText)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.usecase
|
||||||
|
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LoadMoreMessagesUseCase @Inject constructor(
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke(chatId: Long, beforeMessageId: Long): AppResult<Unit> {
|
||||||
|
return messageRepository.loadMoreMessages(chatId = chatId, beforeMessageId = beforeMessageId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.usecase
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import ru.daemonlord.messenger.domain.message.model.MessageItem
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ObserveMessagesUseCase @Inject constructor(
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
) {
|
||||||
|
operator fun invoke(chatId: Long): Flow<List<MessageItem>> {
|
||||||
|
return messageRepository.observeMessages(chatId = chatId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.usecase
|
||||||
|
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class SendTextMessageUseCase @Inject constructor(
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke(chatId: Long, text: String, replyToMessageId: Long? = null): AppResult<Unit> {
|
||||||
|
return messageRepository.sendTextMessage(
|
||||||
|
chatId = chatId,
|
||||||
|
text = text,
|
||||||
|
replyToMessageId = replyToMessageId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.daemonlord.messenger.domain.message.usecase
|
||||||
|
|
||||||
|
import ru.daemonlord.messenger.domain.common.AppResult
|
||||||
|
import ru.daemonlord.messenger.domain.message.repository.MessageRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class SyncRecentMessagesUseCase @Inject constructor(
|
||||||
|
private val messageRepository: MessageRepository,
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke(chatId: Long): AppResult<Unit> {
|
||||||
|
return messageRepository.syncRecentMessages(chatId = chatId)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user