From 6343b80d7d0f25919559dc48ab1b77b854778268 Mon Sep 17 00:00:00 2001 From: Konstantin Ivanov <54908981+konstantiniiv@users.noreply.github.com> Date: Fri, 6 Jun 2025 13:36:21 +0200 Subject: [PATCH] DROID-3626 Space chat | Ui fixes + proper chat space creation (#2508) --- .../anytype/ui/spaces/CreateSpaceScreen.kt | 10 ++++++---- .../com/anytypeio/anytype/ui/vault/VaultScreen.kt | 10 ++++++---- .../com/anytypeio/anytype/core_models/Command.kt | 2 +- .../anytypeio/anytype/core_models/ImportUseCase.kt | 13 +++++++++++++ .../anytypeio/anytype/domain/spaces/CreateSpace.kt | 5 +++-- .../viewmodel/GalleryInstallationViewModel.kt | 8 ++++++-- .../anytype/middleware/interactor/Middleware.kt | 5 +---- .../middleware/mappers/ToMiddlewareModelMappers.kt | 10 ++++++++++ .../presentation/spaces/CreateSpaceViewModel.kt | 12 ++++++++++-- .../anytype/presentation/vault/VaultViewModel.kt | 4 +++- 10 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 core-models/src/main/java/com/anytypeio/anytype/core_models/ImportUseCase.kt diff --git a/app/src/main/java/com/anytypeio/anytype/ui/spaces/CreateSpaceScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/spaces/CreateSpaceScreen.kt index b1cd5c5673..68db392780 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/spaces/CreateSpaceScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/spaces/CreateSpaceScreen.kt @@ -176,9 +176,11 @@ fun CreateSpaceScreen( } ButtonPrimaryLoading( onClick = { - focusManager.clearFocus() - keyboardController?.hide() - onCreate(innerValue.text) + if (isChatSpace || innerValue.text.isNotEmpty()) { + focusManager.clearFocus() + keyboardController?.hide() + onCreate(innerValue.text) + } }, text = stringResource(id = R.string.create), size = ButtonSize.Large, @@ -191,7 +193,7 @@ fun CreateSpaceScreen( .fillMaxWidth() .padding(horizontal = 20.dp), loading = isLoading.value, - enabled = innerValue.text.isNotEmpty() + enabled = isChatSpace || innerValue.text.isNotEmpty() ) } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt index 45e084108c..3cd46d1b20 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -101,15 +102,14 @@ fun VaultScreen( Scaffold( modifier = Modifier .fillMaxSize() - .background( - color = colorResource(id = R.color.background_primary) - ) + .background(color = colorResource(id = R.color.background_primary)) .then( if (SDK_INT >= EDGE_TO_EDGE_MIN_SDK) Modifier.windowInsetsPadding(WindowInsets.systemBars) else Modifier ), + backgroundColor = colorResource(id = R.color.background_primary), topBar = { VaultScreenToolbar( profile = profile, @@ -163,7 +163,9 @@ fun VaultScreen( creatorName = item.creatorName, messageText = item.messageText, messageTime = item.messageTime, - chatPreview = item.chatPreview + chatPreview = item.chatPreview, + unreadMessageCount = item.unreadMessageCount, + unreadMentionCount = item.unreadMentionCount ) } } diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/Command.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/Command.kt index 6c25b54654..b4d66b026e 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/Command.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/Command.kt @@ -478,7 +478,7 @@ sealed class Command { data class CreateSpace( val details: Struct, val withChat: Boolean, - val shouldApplyEmptyUseCase: Boolean + val useCase: SpaceCreationUseCase ) { data class Result( val space: SpaceId, diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/ImportUseCase.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/ImportUseCase.kt new file mode 100644 index 0000000000..77c39f1a82 --- /dev/null +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/ImportUseCase.kt @@ -0,0 +1,13 @@ +package com.anytypeio.anytype.core_models + +/** + * Space creation use case enum that corresponds to Rpc.Object.ImportUseCase.Request.UseCase + */ +enum class SpaceCreationUseCase(val value: Int) { + NONE(0), + GET_STARTED(1), + EMPTY(2), + GUIDE_ONLY(3), + GET_STARTED_MOBILE(4), + EMPTY_MOBILE(5) +} \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/spaces/CreateSpace.kt b/domain/src/main/java/com/anytypeio/anytype/domain/spaces/CreateSpace.kt index c4058d1141..8d991c067e 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/spaces/CreateSpace.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/spaces/CreateSpace.kt @@ -2,6 +2,7 @@ package com.anytypeio.anytype.domain.spaces import com.anytypeio.anytype.core_models.Command import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.SpaceCreationUseCase import com.anytypeio.anytype.core_models.Struct import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers import com.anytypeio.anytype.domain.base.ResultInteractor @@ -17,13 +18,13 @@ class CreateSpace @Inject constructor( command = Command.CreateSpace( details = params.details, withChat = params.withChat, - shouldApplyEmptyUseCase = params.shouldApplyEmptyUseCase + useCase = params.useCase ) ) data class Params( val details: Struct, val withChat: Boolean = false, - val shouldApplyEmptyUseCase: Boolean = false + val useCase: SpaceCreationUseCase = SpaceCreationUseCase.GET_STARTED_MOBILE ) } \ No newline at end of file diff --git a/gallery-experience/src/main/java/com/anytypeio/anytype/gallery_experience/viewmodel/GalleryInstallationViewModel.kt b/gallery-experience/src/main/java/com/anytypeio/anytype/gallery_experience/viewmodel/GalleryInstallationViewModel.kt index 3036239c64..0b8d772d4a 100644 --- a/gallery-experience/src/main/java/com/anytypeio/anytype/gallery_experience/viewmodel/GalleryInstallationViewModel.kt +++ b/gallery-experience/src/main/java/com/anytypeio/anytype/gallery_experience/viewmodel/GalleryInstallationViewModel.kt @@ -14,6 +14,8 @@ import com.anytypeio.anytype.analytics.props.Props import com.anytypeio.anytype.core_models.ManifestInfo import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Relations +import com.anytypeio.anytype.core_models.SpaceCreationUseCase +import com.anytypeio.anytype.core_models.multiplayer.SpaceUxType import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.domain.base.fold import com.anytypeio.anytype.domain.config.ConfigStorage @@ -128,9 +130,11 @@ class GalleryInstallationViewModel( val params = CreateSpace.Params( details = mapOf( Relations.NAME to manifestInfo.title, - Relations.ICON_OPTION to spaceGradientProvider.randomId().toDouble() + Relations.ICON_OPTION to spaceGradientProvider.randomId().toDouble(), + Relations.SPACE_UX_TYPE to SpaceUxType.DATA.code.toDouble(), ), - shouldApplyEmptyUseCase = true + withChat = false, + useCase = SpaceCreationUseCase.EMPTY_MOBILE ) createSpace.async(params).fold( onSuccess = { result -> 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 7b4f54d241..8d78bd1560 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 @@ -1973,10 +1973,7 @@ class Middleware @Inject constructor( fun workspaceCreate(command: Command.CreateSpace): Command.CreateSpace.Result { val request = Rpc.Workspace.Create.Request( details = command.details, - useCase = if (command.shouldApplyEmptyUseCase) - Rpc.Object.ImportUseCase.Request.UseCase.EMPTY_MOBILE - else - Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED_MOBILE, + useCase = command.useCase.toMiddlewareModel(), withChat = command.withChat ) logRequestIfDebug(request) diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToMiddlewareModelMappers.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToMiddlewareModelMappers.kt index a88693493a..3cbde01b68 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToMiddlewareModelMappers.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToMiddlewareModelMappers.kt @@ -20,6 +20,7 @@ import com.anytypeio.anytype.core_models.membership.MembershipPaymentMethod import com.anytypeio.anytype.core_models.membership.NameServiceNameType import com.anytypeio.anytype.core_models.multiplayer.InviteType import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions +import com.anytypeio.anytype.core_models.SpaceCreationUseCase // ---------------------- BLOCKS ------------------------ @@ -644,3 +645,12 @@ fun InviteType.toMiddleware(): MInviteType = when (this) { InviteType.WITHOUT_APPROVE -> MInviteType.WithoutApprove } +fun SpaceCreationUseCase.toMiddlewareModel(): Rpc.Object.ImportUseCase.Request.UseCase = when (this) { + SpaceCreationUseCase.NONE -> Rpc.Object.ImportUseCase.Request.UseCase.NONE + SpaceCreationUseCase.GET_STARTED -> Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED + SpaceCreationUseCase.EMPTY -> Rpc.Object.ImportUseCase.Request.UseCase.EMPTY + SpaceCreationUseCase.GUIDE_ONLY -> Rpc.Object.ImportUseCase.Request.UseCase.GUIDE_ONLY + SpaceCreationUseCase.GET_STARTED_MOBILE -> Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED_MOBILE + SpaceCreationUseCase.EMPTY_MOBILE -> Rpc.Object.ImportUseCase.Request.UseCase.EMPTY_MOBILE +} + diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/CreateSpaceViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/CreateSpaceViewModel.kt index a08f4861b4..d08b66f81a 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/CreateSpaceViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/CreateSpaceViewModel.kt @@ -10,9 +10,11 @@ import com.anytypeio.anytype.analytics.base.sendEvent import com.anytypeio.anytype.analytics.props.Props import com.anytypeio.anytype.core_models.Block import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.SpaceCreationUseCase import com.anytypeio.anytype.core_models.Relations import com.anytypeio.anytype.core_models.SystemColor import com.anytypeio.anytype.core_models.Url +import com.anytypeio.anytype.core_models.multiplayer.SpaceUxType import com.anytypeio.anytype.core_models.primitives.Space import com.anytypeio.anytype.domain.base.fold import com.anytypeio.anytype.domain.media.UploadFile @@ -66,6 +68,11 @@ class CreateSpaceViewModel( sendToast("Please wait...") return } + val (uxType, useCase) = if (withChat) { + SpaceUxType.CHAT to SpaceCreationUseCase.NONE + } else { + SpaceUxType.DATA to SpaceCreationUseCase.EMPTY_MOBILE + } viewModelScope.launch { val params = CreateSpace.Params( details = mapOf( @@ -73,9 +80,10 @@ class CreateSpaceViewModel( Relations.ICON_OPTION to when (val icon = spaceIconView.value) { is SpaceIconView.Placeholder -> icon.color.index.toDouble() else -> SystemColor.SKY.index.toDouble() - } + }, + Relations.SPACE_UX_TYPE to uxType.code.toDouble() ), - shouldApplyEmptyUseCase = true, + useCase = useCase, withChat = withChat ) createSpace.stream(params = params).collect { result -> diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt index 308e2626db..6d4be69a46 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/vault/VaultViewModel.kt @@ -203,7 +203,9 @@ class VaultViewModel( previewText = previewText, creatorName = creatorName, messageText = messageText, - messageTime = messageTime + messageTime = messageTime, + unreadMessageCount = chatPreview.state?.unreadMessages?.counter ?: 0, + unreadMentionCount = chatPreview.state?.unreadMentions?.counter ?: 0 ) }