1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

Droid 2176 Multiplayer | Fix | Design and wording fixes (#1110)

This commit is contained in:
Evgenii Kozlov 2024-04-11 19:23:33 +02:00 committed by GitHub
parent c8dfe2ced0
commit 12c9f26d9c
Signed by: github
GPG key ID: B5690EEEBB952194
7 changed files with 144 additions and 100 deletions

View file

@ -17,10 +17,10 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE
import com.anytypeio.anytype.core_ui.features.multiplayer.JoinSpaceScreen
import com.anytypeio.anytype.core_ui.foundation.AlertConfig
import com.anytypeio.anytype.core_ui.foundation.Announcement
import com.anytypeio.anytype.core_ui.foundation.BUTTON_SECONDARY
import com.anytypeio.anytype.core_ui.foundation.GRADIENT_TYPE_BLUE
import com.anytypeio.anytype.core_ui.foundation.GenericAlert
import com.anytypeio.anytype.core_ui.foundation.Warning
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment
@ -50,29 +50,41 @@ class RequestJoinSpaceFragment : BaseBottomSheetComposeFragment() {
setContent {
MaterialTheme(typography = typography) {
when(val state = vm.state.collectAsStateWithLifecycle().value) {
is TypedViewState.Loading -> {
// Render nothing.
}
is TypedViewState.Success -> {
is TypedViewState.Loading, is TypedViewState.Success -> {
val isLoading: Boolean
val spaceName: String
val createdByName: String
if (state is TypedViewState.Loading) {
isLoading = true
spaceName = stringResource(R.string.three_dots_text_placeholder)
createdByName = stringResource(R.string.three_dots_text_placeholder)
}
else {
isLoading = vm.isRequestInProgress.collectAsStateWithLifecycle().value
with(state as TypedViewState.Success) {
spaceName = state.data.spaceName
createdByName = state.data.creatorName
}
}
JoinSpaceScreen(
isLoading = vm.isRequestInProgress.collectAsStateWithLifecycle().value,
isLoading = isLoading,
onRequestJoinSpaceClicked = vm::onRequestToJoinClicked,
spaceName = state.data.spaceName,
createdByName = state.data.creatorName
spaceName = spaceName,
createdByName = createdByName
)
}
is TypedViewState.Error -> {
when(val err = state.error) {
is ErrorView.AlreadySpaceMember -> {
Warning(
Announcement(
title = stringResource(id = R.string.multiplayer_already_space_member),
subtitle = EMPTY_STRING_VALUE,
actionButtonText = stringResource(id = R.string.multiplayer_open_space),
cancelButtonText = stringResource(id = R.string.cancel),
onNegativeClick = {
onLeftClicked = {
dismiss()
},
onPositiveClick = {
onRightClicked = {
vm.onOpenSpaceClicked(err.space)
}
)

View file

@ -161,6 +161,15 @@ private fun SelectSpaceSpaceItem(
gradientBackground = colorResource(id = R.color.default_gradient_background),
gradientCornerRadius = 4.dp
)
if (item.view.isShared) {
Image(
painter = painterResource(id = R.drawable.ic_shared_space_arrow),
contentDescription = "Shared space arrow icon",
modifier = Modifier
.align(Alignment.BottomStart)
.padding(start = 8.dp, bottom = 8.dp)
)
}
}
Spacer(modifier = Modifier.height(10.dp))
Text(

View file

@ -14,8 +14,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@ -25,7 +23,6 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@ -281,77 +278,70 @@ fun Warning(
}
}
@ExperimentalMaterialApi
@Composable
fun Announcement(
title: String,
subtitle: String,
onBackClicked: () -> Unit,
onNextClicked: () -> Unit
actionButtonText: String,
cancelButtonText: String,
onRightClicked: () -> Unit,
onLeftClicked: () -> Unit,
) {
Box(contentAlignment = Alignment.BottomCenter) {
Card(
Column {
Text(
text = title,
modifier = Modifier.padding(
top = 24.dp,
start = 20.dp,
end = 20.dp,
bottom = 16.dp
end = 20.dp
),
shape = RoundedCornerShape(12.dp),
backgroundColor = colorResource(R.color.background_secondary)
) {
Column {
Text(
text = title,
modifier = Modifier.padding(
top = 24.dp,
start = 20.dp,
end = 20.dp
),
style = HeadlineHeading,
color = colorResource(R.color.text_primary)
)
Text(
text = subtitle,
modifier = Modifier.padding(
top = 12.dp,
start = 20.dp,
end = 20.dp
),
style = BodyCalloutRegular,
color = colorResource(R.color.text_primary)
)
Row(
modifier = Modifier
.height(68.dp)
.padding(
top = 8.dp,
start = 20.dp,
end = 20.dp
)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
ButtonSecondary(
text = stringResource(R.string.back),
onClick = onBackClicked,
size = ButtonSize.LargeSecondary,
modifier = Modifier
.fillMaxWidth()
.weight(1.0f)
)
Spacer(modifier = Modifier.width(10.dp))
ButtonPrimary(
text = stringResource(R.string.next),
onClick = onNextClicked,
size = ButtonSize.Large,
modifier = Modifier
.fillMaxWidth()
.weight(1.0f)
)
}
Spacer(modifier = Modifier.height(10.dp))
}
style = HeadlineHeading,
color = colorResource(R.color.text_primary)
)
if (subtitle.isNotEmpty()) {
Text(
text = subtitle,
modifier = Modifier.padding(
top = 12.dp,
start = 20.dp,
end = 20.dp,
bottom = 10.dp
),
style = BodyCalloutRegular,
color = colorResource(R.color.text_primary)
)
} else {
Spacer(modifier = Modifier.height(12.dp))
}
Row(
modifier = Modifier
.padding(
top = 10.dp,
start = 20.dp,
end = 20.dp
)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
ButtonSecondary(
onClick = onLeftClicked,
size = ButtonSize.LargeSecondary,
text = cancelButtonText,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
)
Spacer(modifier = Modifier.width(10.dp))
ButtonPrimary(
onClick = onRightClicked,
size = ButtonSize.Large,
text = actionButtonText,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
)
}
Spacer(modifier = Modifier.height(10.dp))
}
}
@ -376,4 +366,17 @@ fun WarningPreview() {
onNegativeClick = {},
onPositiveClick = {}
)
}
@Preview
@Composable
fun AnnouncementPreview() {
Announcement(
title = "Leave space",
subtitle = "Investors space will be removed from your devices and you will no longer have access to it",
actionButtonText = "Leave space",
cancelButtonText = "Cancel",
onLeftClicked = {},
onRightClicked = {}
)
}

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"
android:fillColor="#B3252525"
android:fillAlpha="0.7"/>
<path
android:pathData="M11.711,10.754L10.607,10.761L10.607,6.188L4.685,12.11L3.892,11.316L9.814,5.394L5.248,5.401V4.29L11.711,4.29L11.711,10.754Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1346,7 +1346,7 @@
<string name="multiplayer_show_qr_code">Show QR code</string>
<string name="multiplayer_how_to_share_space">How to share a space?</string>
<string name="multiplayer_how_to_share_space_step_1">Please provide the link to the person you\'d like to collaborate with.</string>
<string name="multiplayer_how_to_share_space_qr_code">Please provide this QR code to the person you\'d like to collaborate with.</string>
<string name="multiplayer_how_to_share_space_qr_code">Show this QR code to the person you\'d like to collaborate with.</string>
<string name="multiplayer_how_to_share_space_step_2">By clicking the link, a person requests to join the space.</string>
<string name="multiplayer_how_to_share_space_step_3">After approving the request, you can choose the access rights for that person.</string>
<string name="multiplayer_delete_space_sharing_link">Delete sharing link</string>
@ -1487,4 +1487,7 @@
<string name="gallery_experience_alert_button_space">Open space</string>
<string name="gallery_experience_alert_button_error">Close</string>
<string name="three_dots_text_placeholder">...</string>
</resources>

View file

@ -14,6 +14,7 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_models.restrictions.SpaceStatus
import com.anytypeio.anytype.core_utils.ext.allUniqueBy
@ -42,7 +43,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
class SelectSpaceViewModel(
private val storelessSubscriptionContainer: StorelessSubscriptionContainer,
private val container: StorelessSubscriptionContainer,
private val spaceManager: SpaceManager,
private val spaceGradientProvider: SpaceGradientProvider,
private val urlBuilder: UrlBuilder,
@ -57,7 +58,7 @@ class SelectSpaceViewModel(
private val profile = spaceManager
.observe()
.flatMapLatest { config ->
storelessSubscriptionContainer.subscribe(
container.subscribe(
StoreSearchByIdsParams(
subscription = SELECT_SPACE_PROFILE_SUBSCRIPTION,
keys = listOf(
@ -82,7 +83,7 @@ class SelectSpaceViewModel(
}
}
private val spaces: Flow<List<ObjectWrapper.Basic>> = storelessSubscriptionContainer.subscribe(
private val spaces: Flow<List<ObjectWrapper.SpaceView>> = container.subscribe(
StoreSearchParams(
subscription = SELECT_SPACE_SUBSCRIPTION,
keys = listOf(
@ -92,7 +93,8 @@ class SelectSpaceViewModel(
Relations.ICON_IMAGE,
Relations.ICON_EMOJI,
Relations.ICON_OPTION,
Relations.SPACE_ACCOUNT_STATUS
Relations.SPACE_ACCOUNT_STATUS,
Relations.SPACE_ACCESS_TYPE
),
filters = listOf(
DVFilter(
@ -131,7 +133,9 @@ class SelectSpaceViewModel(
"There were duplicated objects. Need to investigate this issue"
}
}
spaces.distinctBy { it.id }
spaces.distinctBy { it.id }.map { obj ->
ObjectWrapper.SpaceView(obj.map)
}
}
private fun buildUI() {
@ -160,7 +164,8 @@ class SelectSpaceViewModel(
icon = wrapper.spaceIcon(
builder = urlBuilder,
spaceGradientProvider = spaceGradientProvider
)
),
isShared = wrapper.spaceAccessType == SpaceAccessType.SHARED
)
)
} else {
@ -239,7 +244,7 @@ class SelectSpaceViewModel(
private fun proceedWithUnsubscribing() {
viewModelScope.launch {
storelessSubscriptionContainer.unsubscribe(
container.unsubscribe(
subscriptions = listOf(
SELECT_SPACE_PROFILE_SUBSCRIPTION,
SELECT_SPACE_SUBSCRIPTION
@ -260,7 +265,7 @@ class SelectSpaceViewModel(
override fun <T : ViewModel> create(
modelClass: Class<T>
) = SelectSpaceViewModel(
storelessSubscriptionContainer = storelessSubscriptionContainer,
container = storelessSubscriptionContainer,
spaceManager = spaceManager,
spaceGradientProvider = spaceGradientProvider,
urlBuilder = urlBuilder,
@ -282,7 +287,8 @@ data class WorkspaceView(
val space: Id,
val name: String?,
val isSelected: Boolean = false,
val icon: SpaceIconView
val isShared: Boolean,
val icon: SpaceIconView,
)
sealed class SelectSpaceView {

View file

@ -350,6 +350,11 @@ fun PrivateSpaceSharing(
modifier = Modifier
.height(52.dp)
.fillMaxWidth()
.noRippleClickable(
onClick = throttledClick(
onClick = { onSharePrivateSpaceClicked() }
)
)
) {
Text(
modifier = Modifier
@ -360,13 +365,7 @@ fun PrivateSpaceSharing(
style = BodyRegular
)
Row(
modifier = Modifier
.align(Alignment.CenterEnd)
.noRippleClickable(
onClick = throttledClick(
onClick = { onSharePrivateSpaceClicked() }
)
)
modifier = Modifier.align(Alignment.CenterEnd)
) {
Text(
modifier = Modifier.align(Alignment.CenterVertically),
@ -395,6 +394,11 @@ fun SharedSpaceSharing(
modifier = Modifier
.height(52.dp)
.fillMaxWidth()
.noRippleClickable(
onClick = throttledClick(
onClick = { onManageSharedSpaceClicked() }
)
)
) {
Text(
modifier = Modifier
@ -405,13 +409,7 @@ fun SharedSpaceSharing(
style = BodyRegular
)
Row(
modifier = Modifier
.align(Alignment.CenterEnd)
.noRippleClickable(
onClick = throttledClick(
onClick = { onManageSharedSpaceClicked() }
)
)
modifier = Modifier.align(Alignment.CenterEnd)
) {
Text(
modifier = Modifier.align(Alignment.CenterVertically),