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

DROID-2255 Multiplayer | Design | Layout for sharing invite link (#917)

This commit is contained in:
Evgenii Kozlov 2024-02-24 16:35:09 +01:00 committed by GitHub
parent 90f3964a50
commit f0409d1e0e
Signed by: github
GPG key ID: B5690EEEBB952194
10 changed files with 168 additions and 19 deletions

View file

@ -0,0 +1,6 @@
package com.anytypeio.anytype.core_models.multiplayer
data class SpaceInviteLink(
val fileKey: String,
val cid: String
)

View file

@ -0,0 +1,101 @@
package com.anytypeio.anytype.core_ui.features.multiplayer
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.foundation.Divider
import com.anytypeio.anytype.core_ui.views.BodyCalloutRegular
import com.anytypeio.anytype.core_ui.views.ButtonPrimary
import com.anytypeio.anytype.core_ui.views.ButtonSize
import com.anytypeio.anytype.core_ui.views.Title1
@Composable
@Preview
fun ShareInviteLinkCardPreview() {
ShareInviteLinkCard(
link = "https://anytype.io/ibafyrfhfsag6rea3ifffsasssa3ifffsasssga3ifffsasssga3ifffsas",
onShareInviteClicked = {},
)
}
@Composable
fun ShareInviteLinkCard(
link: String,
onShareInviteClicked: () -> Unit
) {
Card {
Spacer(modifier = Modifier.height(20.dp))
Row(
modifier = Modifier.padding(horizontal = 20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(R.string.multiplayer_invite_link),
style = Title1,
color = colorResource(id = R.color.text_primary),
modifier = Modifier.weight(1.0f)
)
Image(
painter = painterResource(id = R.drawable.ic_action_replace),
contentDescription = "Regenerate-invite icon"
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(R.string.multiplayer_share_invite_link_description),
style = BodyCalloutRegular,
color = colorResource(id = R.color.text_primary),
modifier = Modifier.padding(horizontal = 20.dp)
)
Spacer(modifier = Modifier.height(8.dp))
Box(
modifier = Modifier
.padding(horizontal = 20.dp)
.height(48.dp)
.fillMaxWidth(),
contentAlignment = Alignment.CenterStart
) {
Text(
text = link,
style = BodyCalloutRegular,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = colorResource(id = R.color.text_secondary),
modifier = Modifier.fillMaxWidth()
)
}
Divider()
Spacer(modifier = Modifier.height(16.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
ButtonPrimary(
text = stringResource(R.string.multiplayer_share_invite_link),
onClick = onShareInviteClicked,
size = ButtonSize.Large,
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
)
}
Spacer(modifier = Modifier.height(20.dp))
}
}

View file

@ -1,22 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="25"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0.5234,0h24v24h-24z"/>
<path
android:pathData="M6.0631,14C6.9237,16.8915 9.6022,19 12.7733,19C15.9443,19 18.6228,16.8915 19.4834,14H21.0366C20.1372,17.7294 16.7788,20.5 12.7733,20.5C8.7677,20.5 5.4093,17.7294 4.5099,14H6.0631ZM19.4834,10C18.6228,7.1085 15.9443,5 12.7733,5C9.6022,5 6.9237,7.1085 6.0631,10H4.5099C5.4093,6.2706 8.7677,3.5 12.7733,3.5C16.7788,3.5 20.1372,6.2706 21.0366,10H19.4834Z"
android:fillColor="#ACA996"
android:fillType="evenOdd"/>
<path
android:pathData="M20.7734,4C20.3592,4 20.0234,4.3358 20.0234,4.75V8.5H16.2734C15.8592,8.5 15.5234,8.8358 15.5234,9.25C15.5234,9.6642 15.8592,10 16.2734,10H21.5234V4.75C21.5234,4.3358 21.1877,4 20.7734,4Z"
android:fillColor="#ACA996"
android:fillType="evenOdd"/>
<path
android:pathData="M4.2734,20C4.6877,20 5.0234,19.6642 5.0234,19.25V15.5H8.7734C9.1876,15.5 9.5234,15.1642 9.5234,14.75C9.5234,14.3358 9.1876,14 8.7734,14H3.5234V19.25C3.5234,19.6642 3.8592,20 4.2734,20Z"
android:fillColor="#ACA996"
android:fillType="evenOdd"/>
</group>
<path
android:pathData="M4.135,9.5C5.194,6.166 8.315,3.75 12,3.75C15.125,3.75 17.845,5.488 19.244,8.05H15.8C15.386,8.05 15.05,8.386 15.05,8.8C15.05,9.119 15.249,9.392 15.53,9.5H21.55V8.8V3.8C21.55,3.386 21.214,3.05 20.8,3.05C20.386,3.05 20.05,3.386 20.05,3.8V6.497C18.293,3.933 15.343,2.25 12,2.25C7.479,2.25 3.677,5.327 2.573,9.5H4.135ZM8.07,14.5H2.05V15.2V20.2C2.05,20.614 2.386,20.95 2.8,20.95C3.214,20.95 3.55,20.614 3.55,20.2L3.55,16.868C5.235,19.786 8.388,21.75 12,21.75C16.52,21.75 20.322,18.674 21.426,14.5H19.864C18.805,17.834 15.685,20.25 12,20.25C8.874,20.25 6.155,18.512 4.755,15.95H7.8C8.214,15.95 8.55,15.614 8.55,15.2C8.55,14.881 8.351,14.608 8.07,14.5Z"
android:fillColor="@color/glyph_active"
android:fillType="evenOdd"/>
</vector>

View file

@ -24,6 +24,7 @@ import com.anytypeio.anytype.core_models.SearchResult
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.Url
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteLink
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.data.auth.exception.AnytypeNeedsUpgradeException
import com.anytypeio.anytype.data.auth.exception.NotFoundObjectException
@ -898,4 +899,8 @@ class BlockDataRepository(
override suspend fun deleteRelationOption(command: Command.DeleteRelationOptions) {
return remote.deleteRelationOption(command)
}
override suspend fun generateSpaceInviteLink(space: SpaceId): SpaceInviteLink {
return remote.generateSpaceInviteLink(space)
}
}

View file

@ -23,6 +23,7 @@ import com.anytypeio.anytype.core_models.SearchResult
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.Url
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteLink
import com.anytypeio.anytype.core_models.primitives.SpaceId
interface BlockRemote {
@ -382,4 +383,6 @@ interface BlockRemote {
suspend fun debugStackGoroutines(path: String)
suspend fun deleteRelationOption(command: Command.DeleteRelationOptions)
suspend fun generateSpaceInviteLink(space: SpaceId) : SpaceInviteLink
}

View file

@ -24,6 +24,7 @@ import com.anytypeio.anytype.core_models.SearchResult
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.Url
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteLink
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.domain.base.Result
import com.anytypeio.anytype.domain.block.interactor.sets.CreateObjectSet
@ -429,4 +430,6 @@ interface BlockRepository {
suspend fun createTemplateFromObject(ctx: Id): Id
suspend fun debugStackGoroutines(path: String)
suspend fun deleteRelationOption(command: Command.DeleteRelationOptions)
suspend fun generateSpaceInviteLink(space: SpaceId) : SpaceInviteLink
}

View file

@ -0,0 +1,16 @@
package com.anytypeio.anytype.domain.multiplayer
import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteLink
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
class GenerateSpaceInviteLink(
private val dispatchers: AppCoroutineDispatchers,
private val repo: BlockRepository
): ResultInteractor<SpaceId, SpaceInviteLink>(dispatchers.io) {
override suspend fun doWork(params: SpaceId): SpaceInviteLink = repo.generateSpaceInviteLink(
space = params
)
}

View file

@ -1294,9 +1294,15 @@
<string name="network_settings_provide_config_hint">Tap to provide your network config</string>
<string name="network_settings_self_host_config">Current config: %1$s</string>
<!--endregion-->
<!--region MULTIPLAYER -->
<string name="multiplayer_share_invite_link">Share invite link</string>
<string name="multiplayer_share_invite_link_description">Send this link to invite others. Assign access rights upon their request approval</string>
<string name="multiplayer_invite_link">Invite link</string>
<!--endregion-->
</resources>

View file

@ -24,6 +24,7 @@ import com.anytypeio.anytype.core_models.SearchResult
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.Url
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteLink
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.data.auth.repo.block.BlockRemote
import com.anytypeio.anytype.middleware.interactor.Middleware
@ -859,4 +860,8 @@ class BlockMiddleware(
override suspend fun deleteRelationOption(command: Command.DeleteRelationOptions) {
return middleware.deleteRelationOptions(command)
}
override suspend fun generateSpaceInviteLink(space: SpaceId): SpaceInviteLink {
return middleware.generateSpaceInviteLink(space)
}
}

View file

@ -29,6 +29,7 @@ import com.anytypeio.anytype.core_models.SearchResult
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.Url
import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteLink
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_utils.tools.ThreadInfo
import com.anytypeio.anytype.middleware.BuildConfig
@ -2366,6 +2367,21 @@ class Middleware @Inject constructor(
if (BuildConfig.DEBUG) logResponse(response)
}
@Throws(Exception::class)
fun generateSpaceInviteLink(space: SpaceId) : SpaceInviteLink {
val request = Rpc.Space.InviteGenerate.Request(
spaceId = space.id
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.spaceInviteGenerate(request)
if (BuildConfig.DEBUG) logResponse(response)
return SpaceInviteLink(
cid = response.inviteCid,
fileKey= response.inviteFileKey
)
}
private fun logRequest(any: Any) {
logger.logRequest(any).also {
if (BuildConfig.DEBUG && threadInfo.isOnMainThread()) {