Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ class ParticipantFragment: BaseBottomSheetComposeFragment() {
Timber.w("Error while opening participant screen")
}
}

is ParticipantViewModel.Command.SwitchToVault -> {
runCatching {
findNavController().popBackStack(R.id.vaultScreen, false)
}.onFailure {
Timber.e(it, "Error while opening space")
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ enum class SpaceCreationUseCase(val value: Int) {
GET_STARTED_MOBILE(4),
CHAT_SPACE(5),
DATA_SPACE_MOBILE(6),
ONE_TO_ONE_SPACE(7),
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ object Relations {
const val PARTICIPANT_STATUS = "participantStatus"
const val PARTICIPANT_PERMISSIONS = "participantPermissions"
const val SPACE_ACCESS_TYPE = "spaceAccessType"
const val SPACE_DASHBOARD_ID = "spaceDashboardId"
const val ONE_TO_ONE_IDENTITY = "oneToOneIdentity"
const val IDENTITY = "identity"
const val GLOBAL_NAME = "globalName"
const val READERS_LIMIT = "readersLimit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ enum class SpaceUxType(val code: Int) {
DATA(1),
STREAM(2),
CHAT(3),
ONE_TO_ONE(4)
}

sealed class SpaceInviteError : Exception() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import com.anytypeio.anytype.presentation.profile.ParticipantEvent
import com.anytypeio.anytype.presentation.profile.ParticipantViewModel.UiParticipantScreenState
import com.anytypeio.anytype.presentation.profile.ProfileIconView
import coil3.compose.AsyncImage
import com.anytypeio.anytype.core_ui.views.ButtonSecondaryLoading
import com.anytypeio.anytype.core_ui.views.ButtonSize

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand Down Expand Up @@ -136,6 +138,19 @@ fun ParticipantScreen(
description = uiState.description!!
)
}
if (!uiState.isOwner) {
Spacer(modifier = Modifier.height(24.dp))
ButtonSecondaryLoading(
text = stringResource(R.string.participant_btn_connect),
onClick = { onEvent(ParticipantEvent.OnConnectClicked) },
enabled = !uiState.isConnecting,
size = ButtonSize.Large,
loading = uiState.isConnecting,
modifierButton = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp)
)
}
val h = spacer + 16.dp
Spacer(
modifier = Modifier.height(h)
Expand Down
1 change: 1 addition & 0 deletions localization/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2364,5 +2364,6 @@ Please provide specific details of your needs here.</string>
<string name="toast_moved_to_bin">Object moved to bin.</string>
<string name="media_object_in_bin">This object is in the bin. Restore it?</string>
<string name="toast_restored">Object restored.</string>
<string name="participant_btn_connect">Connect</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ fun SpaceCreationUseCase.toMiddlewareModel(): Rpc.Object.ImportUseCase.Request.U
SpaceCreationUseCase.GET_STARTED_MOBILE -> Rpc.Object.ImportUseCase.Request.UseCase.GET_STARTED_MOBILE
SpaceCreationUseCase.CHAT_SPACE -> Rpc.Object.ImportUseCase.Request.UseCase.CHAT_SPACE
SpaceCreationUseCase.DATA_SPACE_MOBILE -> Rpc.Object.ImportUseCase.Request.UseCase.DATA_SPACE_MOBILE
SpaceCreationUseCase.ONE_TO_ONE_SPACE -> Rpc.Object.ImportUseCase.Request.UseCase.CHAT_SPACE
}

fun NotificationState.toMiddlewareModel(): Rpc.PushNotification.Mode = when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package com.anytypeio.anytype.presentation.profile
sealed class ParticipantEvent{
data object OnDismiss: ParticipantEvent()
data object OnCardClicked: ParticipantEvent()
data object OnConnectClicked: ParticipantEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ import com.anytypeio.anytype.analytics.base.EventsDictionary
import com.anytypeio.anytype.analytics.base.sendEvent
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.SpaceCreationUseCase
import com.anytypeio.anytype.core_models.membership.MembershipStatus
import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType
import com.anytypeio.anytype.core_models.multiplayer.SpaceUxType
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.domain.config.ConfigStorage
import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
import com.anytypeio.anytype.domain.base.suspendFold
import com.anytypeio.anytype.domain.primitives.FieldParser
import com.anytypeio.anytype.domain.spaces.CreateSpace
import com.anytypeio.anytype.presentation.membership.provider.MembershipProvider
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
import javax.inject.Inject
Expand All @@ -31,7 +36,8 @@ class ParticipantViewModel(
private val subscriptionContainer: StorelessSubscriptionContainer,
private val fieldsParser: FieldParser,
private val userPermissionProvider: UserPermissionProvider,
private val configStorage: ConfigStorage
private val configStorage: ConfigStorage,
private val createSpace: CreateSpace
) : ViewModel() {

val uiState = MutableStateFlow<UiParticipantScreenState>(UiParticipantScreenState.EMPTY)
Expand Down Expand Up @@ -116,6 +122,56 @@ class ParticipantViewModel(
}
}
}

ParticipantEvent.OnConnectClicked -> {
proceedWithCreatingOneToOneSpace()
}
}
}

