pinned message in messages history draft

This commit is contained in:
2025-03-27 12:16:26 +03:00
parent f66123ba94
commit 9aa85d40c6
24 changed files with 330 additions and 84 deletions
@@ -46,20 +46,22 @@ interface MessagesRepository {
title: String?
): ApiResult<Int, RestApiErrorDomain>
suspend fun pin(
peerId: Int,
messageId: Int?,
conversationMessageId: Int?
): ApiResult<VkMessage, RestApiErrorDomain>
suspend fun unpin(
peerId: Int
): ApiResult<Int, RestApiErrorDomain>
suspend fun storeMessages(messages: List<VkMessage>)
// suspend fun markAsImportant(
// params: MessagesMarkAsImportantRequest
// ): ApiResult<List<Int>, RestApiErrorDomain>
//
// suspend fun pin(
// params: MessagesPinMessageRequest
// ): ApiResult<VkMessageData, RestApiErrorDomain>
//
// suspend fun unpin(
// params: MessagesUnPinMessageRequest
// ): ApiResult<Unit, RestApiErrorDomain>
//
// suspend fun delete(
// params: MessagesDeleteRequest
// ): ApiResult<Unit, RestApiErrorDomain>
@@ -20,7 +20,9 @@ import dev.meloda.fast.model.api.requests.MessagesGetByIdRequest
import dev.meloda.fast.model.api.requests.MessagesGetHistoryAttachmentsRequest
import dev.meloda.fast.model.api.requests.MessagesGetHistoryRequest
import dev.meloda.fast.model.api.requests.MessagesMarkAsReadRequest
import dev.meloda.fast.model.api.requests.MessagesPinMessageRequest
import dev.meloda.fast.model.api.requests.MessagesSendRequest
import dev.meloda.fast.model.api.requests.MessagesUnPinMessageRequest
import dev.meloda.fast.network.RestApiErrorDomain
import dev.meloda.fast.network.mapApiDefault
import dev.meloda.fast.network.mapApiResult
@@ -216,6 +218,32 @@ class MessagesRepositoryImpl(
)
}
override suspend fun pin(
peerId: Int,
messageId: Int?,
conversationMessageId: Int?
): ApiResult<VkMessage, RestApiErrorDomain> = withContext(Dispatchers.IO) {
val requestModel = MessagesPinMessageRequest(
peerId = peerId,
messageId = messageId,
conversationMessageId = conversationMessageId
)
messagesService.pin(requestModel.map).mapApiResult(
successMapper = { apiResponse ->
apiResponse.requireResponse().asDomain()
},
errorMapper = { error -> error?.toDomain() }
)
}
override suspend fun unpin(
peerId: Int
): ApiResult<Int, RestApiErrorDomain> = withContext(Dispatchers.IO) {
val requestModel = MessagesUnPinMessageRequest(peerId = peerId)
messagesService.unpin(requestModel.map).mapApiDefault()
}
override suspend fun storeMessages(messages: List<VkMessage>) {
messageDao.insertAll(messages.map(VkMessage::asEntity))
}
@@ -229,24 +257,6 @@ class MessagesRepositoryImpl(
// )
// }
//
// override suspend fun pin(
// params: MessagesPinMessageRequest
// ): ApiResult<VkMessageData, RestApiErrorDomain> = withContext(Dispatchers.IO) {
// messagesService.pin(params.map).mapResult(
// successMapper = { response -> response.requireResponse() },
// errorMapper = { error -> error?.toDomain() }
// )
// }
//
// override suspend fun unpin(
// params: MessagesUnPinMessageRequest
// ): ApiResult<Unit, RestApiErrorDomain> = withContext(Dispatchers.IO) {
// messagesService.unpin(params.map).mapResult(
// successMapper = {},
// errorMapper = { error -> error?.toDomain() }
// )
// }
//
// override suspend fun delete(
// params: MessagesDeleteRequest
// ): ApiResult<Unit, RestApiErrorDomain> = withContext(Dispatchers.IO) {
@@ -293,4 +303,3 @@ class MessagesRepositoryImpl(
// )
// }
}
@@ -21,7 +21,7 @@ import dev.meloda.fast.model.database.VkUserEntity
VkConversationEntity::class
],
version = 7
version = 8
)
@TypeConverters(Converters::class)
abstract class CacheDatabase : RoomDatabase() {
@@ -2,6 +2,7 @@ package dev.meloda.fast.database.di
import androidx.room.Room
import dev.meloda.fast.database.AccountsDatabase
import dev.meloda.fast.database.CacheDatabase
import org.koin.core.scope.Scope
import org.koin.dsl.module
@@ -12,7 +13,7 @@ val databaseModule = module {
single { get<AccountsDatabase>().accountDao() }
single {
Room.databaseBuilder(get(), dev.meloda.fast.database.CacheDatabase::class.java, "cache")
Room.databaseBuilder(get(), CacheDatabase::class.java, "cache")
.fallbackToDestructiveMigration()
.build()
}
@@ -22,4 +23,4 @@ val databaseModule = module {
single { cacheDB().conversationDao() }
}
private fun Scope.cacheDB(): dev.meloda.fast.database.CacheDatabase = get()
private fun Scope.cacheDB(): CacheDatabase = get()
@@ -47,6 +47,16 @@ interface MessagesUseCase {
title: String?
): Flow<State<Int>>
fun pin(
peerId: Int,
messageId: Int?,
conversationMessageId: Int?
): Flow<State<VkMessage>>
fun unpin(
peerId: Int
): Flow<State<Int>>
suspend fun storeMessage(message: VkMessage)
suspend fun storeMessages(messages: List<VkMessage>)
}
@@ -108,6 +108,30 @@ class MessagesUseCaseImpl(
emit(newState)
}
override fun pin(
peerId: Int,
messageId: Int?,
conversationMessageId: Int?
): Flow<State<VkMessage>> = flow {
emit(State.Loading)
val newState = repository.pin(
peerId = peerId,
messageId = messageId,
conversationMessageId = conversationMessageId
).mapToState()
emit(newState)
}
override fun unpin(peerId: Int): Flow<State<Int>> = flow {
emit(State.Loading)
val newState = repository.unpin(peerId = peerId).mapToState()
emit(newState)
}
override suspend fun storeMessage(message: VkMessage) {
repository.storeMessages(listOf(message))
}
@@ -1,8 +1,8 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkMessage
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkMessage
@JsonClass(generateAdapter = true)
data class VkMessageData(
@@ -23,7 +23,9 @@ data class VkMessageData(
@Json(name = "action") val action: Action?,
@Json(name = "ttl") val ttl: Int?,
@Json(name = "reply_message") val replyMessage: VkMessageData?,
@Json(name = "update_time") val updateTime: Int?
@Json(name = "update_time") val updateTime: Int?,
@Json(name = "is_pinned") val isPinned: Boolean?,
@Json(name = "pinned_at") val pinnedAt: Int?
) {
@JsonClass(generateAdapter = true)
@@ -72,7 +74,7 @@ fun VkMessageData.asDomain(): VkMessage = VkMessage(
actionConversationMessageId = action?.conversationMessageId,
actionMessage = action?.message,
geoType = geo?.type,
important = important,
isImportant = important,
updateTime = updateTime,
forwards = fwdMessages.orEmpty().map(VkMessageData::asDomain),
attachments = attachments.map(VkAttachmentItemData::toDomain),
@@ -81,4 +83,6 @@ fun VkMessageData.asDomain(): VkMessage = VkMessage(
group = null,
actionUser = null,
actionGroup = null,
pinnedAt = pinnedAt,
isPinned = isPinned == true
)
@@ -41,7 +41,7 @@ data class VkPinnedMessageData(
actionConversationMessageId = action?.conversationMessageId,
actionMessage = action?.message,
geoType = geo?.type,
important = important,
isImportant = important,
updateTime = updateTime,
forwards = forwards.orEmpty().map(VkMessageData::asDomain),
@@ -52,6 +52,7 @@ data class VkPinnedMessageData(
group = null,
actionUser = null,
actionGroup = null,
pinnedAt = null,
isPinned = true,
)
}
@@ -18,8 +18,9 @@ data class VkMessage(
val actionMessage: String?,
val updateTime: Int?,
val important: Boolean = false,
val pinnedAt: Int?,
val isPinned: Boolean,
val isImportant: Boolean = false,
val forwards: List<VkMessage>?,
val attachments: List<VkAttachment>?,
@@ -91,10 +92,12 @@ fun VkMessage.asEntity(): VkMessageEntity = VkMessageEntity(
actionConversationMessageId = actionConversationMessageId,
actionMessage = actionMessage,
updateTime = updateTime,
important = important,
important = isImportant,
forwardIds = forwards.orEmpty().map(VkMessage::id),
// TODO: 05/05/2024, Danil Nikolaev: save attachments
attachments = emptyList(),
replyMessageId = replyMessage?.id,
geoType = geoType
geoType = geoType,
pinnedAt = pinnedAt,
isPinned = isPinned,
)
@@ -25,7 +25,9 @@ data class VkMessageEntity(
val forwardIds: List<Int>?,
val attachments: List<String>?, // TODO: 01/05/2024, Danil Nikolaev: how to store???
val replyMessageId: Int?,
val geoType: String?
val geoType: String?,
val pinnedAt: Int?,
val isPinned: Boolean
)
fun VkMessageEntity.asExternalModel(): VkMessage = VkMessage(
@@ -43,7 +45,7 @@ fun VkMessageEntity.asExternalModel(): VkMessage = VkMessage(
actionConversationMessageId = actionConversationMessageId,
actionMessage = actionMessage,
updateTime = updateTime,
important = important,
isImportant = important,
forwards = emptyList(),//forwards.orEmpty().map(VkMessageEntity::asExternalModel),
// TODO: 05/05/2024, Danil Nikolaev: restore attachments
attachments = attachments.orEmpty().map { VkUnknownAttachment },
@@ -53,4 +55,6 @@ fun VkMessageEntity.asExternalModel(): VkMessage = VkMessage(
group = null,
actionUser = null,
actionGroup = null,
pinnedAt = pinnedAt,
isPinned = isPinned
)
@@ -2,6 +2,7 @@ package dev.meloda.fast.network.service.messages
import com.slack.eithernet.ApiResult
import dev.meloda.fast.model.api.data.VkLongPollData
import dev.meloda.fast.model.api.data.VkMessageData
import dev.meloda.fast.model.api.responses.MessagesCreateChatResponse
import dev.meloda.fast.model.api.responses.MessagesGetByIdResponse
import dev.meloda.fast.model.api.responses.MessagesGetHistoryAttachmentsResponse
@@ -56,6 +57,18 @@ interface MessagesService {
@FieldMap params: Map<String, String>
): ApiResult<ApiResponse<MessagesCreateChatResponse>, RestApiError>
@FormUrlEncoded
@POST(MessagesUrls.PIN)
suspend fun pin(
@FieldMap params: Map<String, String>
): ApiResult<ApiResponse<VkMessageData>, RestApiError>
@FormUrlEncoded
@POST(MessagesUrls.UNPIN)
suspend fun unpin(
@FieldMap params: Map<String, String>
): ApiResult<ApiResponse<Int>, RestApiError>
// @FormUrlEncoded
// @POST(MessagesUrls.MarkAsImportant)
// suspend fun markAsImportant(
@@ -63,18 +76,6 @@ interface MessagesService {
// ): ApiResult<ApiResponse<List<Int>>, RestApiError>
//
// @FormUrlEncoded
// @POST(MessagesUrls.Pin)
// suspend fun pin(
// @FieldMap params: Map<String, String>
// ): ApiResult<ApiResponse<VkMessageData>, RestApiError>
//
// @FormUrlEncoded
// @POST(MessagesUrls.Unpin)
// suspend fun unpin(
// @FieldMap params: Map<String, String>
// ): ApiResult<ApiResponse<Unit>, RestApiError>
//
// @FormUrlEncoded
// @POST(MessagesUrls.Delete)
// suspend fun delete(
// @FieldMap params: Map<String, String>
+5 -1
View File
@@ -6,13 +6,16 @@
<string name="yes">Да</string>
<string name="no">Нет</string>
<string name="message_context_action_reply">Ответить</string>
<string name="message_context_action_forward">Переслать</string>
<string name="message_context_action_mark_as_important">Пометить как важное</string>
<string name="message_context_action_unmark_as_important">Помететить как не важное</string>
<string name="message_context_action_unmark_as_important">Пометить как не важное</string>
<string name="time_format">Время: %1$s</string>
<string name="message_context_action_unmark_as_spam">Помеьиьб как не спам</string>
<string name="message_context_action_pin">Закрепить</string>
<string name="message_context_action_unpin">Открепить</string>
<string name="message_context_action_edit">Изменить</string>
<string name="message_context_action_delete">Удалить</string>
<string name="message_context_action_copy">Скопировать</string>
<string name="confirm_delete_message">Удалить сообщение?</string>
<string name="message_delete_for_all">Для всех</string>
<string name="message_mark_as_spam">Пометить как спам</string>
@@ -229,4 +232,5 @@
<string name="chat_attachment_music">Музыка</string>
<string name="chat_attachment_files">Файлы</string>
<string name="chat_attachment_links">Ссылки</string>
<string name="message_context_action_mark_as_spam">Пометить как спам</string>
</resources>
+6 -1
View File
@@ -124,14 +124,19 @@
<string name="sign_out_confirm">Signing out will delete all data related to this account from this device. Continue?</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="time_format">Time: %1$s</string>
<string name="message_context_action_reply">Reply</string>
<string name="message_context_action_forward">Forward</string>
<string name="message_context_action_mark_as_important">Mark as important</string>
<string name="message_context_action_unmark_as_important">Unmark as important</string>
<string name="time_format">Time: %1$s</string>
<string name="message_context_action_mark_as_spam">Mark as spam</string>
<string name="message_context_action_unmark_as_spam">Unmark as spam</string>
<string name="message_context_action_pin">Pin</string>
<string name="message_context_action_unpin">Unpin</string>
<string name="message_context_action_edit">Edit</string>
<string name="message_context_action_delete">Delete</string>
<string name="message_context_action_copy">Copy</string>
<string name="confirm_delete_message">Delete the message?</string>