From 55e430c70b3f7f9a76760ed09429e3113c56ad40 Mon Sep 17 00:00:00 2001 From: Evgenii Kozlov Date: Fri, 23 May 2025 14:59:46 +0200 Subject: [PATCH] DROID-3622 Chats | Tech | Integrate API for chat previews (#2444) --- .../anytype/core_models/chats/Chat.kt | 10 +++++++ .../auth/repo/block/BlockDataRepository.kt | 8 ++++++ .../data/auth/repo/block/BlockRemote.kt | 2 ++ .../domain/block/repo/BlockRepository.kt | 2 ++ .../middleware/block/BlockMiddleware.kt | 8 ++++++ .../middleware/interactor/Middleware.kt | 19 +++++++++++++- .../anytype/middleware/mappers/Alias.kt | 1 + .../middleware/mappers/ToCoreModelMappers.kt | 11 ++++++++ .../middleware/service/MiddlewareService.kt | 2 ++ .../MiddlewareServiceImplementation.kt | 26 +++++++++++++++++++ 10 files changed, 88 insertions(+), 1 deletion(-) diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/chats/Chat.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/chats/Chat.kt index 8cf0771525..aa6e056f81 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/chats/Chat.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/chats/Chat.kt @@ -2,6 +2,8 @@ package com.anytypeio.anytype.core_models.chats import com.anytypeio.anytype.core_models.Block import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.ObjectWrapper +import com.anytypeio.anytype.core_models.primitives.SpaceId sealed class Chat { @@ -110,4 +112,12 @@ sealed class Chat { val oldestMessageOrderId: Id? = unreadMessages?.olderOrderId val oldestMentionMessageOrderId: Id? = unreadMentions?.olderOrderId } + + data class Preview( + val space: SpaceId, + val chat: Id, + val message: Message? = null, + val state: State? = null, + val dependencies: List = emptyList() + ) } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt index d90263af0a..aa8b8aa8f6 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockDataRepository.kt @@ -1101,6 +1101,14 @@ class BlockDataRepository( return remote.unsubscribeChat(chat) } + override suspend fun subscribeToMessagePreviews(subscription: Id): List { + return remote.subscribeToMessagePreviews(subscription) + } + + override suspend fun unsubscribeFromMessagePreviews(subscription: Id) { + remote.unsubscribeFromMessagePreviews(subscription) + } + override suspend fun objectRelationListWithValue(command: Command.RelationListWithValue): List { return remote.objectRelationListWithValue(command) } diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt index 05e06d199d..66334d59c9 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemote.kt @@ -467,6 +467,8 @@ interface BlockRemote { suspend fun subscribeLastChatMessages(command: Command.ChatCommand.SubscribeLastMessages): Command.ChatCommand.SubscribeLastMessages.Response suspend fun toggleChatMessageReaction(command: Command.ChatCommand.ToggleMessageReaction) suspend fun unsubscribeChat(chat: Id) + suspend fun subscribeToMessagePreviews(subscription: Id): List + suspend fun unsubscribeFromMessagePreviews(subscription: Id) //endregion diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt index ff238bd938..eaa8ab2dfb 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt @@ -509,6 +509,8 @@ interface BlockRepository { suspend fun subscribeLastChatMessages(command: Command.ChatCommand.SubscribeLastMessages): Command.ChatCommand.SubscribeLastMessages.Response suspend fun toggleChatMessageReaction(command: Command.ChatCommand.ToggleMessageReaction) suspend fun unsubscribeChat(chat: Id) + suspend fun subscribeToMessagePreviews(subscription: Id): List + suspend fun unsubscribeFromMessagePreviews(subscription: Id) //endregion diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt index 4f21c3da07..a772904d60 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt @@ -1067,6 +1067,14 @@ class BlockMiddleware( return middleware.chatUnsubscribe(chat = chat) } + override suspend fun subscribeToMessagePreviews(subscription: Id): List { + return middleware.chatSubscribeToMessagePreviews(subscription) + } + + override suspend fun unsubscribeFromMessagePreviews(subscription: Id) { + middleware.chatUnsubscribeFromMessagePreviews(subscription) + } + override suspend fun dataViewSetActiveView(command: Command.DataViewSetActiveView): Payload { return middleware.dataViewSetActiveView(command) } diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt index 43de24d6d2..2ddb42a1f6 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt @@ -2895,7 +2895,7 @@ class Middleware @Inject constructor( return response.event.toPayload() } - @Throws + @Throws(Exception::class) fun chatUnsubscribe(chat: Id) { val request = Rpc.Chat.Unsubscribe.Request(chatObjectId = chat) logRequestIfDebug(request) @@ -2903,6 +2903,23 @@ class Middleware @Inject constructor( logResponseIfDebug(response, time) } + @Throws(Exception::class) + fun chatSubscribeToMessagePreviews(subscription: Id): List { + val request = Rpc.Chat.SubscribeToMessagePreviews.Request(subId = subscription) + logRequestIfDebug(request) + val (response, time) = measureTimedValue { service.chatSubscribeToMessagePreviews(request) } + logResponseIfDebug(response, time) + return response.previews.map { it.core() } + } + + @Throws(Exception::class) + fun chatUnsubscribeFromMessagePreviews(subscription: Id) { + val request = Rpc.Chat.UnsubscribeFromMessagePreviews.Request(subId = subscription) + logRequestIfDebug(request) + val (response, time) = measureTimedValue { service.chatUnsubscribeToMessagePreviews(request) } + logResponseIfDebug(response, time) + } + @Throws(Exception::class) fun debugAccountSelectTrace(dir: String): String { val request = Rpc.Debug.AccountSelectTrace.Request(dir = dir) diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt index 5ee4c1f5c8..fee79f35bc 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt @@ -2,6 +2,7 @@ package com.anytypeio.anytype.middleware.mappers import anytype.Event.P2PStatus import anytype.Event.Space +import com.anytypeio.anytype.core_models.chats.Chat typealias MEvent = anytype.Event diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt index 211e7c8bcd..cae5ec9373 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt @@ -38,6 +38,7 @@ import com.anytypeio.anytype.core_models.NotificationStatus import com.anytypeio.anytype.core_models.ObjectOrder import com.anytypeio.anytype.core_models.ObjectType import com.anytypeio.anytype.core_models.ObjectView +import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Payload import com.anytypeio.anytype.core_models.Process import com.anytypeio.anytype.core_models.Relation @@ -1174,6 +1175,16 @@ fun MChatState.core(): Chat.State = Chat.State( lastStateId = lastStateId ) +fun Rpc.Chat.SubscribeToMessagePreviews.Response.ChatPreview.core(): Chat.Preview { + return Chat.Preview( + space = SpaceId(spaceId), + chat = chatObjectId, + message = message?.core(), + state = state?.core(), + dependencies = dependencies.map { ObjectWrapper.Basic(it.orEmpty()) }.filter { it.isValid } + ) +} + fun Rpc.History.Version.toCoreModel(): Version { return Version( id = id, diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt index 707799f816..87c5f08ebb 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt @@ -611,6 +611,8 @@ interface MiddlewareService { fun chatSubscribeLastMessages(request: Rpc.Chat.SubscribeLastMessages.Request): Rpc.Chat.SubscribeLastMessages.Response fun chatToggleMessageReaction(request: Rpc.Chat.ToggleMessageReaction.Request): Rpc.Chat.ToggleMessageReaction.Response fun chatUnsubscribe(request: Rpc.Chat.Unsubscribe.Request): Rpc.Chat.Unsubscribe.Response + fun chatSubscribeToMessagePreviews(request: Rpc.Chat.SubscribeToMessagePreviews.Request): Rpc.Chat.SubscribeToMessagePreviews.Response + fun chatUnsubscribeToMessagePreviews(request: Rpc.Chat.UnsubscribeFromMessagePreviews.Request): Rpc.Chat.UnsubscribeFromMessagePreviews.Response //endregion diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt index 5ea84838e6..06a7117dd1 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt @@ -2470,6 +2470,32 @@ class MiddlewareServiceImplementation @Inject constructor( } } + override fun chatSubscribeToMessagePreviews(request: Rpc.Chat.SubscribeToMessagePreviews.Request): Rpc.Chat.SubscribeToMessagePreviews.Response { + val encoded = Service.chatSubscribeToMessagePreviews( + Rpc.Chat.SubscribeToMessagePreviews.Request.ADAPTER.encode(request) + ) + val response = Rpc.Chat.SubscribeToMessagePreviews.Response.ADAPTER.decode(encoded) + val error = response.error + if (error != null && error.code != Rpc.Chat.SubscribeToMessagePreviews.Response.Error.Code.NULL) { + throw Exception(error.description) + } else { + return response + } + } + + override fun chatUnsubscribeToMessagePreviews(request: Rpc.Chat.UnsubscribeFromMessagePreviews.Request): Rpc.Chat.UnsubscribeFromMessagePreviews.Response { + val encoded = Service.chatUnsubscribeFromMessagePreviews( + Rpc.Chat.UnsubscribeFromMessagePreviews.Request.ADAPTER.encode(request) + ) + val response = Rpc.Chat.UnsubscribeFromMessagePreviews.Response.ADAPTER.decode(encoded) + val error = response.error + if (error != null && error.code != Rpc.Chat.UnsubscribeFromMessagePreviews.Response.Error.Code.NULL) { + throw Exception(error.description) + } else { + return response + } + } + override fun debugAccountSelectTrace(request: Rpc.Debug.AccountSelectTrace.Request): Rpc.Debug.AccountSelectTrace.Response { val encoded = Service.debugAccountSelectTrace( Rpc.Debug.AccountSelectTrace.Request.ADAPTER.encode(request)