private fun proceedWithCreatingOneToOneSpace() {
val state = uiState.value
val participantIdentity = state.identity
if (participantIdentity.isNullOrBlank()) {
viewModelScope.launch {
commands.emit(Command.Toast.Error("Unable to connect: participant identity not found"))
}
return
}

viewModelScope.launch {
// Set loading state
uiState.value = state.copy(isConnecting = true)

// Create the 1-on-1 space
val params = CreateSpace.Params(
details = mapOf(
Relations.ONE_TO_ONE_IDENTITY to participantIdentity,
Relations.SPACE_UX_TYPE to SpaceUxType.ONE_TO_ONE.code.toDouble(),
Relations.SPACE_ACCESS_TYPE to SpaceAccessType.SHARED.code.toDouble(),
Relations.SPACE_DASHBOARD_ID to "chat" // Chat dashboard ID
),
useCase = SpaceCreationUseCase.ONE_TO_ONE_SPACE
)

createSpace.async(params).suspendFold(
onSuccess = { response ->
// Reset loading state
uiState.value = state.copy(isConnecting = false)
// Switch to the new space
commands.emit(Command.SwitchToVault(response.space.id))
},
onFailure = { error ->
// Reset loading state
uiState.value = state.copy(isConnecting = false)
// Show error
commands.emit(
Command.Toast.Error(
error.message ?: "Failed to create 1-on-1 space"
)
)
}
)
}
}

Expand All @@ -124,13 +180,15 @@ class ParticipantViewModel(
val icon: ProfileIconView,
val description: String? = null,
val identity: String? = null,
val isOwner: Boolean
val isOwner: Boolean,
val isConnecting: Boolean = false
) {
companion object {
val EMPTY = UiParticipantScreenState(
name = "",
icon = ProfileIconView.Loading,
isOwner = false
isOwner = false,
isConnecting = false
)
}
}
Expand All @@ -147,6 +205,7 @@ class ParticipantViewModel(

data object Dismiss : Command()
data object OpenSettingsProfile : Command()
data class SwitchToVault(val spaceId: Id) : Command()
}

companion object {
Expand All @@ -161,7 +220,8 @@ class ParticipantViewModel(
private val subscriptionContainer: StorelessSubscriptionContainer,
private val fieldsParser: FieldParser,
private val userPermissionProvider: UserPermissionProvider,
private val configStorage: ConfigStorage
private val configStorage: ConfigStorage,
private val createSpace: CreateSpace
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
Expand All @@ -173,7 +233,8 @@ class ParticipantViewModel(
subscriptionContainer = subscriptionContainer,
fieldsParser = fieldsParser,
userPermissionProvider = userPermissionProvider,
configStorage = configStorage
configStorage = configStorage,
createSpace = createSpace
) as T
}
}
Expand Down