feat: new add server sheet with server creation
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
67816d9cfe
commit
48e63e549a
|
|
@ -6,11 +6,14 @@ import chat.revolt.api.RevoltHttp
|
|||
import chat.revolt.api.RevoltJson
|
||||
import chat.revolt.api.api
|
||||
import chat.revolt.api.schemas.Member
|
||||
import chat.revolt.api.schemas.ServerWithChannelObjects
|
||||
import chat.revolt.api.schemas.User
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.client.request.put
|
||||
import io.ktor.client.request.setBody
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.SerializationException
|
||||
|
|
@ -91,3 +94,31 @@ suspend fun leaveOrDeleteServer(serverId: String, leaveSilently: Boolean = false
|
|||
parameter("leave_silently", leaveSilently)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ServerCreationBody(
|
||||
val name: String,
|
||||
val description: String? = null,
|
||||
val nsfw: Boolean = false
|
||||
)
|
||||
|
||||
suspend fun createServer(
|
||||
name: String,
|
||||
description: String = "",
|
||||
nsfw: Boolean = false
|
||||
): ServerWithChannelObjects {
|
||||
val body = ServerCreationBody(name, description, nsfw)
|
||||
|
||||
val response = RevoltHttp.post("/servers/create".api()) {
|
||||
setBody(RevoltJson.encodeToString(ServerCreationBody.serializer(), body))
|
||||
}
|
||||
|
||||
try {
|
||||
val error = RevoltJson.decodeFromString(RevoltError.serializer(), response.bodyAsText())
|
||||
throw Exception(error.type)
|
||||
} catch (e: SerializationException) {
|
||||
// Not an error
|
||||
}
|
||||
|
||||
return RevoltJson.decodeFromString(ServerWithChannelObjects.serializer(), response.bodyAsText())
|
||||
}
|
||||
|
|
@ -100,3 +100,27 @@ data class EmojiParent(
|
|||
val type: String? = null,
|
||||
val id: String? = null
|
||||
)
|
||||
|
||||
/**
|
||||
* Like [Server] but with complete channel objects instead of only IDs.
|
||||
*/
|
||||
@Serializable
|
||||
data class ServerWithChannelObjects(
|
||||
@SerialName("_id")
|
||||
val id: String? = null,
|
||||
val owner: String? = null,
|
||||
val name: String? = null,
|
||||
val description: String? = null,
|
||||
val channels: List<Channel>? = null,
|
||||
val categories: List<Category>? = null,
|
||||
@SerialName("system_messages")
|
||||
val systemMessages: SystemMessages? = null,
|
||||
val roles: Map<String, Role>? = null,
|
||||
@SerialName("default_permissions")
|
||||
val defaultPermissions: Long? = null,
|
||||
val icon: AutumnResource? = null,
|
||||
val banner: AutumnResource? = null,
|
||||
val flags: Long? = null,
|
||||
val analytics: Boolean? = null,
|
||||
val discoverable: Boolean? = null
|
||||
)
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package chat.revolt.composables.sheets
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ProvideTextStyle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Sheet selection. Used when a modal sheet prompts a choice out of x options.
|
||||
* The choices have an extended icon, a title and a description.
|
||||
* An end-facing chevron is shown on the end side of the row.
|
||||
*/
|
||||
@Composable
|
||||
fun SheetSelection(
|
||||
icon: @Composable () -> Unit,
|
||||
title: @Composable () -> Unit,
|
||||
description: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.clip(MaterialTheme.shapes.medium)
|
||||
.clickable(onClick = onClick)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
icon()
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 8.dp)
|
||||
.then(modifier)
|
||||
) {
|
||||
ProvideTextStyle(MaterialTheme.typography.titleMedium) {
|
||||
title()
|
||||
}
|
||||
ProvideTextStyle(MaterialTheme.typography.bodyMedium) {
|
||||
description()
|
||||
}
|
||||
}
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Default.KeyboardArrowRight,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package chat.revolt.composables.vectorassets
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
val CreateServer: ImageVector
|
||||
@Composable
|
||||
get() {
|
||||
if (_CreateServer != null) {
|
||||
return _CreateServer!!
|
||||
}
|
||||
_CreateServer = ImageVector.Builder(
|
||||
name = "CreateServer",
|
||||
defaultWidth = 605.dp,
|
||||
defaultHeight = 604.dp,
|
||||
viewportWidth = 605f,
|
||||
viewportHeight = 604f
|
||||
).apply {
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.primaryContainer)) {
|
||||
moveTo(270.33f, 36.02f)
|
||||
curveTo(287.45f, 16.89f, 317.41f, 16.89f, 334.54f, 36.02f)
|
||||
lineTo(374.1f, 80.21f)
|
||||
curveTo(382.83f, 89.96f, 395.52f, 95.22f, 408.59f, 94.5f)
|
||||
lineTo(467.8f, 91.22f)
|
||||
curveTo(493.45f, 89.8f, 514.63f, 110.99f, 513.21f, 136.63f)
|
||||
lineTo(509.94f, 195.85f)
|
||||
curveTo(509.22f, 208.91f, 514.47f, 221.6f, 524.22f, 230.34f)
|
||||
lineTo(568.41f, 269.89f)
|
||||
curveTo(587.54f, 287.02f, 587.54f, 316.98f, 568.41f, 334.11f)
|
||||
lineTo(524.22f, 373.67f)
|
||||
curveTo(514.47f, 382.4f, 509.22f, 395.08f, 509.94f, 408.15f)
|
||||
lineTo(513.21f, 467.37f)
|
||||
curveTo(514.63f, 493.01f, 493.45f, 514.2f, 467.8f, 512.78f)
|
||||
lineTo(408.59f, 509.5f)
|
||||
curveTo(395.52f, 508.78f, 382.83f, 514.04f, 374.1f, 523.79f)
|
||||
lineTo(334.54f, 567.97f)
|
||||
curveTo(317.41f, 587.11f, 287.45f, 587.11f, 270.33f, 567.97f)
|
||||
lineTo(230.77f, 523.79f)
|
||||
curveTo(222.04f, 514.04f, 209.35f, 508.78f, 196.28f, 509.5f)
|
||||
lineTo(137.07f, 512.78f)
|
||||
curveTo(111.42f, 514.2f, 90.24f, 493.01f, 91.66f, 467.37f)
|
||||
lineTo(94.93f, 408.15f)
|
||||
curveTo(95.65f, 395.08f, 90.4f, 382.4f, 80.64f, 373.67f)
|
||||
lineTo(36.46f, 334.11f)
|
||||
curveTo(17.32f, 316.98f, 17.32f, 287.02f, 36.46f, 269.89f)
|
||||
lineTo(80.64f, 230.34f)
|
||||
curveTo(90.4f, 221.6f, 95.65f, 208.91f, 94.93f, 195.85f)
|
||||
lineTo(91.66f, 136.63f)
|
||||
curveTo(90.24f, 110.99f, 111.42f, 89.8f, 137.07f, 91.22f)
|
||||
lineTo(196.28f, 94.5f)
|
||||
curveTo(209.35f, 95.22f, 222.04f, 89.96f, 230.77f, 80.21f)
|
||||
lineTo(270.33f, 36.02f)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.onPrimaryContainer)) {
|
||||
moveTo(285.02f, 404.6f)
|
||||
verticalLineTo(199.4f)
|
||||
horizontalLineTo(319.85f)
|
||||
verticalLineTo(404.6f)
|
||||
horizontalLineTo(285.02f)
|
||||
close()
|
||||
moveTo(199.83f, 319.41f)
|
||||
verticalLineTo(284.59f)
|
||||
horizontalLineTo(405.03f)
|
||||
verticalLineTo(319.41f)
|
||||
horizontalLineTo(199.83f)
|
||||
close()
|
||||
}
|
||||
}.build()
|
||||
|
||||
return _CreateServer!!
|
||||
}
|
||||
|
||||
@Suppress("ObjectPropertyName")
|
||||
private var _CreateServer: ImageVector? = null
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package chat.revolt.composables.vectorassets
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
val JoinServer: ImageVector
|
||||
@Composable
|
||||
get() {
|
||||
if (_JoinServer != null) {
|
||||
return _JoinServer!!
|
||||
}
|
||||
_JoinServer = ImageVector.Builder(
|
||||
name = "JoinServer",
|
||||
defaultWidth = 518.dp,
|
||||
defaultHeight = 338.dp,
|
||||
viewportWidth = 518f,
|
||||
viewportHeight = 338f
|
||||
).apply {
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.secondaryContainer)) {
|
||||
moveTo(196.04f, 208.6f)
|
||||
curveTo(174.16f, 186.73f, 174.16f, 151.27f, 196.04f, 129.4f)
|
||||
lineTo(308.76f, 16.68f)
|
||||
curveTo(330.63f, -5.19f, 366.08f, -5.19f, 387.95f, 16.68f)
|
||||
lineTo(500.68f, 129.4f)
|
||||
curveTo(522.55f, 151.27f, 522.55f, 186.73f, 500.68f, 208.6f)
|
||||
lineTo(387.95f, 321.32f)
|
||||
curveTo(366.08f, 343.19f, 330.63f, 343.19f, 308.76f, 321.32f)
|
||||
lineTo(196.04f, 208.6f)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.onSurface)) {
|
||||
moveTo(85.98f, 250.61f)
|
||||
lineTo(67.19f, 231.99f)
|
||||
lineTo(116.5f, 182.68f)
|
||||
horizontalLineTo(0.96f)
|
||||
verticalLineTo(155.32f)
|
||||
horizontalLineTo(116.5f)
|
||||
lineTo(67.19f, 106.09f)
|
||||
lineTo(85.98f, 87.39f)
|
||||
lineTo(167.59f, 169f)
|
||||
lineTo(85.98f, 250.61f)
|
||||
close()
|
||||
}
|
||||
}.build()
|
||||
|
||||
return _JoinServer!!
|
||||
}
|
||||
|
||||
@Suppress("ObjectPropertyName")
|
||||
private var _JoinServer: ImageVector? = null
|
||||
|
|
@ -0,0 +1,399 @@
|
|||
package chat.revolt.composables.vectorassets
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
val NewServer: ImageVector
|
||||
@Composable
|
||||
get() {
|
||||
if (_NewServer != null) {
|
||||
return _NewServer!!
|
||||
}
|
||||
_NewServer = ImageVector.Builder(
|
||||
name = "NewServer",
|
||||
defaultWidth = 570.dp,
|
||||
defaultHeight = 508.dp,
|
||||
viewportWidth = 570f,
|
||||
viewportHeight = 508f
|
||||
).apply {
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.primaryContainer)) {
|
||||
moveTo(131.17f, 166.37f)
|
||||
lineTo(131.17f, 166.37f)
|
||||
arcTo(
|
||||
131.03f,
|
||||
131.03f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
262.2f,
|
||||
297.4f
|
||||
)
|
||||
lineTo(262.2f, 297.4f)
|
||||
arcTo(
|
||||
131.03f,
|
||||
131.03f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
131.17f,
|
||||
428.43f
|
||||
)
|
||||
lineTo(131.17f, 428.43f)
|
||||
arcTo(
|
||||
131.03f,
|
||||
131.03f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
0.14f,
|
||||
297.4f
|
||||
)
|
||||
lineTo(0.14f, 297.4f)
|
||||
arcTo(
|
||||
131.03f,
|
||||
131.03f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
131.17f,
|
||||
166.37f
|
||||
)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.onPrimaryContainer)) {
|
||||
moveTo(87.36f, 357.23f)
|
||||
lineTo(92.08f, 330.64f)
|
||||
horizontalLineTo(65.48f)
|
||||
lineTo(67.81f, 317.34f)
|
||||
horizontalLineTo(94.4f)
|
||||
lineTo(101.45f, 277.45f)
|
||||
horizontalLineTo(74.86f)
|
||||
lineTo(77.18f, 264.15f)
|
||||
horizontalLineTo(103.78f)
|
||||
lineTo(108.5f, 237.56f)
|
||||
horizontalLineTo(121.79f)
|
||||
lineTo(117.07f, 264.15f)
|
||||
horizontalLineTo(156.96f)
|
||||
lineTo(161.68f, 237.56f)
|
||||
horizontalLineTo(174.98f)
|
||||
lineTo(170.26f, 264.15f)
|
||||
horizontalLineTo(196.85f)
|
||||
lineTo(194.53f, 277.45f)
|
||||
horizontalLineTo(167.93f)
|
||||
lineTo(160.89f, 317.34f)
|
||||
horizontalLineTo(187.48f)
|
||||
lineTo(185.15f, 330.64f)
|
||||
horizontalLineTo(158.56f)
|
||||
lineTo(153.84f, 357.23f)
|
||||
horizontalLineTo(140.54f)
|
||||
lineTo(145.26f, 330.64f)
|
||||
horizontalLineTo(105.37f)
|
||||
lineTo(100.65f, 357.23f)
|
||||
horizontalLineTo(87.36f)
|
||||
close()
|
||||
moveTo(114.75f, 277.45f)
|
||||
lineTo(107.7f, 317.34f)
|
||||
horizontalLineTo(147.59f)
|
||||
lineTo(154.64f, 277.45f)
|
||||
horizontalLineTo(114.75f)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.secondaryContainer)) {
|
||||
moveTo(369.52f, 314.28f)
|
||||
lineTo(369.52f, 314.28f)
|
||||
arcTo(
|
||||
96.66f,
|
||||
96.66f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
466.18f,
|
||||
410.94f
|
||||
)
|
||||
lineTo(466.18f, 410.94f)
|
||||
arcTo(
|
||||
96.66f,
|
||||
96.66f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
369.52f,
|
||||
507.6f
|
||||
)
|
||||
lineTo(369.52f, 507.6f)
|
||||
arcTo(
|
||||
96.66f,
|
||||
96.66f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
272.86f,
|
||||
410.94f
|
||||
)
|
||||
lineTo(272.86f, 410.94f)
|
||||
arcTo(
|
||||
96.66f,
|
||||
96.66f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
369.52f,
|
||||
314.28f
|
||||
)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.onSecondaryContainer)) {
|
||||
moveTo(389.14f, 441.79f)
|
||||
verticalLineTo(451.6f)
|
||||
horizontalLineTo(320.48f)
|
||||
verticalLineTo(441.79f)
|
||||
curveTo(320.48f, 441.79f, 320.48f, 422.18f, 354.81f, 422.18f)
|
||||
curveTo(389.14f, 422.18f, 389.14f, 441.79f, 389.14f, 441.79f)
|
||||
close()
|
||||
moveTo(371.97f, 395.2f)
|
||||
curveTo(371.97f, 391.81f, 370.97f, 388.49f, 369.08f, 385.67f)
|
||||
curveTo(367.2f, 382.84f, 364.51f, 380.64f, 361.38f, 379.35f)
|
||||
curveTo(358.24f, 378.05f, 354.79f, 377.71f, 351.46f, 378.37f)
|
||||
curveTo(348.13f, 379.03f, 345.07f, 380.67f, 342.67f, 383.07f)
|
||||
curveTo(340.27f, 385.47f, 338.64f, 388.52f, 337.97f, 391.86f)
|
||||
curveTo(337.31f, 395.18f, 337.65f, 398.64f, 338.95f, 401.77f)
|
||||
curveTo(340.25f, 404.91f, 342.45f, 407.59f, 345.27f, 409.48f)
|
||||
curveTo(348.1f, 411.36f, 351.41f, 412.37f, 354.81f, 412.37f)
|
||||
curveTo(359.36f, 412.37f, 363.73f, 410.56f, 366.95f, 407.34f)
|
||||
curveTo(370.17f, 404.12f, 371.97f, 399.76f, 371.97f, 395.2f)
|
||||
close()
|
||||
moveTo(388.84f, 422.18f)
|
||||
curveTo(391.86f, 424.51f, 394.33f, 427.48f, 396.07f, 430.86f)
|
||||
curveTo(397.82f, 434.25f, 398.8f, 437.98f, 398.95f, 441.79f)
|
||||
verticalLineTo(451.6f)
|
||||
horizontalLineTo(418.57f)
|
||||
verticalLineTo(441.79f)
|
||||
curveTo(418.57f, 441.79f, 418.57f, 423.99f, 388.84f, 422.18f)
|
||||
close()
|
||||
moveTo(384.23f, 378.04f)
|
||||
curveTo(380.86f, 378.02f, 377.56f, 379.03f, 374.77f, 380.93f)
|
||||
curveTo(377.75f, 385.09f, 379.35f, 390.08f, 379.35f, 395.2f)
|
||||
curveTo(379.35f, 400.32f, 377.75f, 405.31f, 374.77f, 409.48f)
|
||||
curveTo(377.56f, 411.38f, 380.86f, 412.38f, 384.23f, 412.37f)
|
||||
curveTo(388.79f, 412.37f, 393.15f, 410.56f, 396.37f, 407.34f)
|
||||
curveTo(399.59f, 404.12f, 401.4f, 399.76f, 401.4f, 395.2f)
|
||||
curveTo(401.4f, 390.65f, 399.59f, 386.29f, 396.37f, 383.07f)
|
||||
curveTo(393.15f, 379.85f, 388.79f, 378.04f, 384.23f, 378.04f)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.errorContainer)) {
|
||||
moveTo(202.3f, 40.46f)
|
||||
lineTo(202.3f, 40.46f)
|
||||
arcTo(
|
||||
59.91f,
|
||||
59.91f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
262.2f,
|
||||
100.36f
|
||||
)
|
||||
lineTo(262.2f, 100.36f)
|
||||
arcTo(
|
||||
59.91f,
|
||||
59.91f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
202.3f,
|
||||
160.27f
|
||||
)
|
||||
lineTo(202.3f, 160.27f)
|
||||
arcTo(
|
||||
59.91f,
|
||||
59.91f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
142.39f,
|
||||
100.36f
|
||||
)
|
||||
lineTo(142.39f, 100.36f)
|
||||
arcTo(
|
||||
59.91f,
|
||||
59.91f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
202.3f,
|
||||
40.46f
|
||||
)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.onErrorContainer)) {
|
||||
moveTo(202.3f, 67.27f)
|
||||
curveTo(203.91f, 67.27f, 205.46f, 67.91f, 206.6f, 69.05f)
|
||||
curveTo(207.74f, 70.19f, 208.38f, 71.73f, 208.38f, 73.34f)
|
||||
curveTo(208.38f, 75.59f, 207.16f, 77.57f, 205.34f, 78.6f)
|
||||
verticalLineTo(82.46f)
|
||||
horizontalLineTo(208.38f)
|
||||
curveTo(214.02f, 82.46f, 219.43f, 84.71f, 223.42f, 88.7f)
|
||||
curveTo(227.41f, 92.69f, 229.65f, 98.1f, 229.65f, 103.74f)
|
||||
horizontalLineTo(232.69f)
|
||||
curveTo(233.5f, 103.74f, 234.27f, 104.06f, 234.84f, 104.63f)
|
||||
curveTo(235.41f, 105.2f, 235.73f, 105.97f, 235.73f, 106.78f)
|
||||
verticalLineTo(115.9f)
|
||||
curveTo(235.73f, 116.71f, 235.41f, 117.48f, 234.84f, 118.05f)
|
||||
curveTo(234.27f, 118.62f, 233.5f, 118.94f, 232.69f, 118.94f)
|
||||
horizontalLineTo(229.65f)
|
||||
verticalLineTo(121.98f)
|
||||
curveTo(229.65f, 123.59f, 229.01f, 125.14f, 227.87f, 126.28f)
|
||||
curveTo(226.73f, 127.42f, 225.19f, 128.06f, 223.57f, 128.06f)
|
||||
horizontalLineTo(181.02f)
|
||||
curveTo(179.41f, 128.06f, 177.86f, 127.42f, 176.72f, 126.28f)
|
||||
curveTo(175.58f, 125.14f, 174.94f, 123.59f, 174.94f, 121.98f)
|
||||
verticalLineTo(118.94f)
|
||||
horizontalLineTo(171.9f)
|
||||
curveTo(171.1f, 118.94f, 170.32f, 118.62f, 169.75f, 118.05f)
|
||||
curveTo(169.18f, 117.48f, 168.86f, 116.71f, 168.86f, 115.9f)
|
||||
verticalLineTo(106.78f)
|
||||
curveTo(168.86f, 105.97f, 169.18f, 105.2f, 169.75f, 104.63f)
|
||||
curveTo(170.32f, 104.06f, 171.1f, 103.74f, 171.9f, 103.74f)
|
||||
horizontalLineTo(174.94f)
|
||||
curveTo(174.94f, 98.1f, 177.18f, 92.69f, 181.17f, 88.7f)
|
||||
curveTo(185.16f, 84.71f, 190.57f, 82.46f, 196.22f, 82.46f)
|
||||
horizontalLineTo(199.26f)
|
||||
verticalLineTo(78.6f)
|
||||
curveTo(197.43f, 77.57f, 196.22f, 75.59f, 196.22f, 73.34f)
|
||||
curveTo(196.22f, 71.73f, 196.86f, 70.19f, 198f, 69.05f)
|
||||
curveTo(199.14f, 67.91f, 200.68f, 67.27f, 202.3f, 67.27f)
|
||||
close()
|
||||
moveTo(188.62f, 100.7f)
|
||||
curveTo(186.6f, 100.7f, 184.67f, 101.5f, 183.25f, 102.93f)
|
||||
curveTo(181.82f, 104.35f, 181.02f, 106.29f, 181.02f, 108.3f)
|
||||
curveTo(181.02f, 110.32f, 181.82f, 112.25f, 183.25f, 113.67f)
|
||||
curveTo(184.67f, 115.1f, 186.6f, 115.9f, 188.62f, 115.9f)
|
||||
curveTo(190.63f, 115.9f, 192.57f, 115.1f, 193.99f, 113.67f)
|
||||
curveTo(195.42f, 112.25f, 196.22f, 110.32f, 196.22f, 108.3f)
|
||||
curveTo(196.22f, 106.29f, 195.42f, 104.35f, 193.99f, 102.93f)
|
||||
curveTo(192.57f, 101.5f, 190.63f, 100.7f, 188.62f, 100.7f)
|
||||
close()
|
||||
moveTo(215.98f, 100.7f)
|
||||
curveTo(213.96f, 100.7f, 212.03f, 101.5f, 210.6f, 102.93f)
|
||||
curveTo(209.18f, 104.35f, 208.38f, 106.29f, 208.38f, 108.3f)
|
||||
curveTo(208.38f, 110.32f, 209.18f, 112.25f, 210.6f, 113.67f)
|
||||
curveTo(212.03f, 115.1f, 213.96f, 115.9f, 215.98f, 115.9f)
|
||||
curveTo(217.99f, 115.9f, 219.92f, 115.1f, 221.35f, 113.67f)
|
||||
curveTo(222.77f, 112.25f, 223.57f, 110.32f, 223.57f, 108.3f)
|
||||
curveTo(223.57f, 106.29f, 222.77f, 104.35f, 221.35f, 102.93f)
|
||||
curveTo(219.92f, 101.5f, 217.99f, 100.7f, 215.98f, 100.7f)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.tertiaryContainer)) {
|
||||
moveTo(421.36f, 0.4f)
|
||||
lineTo(421.36f, 0.4f)
|
||||
arcTo(
|
||||
148.5f,
|
||||
148.5f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
569.86f,
|
||||
148.9f
|
||||
)
|
||||
lineTo(569.86f, 148.9f)
|
||||
arcTo(
|
||||
148.5f,
|
||||
148.5f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
421.36f,
|
||||
297.4f
|
||||
)
|
||||
lineTo(421.36f, 297.4f)
|
||||
arcTo(
|
||||
148.5f,
|
||||
148.5f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
272.86f,
|
||||
148.9f
|
||||
)
|
||||
lineTo(272.86f, 148.9f)
|
||||
arcTo(
|
||||
148.5f,
|
||||
148.5f,
|
||||
0f,
|
||||
isMoreThanHalf = false,
|
||||
isPositiveArc = true,
|
||||
421.36f,
|
||||
0.4f
|
||||
)
|
||||
close()
|
||||
}
|
||||
path(fill = SolidColor(MaterialTheme.colorScheme.onTertiaryContainer)) {
|
||||
moveTo(421.36f, 171.5f)
|
||||
curveTo(427.47f, 171.5f, 432.67f, 169.24f, 437.26f, 164.8f)
|
||||
curveTo(441.71f, 160.2f, 443.97f, 155f, 443.97f, 148.9f)
|
||||
curveTo(443.97f, 142.8f, 441.71f, 137.6f, 437.26f, 133f)
|
||||
curveTo(432.67f, 128.56f, 427.47f, 126.3f, 421.36f, 126.3f)
|
||||
curveTo(415.26f, 126.3f, 410.06f, 128.56f, 405.47f, 133f)
|
||||
curveTo(401.02f, 137.6f, 398.76f, 142.8f, 398.76f, 148.9f)
|
||||
curveTo(398.76f, 155f, 401.02f, 160.2f, 405.47f, 164.8f)
|
||||
curveTo(410.06f, 169.24f, 415.26f, 171.5f, 421.36f, 171.5f)
|
||||
close()
|
||||
moveTo(421.36f, 73.56f)
|
||||
curveTo(442.08f, 73.56f, 459.79f, 81.09f, 474.48f, 95.78f)
|
||||
curveTo(489.17f, 110.47f, 496.71f, 128.18f, 496.71f, 148.9f)
|
||||
verticalLineTo(159.83f)
|
||||
curveTo(496.71f, 167.36f, 494.07f, 173.76f, 489.17f, 179.04f)
|
||||
curveTo(483.9f, 184.09f, 477.87f, 186.57f, 470.34f, 186.57f)
|
||||
curveTo(461.3f, 186.57f, 453.84f, 182.81f, 448.19f, 175.27f)
|
||||
curveTo(440.65f, 182.81f, 431.76f, 186.57f, 421.36f, 186.57f)
|
||||
curveTo(411.04f, 186.57f, 402.15f, 182.81f, 394.69f, 175.57f)
|
||||
curveTo(387.46f, 168.11f, 383.69f, 159.3f, 383.69f, 148.9f)
|
||||
curveTo(383.69f, 138.58f, 387.46f, 129.69f, 394.69f, 122.23f)
|
||||
curveTo(402.15f, 115f, 411.04f, 111.23f, 421.36f, 111.23f)
|
||||
curveTo(431.76f, 111.23f, 440.58f, 115f, 448.04f, 122.23f)
|
||||
curveTo(455.27f, 129.69f, 459.04f, 138.58f, 459.04f, 148.9f)
|
||||
verticalLineTo(159.83f)
|
||||
curveTo(459.04f, 162.91f, 460.24f, 165.63f, 462.5f, 167.96f)
|
||||
curveTo(464.76f, 170.3f, 467.4f, 171.5f, 470.34f, 171.5f)
|
||||
curveTo(473.5f, 171.5f, 476.14f, 170.3f, 478.4f, 167.96f)
|
||||
curveTo(480.66f, 165.63f, 481.64f, 162.91f, 481.64f, 159.83f)
|
||||
verticalLineTo(148.9f)
|
||||
curveTo(481.64f, 132.4f, 475.84f, 118.24f, 463.93f, 106.33f)
|
||||
curveTo(452.03f, 94.43f, 437.86f, 88.62f, 421.36f, 88.62f)
|
||||
curveTo(404.86f, 88.62f, 390.7f, 94.43f, 378.8f, 106.33f)
|
||||
curveTo(366.89f, 118.24f, 361.09f, 132.4f, 361.09f, 148.9f)
|
||||
curveTo(361.09f, 165.4f, 366.89f, 179.57f, 378.8f, 191.47f)
|
||||
curveTo(390.7f, 203.38f, 404.86f, 209.18f, 421.36f, 209.18f)
|
||||
horizontalLineTo(459.04f)
|
||||
verticalLineTo(224.24f)
|
||||
horizontalLineTo(421.36f)
|
||||
curveTo(400.64f, 224.24f, 382.94f, 216.71f, 368.25f, 202.02f)
|
||||
curveTo(353.55f, 187.33f, 346.02f, 169.62f, 346.02f, 148.9f)
|
||||
curveTo(346.02f, 128.18f, 353.55f, 110.47f, 368.25f, 95.78f)
|
||||
curveTo(382.94f, 81.09f, 400.64f, 73.56f, 421.36f, 73.56f)
|
||||
close()
|
||||
}
|
||||
}.build()
|
||||
|
||||
return _NewServer!!
|
||||
}
|
||||
|
||||
@Suppress("ObjectPropertyName")
|
||||
private var _NewServer: ImageVector? = null
|
||||
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun NewServerPreview() {
|
||||
Image(
|
||||
imageVector = NewServer,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
|
|
@ -517,7 +517,11 @@ fun ChatRouterScreen(
|
|||
showAddServerSheet = false
|
||||
}
|
||||
) {
|
||||
AddServerSheet()
|
||||
AddServerSheet(
|
||||
onDismiss = {
|
||||
showAddServerSheet = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,165 +2,493 @@ package chat.revolt.sheets
|
|||
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.input.TextFieldLineLimits
|
||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ExitToApp
|
||||
import androidx.compose.material.icons.filled.Build
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.PathEffect
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import chat.revolt.R
|
||||
import chat.revolt.activities.InviteActivity
|
||||
import chat.revolt.api.REVOLT_APP
|
||||
import chat.revolt.composables.generic.FormTextField
|
||||
import chat.revolt.composables.generic.SheetButton
|
||||
import chat.revolt.composables.generic.SheetHeaderPadding
|
||||
import chat.revolt.api.routes.server.createServer
|
||||
import chat.revolt.callbacks.Action
|
||||
import chat.revolt.callbacks.ActionChannel
|
||||
import chat.revolt.composables.sheets.SheetSelection
|
||||
import chat.revolt.composables.vectorassets.CreateServer
|
||||
import chat.revolt.composables.vectorassets.JoinServer
|
||||
import chat.revolt.composables.vectorassets.NewServer
|
||||
import chat.revolt.material.EasingTokens
|
||||
import chat.revolt.screens.chat.ChatRouterDestination
|
||||
import chat.revolt.ui.theme.FragmentMono
|
||||
import kotlinx.coroutines.launch
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
enum class AddServerSheetStep(val animationValue: Int) {
|
||||
Initial(0),
|
||||
JoinFromInvite(1),
|
||||
CreateServer(1)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AddServerSheet() {
|
||||
fun AddServerSheet(onDismiss: () -> Unit) {
|
||||
var currentStep by remember { mutableStateOf(AddServerSheetStep.Initial) }
|
||||
val context = LocalContext.current
|
||||
|
||||
val joinFromInviteModalOpen = remember { mutableStateOf(false) }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
if (joinFromInviteModalOpen.value) {
|
||||
JoinFromInviteModal(
|
||||
onDismiss = {
|
||||
joinFromInviteModalOpen.value = false
|
||||
AnimatedContent(
|
||||
currentStep,
|
||||
transitionSpec = {
|
||||
if (targetState.animationValue > initialState.animationValue) {
|
||||
(slideInHorizontally(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate),
|
||||
initialOffsetX = { fullWidth -> fullWidth }
|
||||
) + fadeIn(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate)
|
||||
)) togetherWith (slideOutHorizontally(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate),
|
||||
targetOffsetX = { fullWidth -> -fullWidth }
|
||||
) + fadeOut(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate)
|
||||
))
|
||||
} else {
|
||||
(slideInHorizontally(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate),
|
||||
initialOffsetX = { fullWidth -> -fullWidth }
|
||||
) + fadeIn(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate)
|
||||
)) togetherWith (slideOutHorizontally(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate),
|
||||
targetOffsetX = { fullWidth -> fullWidth }
|
||||
) + fadeOut(
|
||||
animationSpec = tween(300, 0, EasingTokens.EmphasizedDecelerate)
|
||||
))
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
modifier = Modifier.animateContentSize(
|
||||
animationSpec = tween(150, 0, EasingTokens.EmphasizedDecelerate)
|
||||
)
|
||||
}
|
||||
|
||||
SheetHeaderPadding {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_title),
|
||||
style = MaterialTheme.typography.headlineSmall
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
SheetButton(
|
||||
headlineContent = {
|
||||
Text(stringResource(id = R.string.add_server_sheet_join_by_invite))
|
||||
},
|
||||
leadingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Default.ExitToApp,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
joinFromInviteModalOpen.value = true
|
||||
}
|
||||
)
|
||||
|
||||
SheetButton(
|
||||
headlineContent = {
|
||||
Text(stringResource(id = R.string.add_server_sheet_create_new))
|
||||
},
|
||||
leadingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Build,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(
|
||||
R.string.add_server_sheet_create_new_modal_under_construction
|
||||
),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun JoinFromInviteModal(onDismiss: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val inviteCode = remember { mutableStateOf("") }
|
||||
|
||||
val inviteActivityResult = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) { result ->
|
||||
Log.d("InviteActivity", "Result: $result")
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = {
|
||||
Text(text = stringResource(id = R.string.add_server_sheet_join_by_invite_modal_title))
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = R.string.add_server_sheet_join_by_invite_modal_description
|
||||
)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
FormTextField(
|
||||
label = stringResource(
|
||||
id = R.string.add_server_sheet_join_by_invite_modal_hint
|
||||
),
|
||||
value = inviteCode.value,
|
||||
onChange = {
|
||||
inviteCode.value = it
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
val intent = Intent(context, InviteActivity::class.java)
|
||||
intent.data = if (inviteCode.value.startsWith("https://")) {
|
||||
inviteCode.value.toUri()
|
||||
} else {
|
||||
"https://$REVOLT_APP/invite/${inviteCode.value}".toUri()
|
||||
}
|
||||
inviteActivityResult.launch(intent)
|
||||
}
|
||||
) { step ->
|
||||
Box(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_join_by_invite_modal_join)
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onDismiss()
|
||||
if (step == AddServerSheetStep.Initial) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Image(
|
||||
imageVector = NewServer,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.5f)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_0_title),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_0_description),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = LocalContentColor.current.copy(alpha = 0.7f),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
SheetSelection(
|
||||
icon = {
|
||||
Image(
|
||||
imageVector = JoinServer,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_0_join)
|
||||
)
|
||||
},
|
||||
description = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_0_join_description)
|
||||
)
|
||||
},
|
||||
) {
|
||||
currentStep = AddServerSheetStep.JoinFromInvite
|
||||
}
|
||||
|
||||
SheetSelection(
|
||||
icon = {
|
||||
Image(
|
||||
imageVector = CreateServer,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_0_create)
|
||||
)
|
||||
},
|
||||
description = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_0_create_description)
|
||||
)
|
||||
},
|
||||
) {
|
||||
currentStep = AddServerSheetStep.CreateServer
|
||||
}
|
||||
}
|
||||
} else if (step == AddServerSheetStep.JoinFromInvite) {
|
||||
val inviteState = rememberTextFieldState()
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_title),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
IconButton(
|
||||
onClick = {
|
||||
currentStep = AddServerSheetStep.Initial
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Default.ArrowBack,
|
||||
contentDescription = stringResource(id = R.string.back),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_description),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = LocalContentColor.current.copy(alpha = 0.7f),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_examples_heading),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_example_1),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
fontFamily = FragmentMono,
|
||||
modifier = Modifier
|
||||
.clip(
|
||||
MaterialTheme.shapes.small.copy(
|
||||
topStart = MaterialTheme.shapes.large.topStart,
|
||||
topEnd = MaterialTheme.shapes.large.topEnd,
|
||||
)
|
||||
)
|
||||
.background(MaterialTheme.colorScheme.surfaceContainerHighest)
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth()
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_example_2),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
fontFamily = FragmentMono,
|
||||
modifier = Modifier
|
||||
.clip(
|
||||
MaterialTheme.shapes.small
|
||||
)
|
||||
.background(MaterialTheme.colorScheme.surfaceContainerHighest)
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth()
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_example_3),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
fontFamily = FragmentMono,
|
||||
modifier = Modifier
|
||||
.clip(
|
||||
MaterialTheme.shapes.small.copy(
|
||||
bottomStart = MaterialTheme.shapes.large.bottomStart,
|
||||
bottomEnd = MaterialTheme.shapes.large.bottomEnd,
|
||||
)
|
||||
)
|
||||
.background(MaterialTheme.colorScheme.surfaceContainerHighest)
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
TextField(
|
||||
state = inviteState,
|
||||
label = {
|
||||
Text(stringResource(R.string.add_server_sheet_step_1j_label))
|
||||
},
|
||||
lineLimits = TextFieldLineLimits.SingleLine,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp, horizontal = 8.dp)
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
val intent = Intent(context, InviteActivity::class.java)
|
||||
intent.data = if (inviteState.text.startsWith("https://")) {
|
||||
try {
|
||||
inviteState.text.toString().toUri()
|
||||
} catch (e: Exception) {
|
||||
Log.e(
|
||||
"AddServerSheet",
|
||||
"Invalid URL: ${inviteState.text}",
|
||||
e
|
||||
)
|
||||
return@Button
|
||||
}
|
||||
} else {
|
||||
"https://$REVOLT_APP/invite/${inviteState.text}".toUri()
|
||||
}
|
||||
context.startActivity(intent)
|
||||
|
||||
onDismiss()
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1j_join)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (step == AddServerSheetStep.CreateServer) {
|
||||
val serverNameState = rememberTextFieldState()
|
||||
val serverNameIsBlank = remember(serverNameState.text) {
|
||||
serverNameState.text.isBlank()
|
||||
}
|
||||
|
||||
var serverNameRangeError by remember { mutableStateOf(false) }
|
||||
var serverCreationError by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(serverNameState.text) {
|
||||
if (serverNameState.text.length > 32) {
|
||||
serverNameRangeError = true
|
||||
} else {
|
||||
serverNameRangeError = false
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1c_title),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
IconButton(
|
||||
onClick = {
|
||||
currentStep = AddServerSheetStep.Initial
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Default.ArrowBack,
|
||||
contentDescription = stringResource(id = R.string.back),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1c_description),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = LocalContentColor.current.copy(alpha = 0.7f),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
val outline = MaterialTheme.colorScheme.outline
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Canvas(Modifier.size(80.dp)) {
|
||||
val stroke = Stroke(
|
||||
width = 4.dp.toPx(),
|
||||
pathEffect = PathEffect.dashPathEffect(
|
||||
floatArrayOf(30f, 40f),
|
||||
0f
|
||||
)
|
||||
)
|
||||
|
||||
drawCircle(
|
||||
color = outline,
|
||||
style = stroke,
|
||||
radius = size.minDimension / 2 - stroke.width / 2
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = when {
|
||||
serverNameIsBlank -> stringResource(R.string.add_server_sheet_step_1c_name_placeholder)
|
||||
else -> serverNameState.text.toString()
|
||||
},
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = LocalContentColor.current.copy(
|
||||
alpha = when {
|
||||
serverNameIsBlank -> 0.5f
|
||||
else -> 1f
|
||||
}
|
||||
),
|
||||
fontWeight = when {
|
||||
serverNameIsBlank -> FontWeight.Medium
|
||||
else -> FontWeight.Bold
|
||||
},
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
TextField(
|
||||
state = serverNameState,
|
||||
label = {
|
||||
Text(stringResource(R.string.add_server_sheet_step_1c_name))
|
||||
},
|
||||
lineLimits = TextFieldLineLimits.SingleLine,
|
||||
supportingText = {
|
||||
Text(
|
||||
when {
|
||||
serverCreationError -> stringResource(R.string.add_server_sheet_step_1c_error)
|
||||
serverNameRangeError -> stringResource(
|
||||
R.string.add_server_sheet_step_1c_name_error_range,
|
||||
32
|
||||
)
|
||||
|
||||
else -> ""
|
||||
}
|
||||
)
|
||||
},
|
||||
isError = serverNameRangeError || serverCreationError,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp, horizontal = 8.dp)
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
serverCreationError = false
|
||||
|
||||
scope.launch {
|
||||
try {
|
||||
val server = createServer(serverNameState.text.toString())
|
||||
|
||||
// Backend should've already created a channel for us to go to
|
||||
server.channels?.first()?.id?.let {
|
||||
ActionChannel.send(
|
||||
Action.ChatNavigate(
|
||||
ChatRouterDestination.Channel(it)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
onDismiss()
|
||||
} catch (e: Exception) {
|
||||
serverCreationError = true
|
||||
logcat { "Error creating server: ${e.asLog()}" }
|
||||
}
|
||||
}
|
||||
},
|
||||
enabled = !serverNameIsBlank && !serverNameRangeError,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.add_server_sheet_step_1c_create)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.cancel))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,15 +435,27 @@
|
|||
<string name="user_badge_reserved_relevant_joke_badge_1" translatable="false">sus</string>
|
||||
<string name="user_badge_reserved_relevant_joke_badge_2" translatable="false">It\'s Morbin Time</string>
|
||||
|
||||
<string name="add_server_sheet_title">Add a server</string>
|
||||
<string name="add_server_sheet_join_by_invite">Join by invite code or link</string>
|
||||
<string name="add_server_sheet_join_by_invite_modal_title">Invite code or link</string>
|
||||
<string name="add_server_sheet_join_by_invite_modal_description">Enter a link like rvlt.gg/Testers or an invite code like Testers</string>
|
||||
<string name="add_server_sheet_join_by_invite_modal_hint">Invite code or link</string>
|
||||
<string name="add_server_sheet_join_by_invite_modal_join">Join</string>
|
||||
<string name="add_server_sheet_create_new">Create a new server</string>
|
||||
<string name="add_server_sheet_create_new_modal_title">Create a new server</string>
|
||||
<string name="add_server_sheet_create_new_modal_under_construction">This feature is currently under construction.</string>
|
||||
<string name="add_server_sheet_step_0_title">Add Server</string>
|
||||
<string name="add_server_sheet_step_0_description">A server is where the magic happens. Chat with your friends, share memes, build communities, and more.</string>
|
||||
<string name="add_server_sheet_step_0_join">Join by invite code or link</string>
|
||||
<string name="add_server_sheet_step_0_join_description">You already have an invite code to join an existing server.</string>
|
||||
<string name="add_server_sheet_step_0_create">Create a new server</string>
|
||||
<string name="add_server_sheet_step_0_create_description">You want to create a completely new server from scratch.</string>
|
||||
<string name="add_server_sheet_step_1j_title">Join with an Invite</string>
|
||||
<string name="add_server_sheet_step_1j_description">If you have an invite code or link, you can join a server right now.</string>
|
||||
<string name="add_server_sheet_step_1j_examples_heading">Examples of invite codes include:</string>
|
||||
<string name="add_server_sheet_step_1j_example_1" translatable="false">rvlt.gg/Testers</string>
|
||||
<string name="add_server_sheet_step_1j_example_2" translatable="false">Testers</string>
|
||||
<string name="add_server_sheet_step_1j_example_3" translatable="false">app.revolt.chat/invite/Testers</string>
|
||||
<string name="add_server_sheet_step_1j_label">Invite code or link</string>
|
||||
<string name="add_server_sheet_step_1j_join">Join</string>
|
||||
<string name="add_server_sheet_step_1c_title">Create a Server</string>
|
||||
<string name="add_server_sheet_step_1c_description">You can always customise the name or icon and invite your friends later.</string>
|
||||
<string name="add_server_sheet_step_1c_name">Server Name</string>
|
||||
<string name="add_server_sheet_step_1c_name_placeholder">My Server</string>
|
||||
<string name="add_server_sheet_step_1c_name_error_range">Server name can be up to %1$d characters in length.</string>
|
||||
<string name="add_server_sheet_step_1c_error">An error occurred while creating your server. Please try again later.</string>
|
||||
<string name="add_server_sheet_step_1c_create">Create</string>
|
||||
|
||||
<string name="discover">Discover Revolt</string>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue