diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt
new file mode 100644
index 0000000000..fad13fecd1
--- /dev/null
+++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt
@@ -0,0 +1,6 @@
+package com.anytypeio.anytype.core_models.multiplayer
+
+data class SpaceInviteLink(
+ val fileKey: String,
+ val cid: String
+)
\ No newline at end of file
diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/multiplayer/Inviting.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/multiplayer/Inviting.kt
new file mode 100644
index 0000000000..020051d4d8
--- /dev/null
+++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/multiplayer/Inviting.kt
@@ -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))
+ }
+}
\ No newline at end of file
diff --git a/core-ui/src/main/res/drawable/ic_action_replace.xml b/core-ui/src/main/res/drawable/ic_action_replace.xml
index ed28553cdb..7263dac11c 100644
--- a/core-ui/src/main/res/drawable/ic_action_replace.xml
+++ b/core-ui/src/main/res/drawable/ic_action_replace.xml
@@ -1,22 +1,10 @@
-
-
-
-
-
-
+
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 a27c598bdd..fe776ce59d 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
@@ -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)
+ }
}
\ No newline at end of file
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 c4ff67582a..a8eab0a56d 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
@@ -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
}
\ No newline at end of file
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 54c0d8f1f3..8da8a0dd6b 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
@@ -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
}
\ No newline at end of file
diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/multiplayer/GenerateSpaceInviteLink.kt b/domain/src/main/java/com/anytypeio/anytype/domain/multiplayer/GenerateSpaceInviteLink.kt
new file mode 100644
index 0000000000..c7dce3fc60
--- /dev/null
+++ b/domain/src/main/java/com/anytypeio/anytype/domain/multiplayer/GenerateSpaceInviteLink.kt
@@ -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(dispatchers.io) {
+ override suspend fun doWork(params: SpaceId): SpaceInviteLink = repo.generateSpaceInviteLink(
+ space = params
+ )
+}
\ No newline at end of file
diff --git a/localization/src/main/res/values/strings.xml b/localization/src/main/res/values/strings.xml
index 8bcbccc3a6..5b17290421 100644
--- a/localization/src/main/res/values/strings.xml
+++ b/localization/src/main/res/values/strings.xml
@@ -1294,9 +1294,15 @@
Tap to provide your network config
Current config: %1$s
-
+
+
+ Share invite link
+ Send this link to invite others. Assign access rights upon their request approval
+ Invite link
+
+
\ No newline at end of file
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 c8df07dd86..dc2bf80e2e 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
@@ -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)
+ }
}
\ No newline at end of file
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 2969d92037..67e9f8b53a 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
@@ -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()) {