feat: user action buttons
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
adba9da754
commit
9159f33c3b
|
|
@ -28,6 +28,7 @@ import chat.revolt.api.realtime.frames.receivable.UserUpdateFrame
|
||||||
import chat.revolt.api.realtime.frames.sendable.AuthorizationFrame
|
import chat.revolt.api.realtime.frames.sendable.AuthorizationFrame
|
||||||
import chat.revolt.api.realtime.frames.sendable.PingFrame
|
import chat.revolt.api.realtime.frames.sendable.PingFrame
|
||||||
import chat.revolt.api.routes.server.fetchMember
|
import chat.revolt.api.routes.server.fetchMember
|
||||||
|
import chat.revolt.api.schemas.Channel
|
||||||
import chat.revolt.api.settings.GlobalState
|
import chat.revolt.api.settings.GlobalState
|
||||||
import chat.revolt.api.settings.SyncedSettings
|
import chat.revolt.api.settings.SyncedSettings
|
||||||
import io.ktor.client.plugins.websocket.ws
|
import io.ktor.client.plugins.websocket.ws
|
||||||
|
|
@ -304,6 +305,18 @@ object RealtimeSocket {
|
||||||
existing.mergeWithPartial(channelUpdateFrame.data)
|
existing.mergeWithPartial(channelUpdateFrame.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"ChannelCreate" -> {
|
||||||
|
val channelCreateFrame =
|
||||||
|
RevoltJson.decodeFromString(Channel.serializer(), rawFrame)
|
||||||
|
|
||||||
|
Log.d(
|
||||||
|
"RealtimeSocket",
|
||||||
|
"Received channel create frame for ${channelCreateFrame.id}, with name ${channelCreateFrame.name}. Adding to cache."
|
||||||
|
)
|
||||||
|
|
||||||
|
RevoltAPI.channelCache[channelCreateFrame.id!!] = channelCreateFrame
|
||||||
|
}
|
||||||
|
|
||||||
"ChannelAck" -> {
|
"ChannelAck" -> {
|
||||||
val channelAckFrame =
|
val channelAckFrame =
|
||||||
RevoltJson.decodeFromString(ChannelAckFrame.serializer(), rawFrame)
|
RevoltJson.decodeFromString(ChannelAckFrame.serializer(), rawFrame)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package chat.revolt.api.routes.user
|
||||||
|
|
||||||
|
import chat.revolt.api.RevoltError
|
||||||
|
import chat.revolt.api.RevoltHttp
|
||||||
|
import chat.revolt.api.RevoltJson
|
||||||
|
import chat.revolt.api.schemas.Channel
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.statement.bodyAsText
|
||||||
|
import kotlinx.serialization.SerializationException
|
||||||
|
|
||||||
|
suspend fun openDM(userId: String): Channel {
|
||||||
|
val response = RevoltHttp.get("/users/$userId/dm")
|
||||||
|
.bodyAsText()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val error = RevoltJson.decodeFromString(RevoltError.serializer(), response)
|
||||||
|
throw Error(error.type)
|
||||||
|
} catch (e: SerializationException) {
|
||||||
|
// Not an error
|
||||||
|
}
|
||||||
|
|
||||||
|
return RevoltJson.decodeFromString(Channel.serializer(), response)
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
package chat.revolt.api.routes.user
|
package chat.revolt.api.routes.user
|
||||||
|
|
||||||
import chat.revolt.api.RevoltAPI
|
|
||||||
import chat.revolt.api.RevoltError
|
import chat.revolt.api.RevoltError
|
||||||
import chat.revolt.api.RevoltHttp
|
import chat.revolt.api.RevoltHttp
|
||||||
import chat.revolt.api.RevoltJson
|
import chat.revolt.api.RevoltJson
|
||||||
import io.ktor.client.request.delete
|
import io.ktor.client.request.delete
|
||||||
|
import io.ktor.client.request.post
|
||||||
import io.ktor.client.request.put
|
import io.ktor.client.request.put
|
||||||
|
import io.ktor.client.request.setBody
|
||||||
import io.ktor.client.statement.bodyAsText
|
import io.ktor.client.statement.bodyAsText
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.http.contentType
|
||||||
import kotlinx.serialization.SerializationException
|
import kotlinx.serialization.SerializationException
|
||||||
import kotlin.collections.set
|
|
||||||
|
|
||||||
suspend fun blockUser(userId: String) {
|
suspend fun blockUser(userId: String) {
|
||||||
val response = RevoltHttp.put("/users/$userId/block")
|
val response = RevoltHttp.put("/users/$userId/block")
|
||||||
|
|
@ -20,9 +22,6 @@ suspend fun blockUser(userId: String) {
|
||||||
} catch (e: SerializationException) {
|
} catch (e: SerializationException) {
|
||||||
// Not an error
|
// Not an error
|
||||||
}
|
}
|
||||||
|
|
||||||
val user = RevoltAPI.userCache[userId] ?: return
|
|
||||||
RevoltAPI.userCache[userId] = user.copy(relationship = "Blocked")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unblockUser(userId: String) {
|
suspend fun unblockUser(userId: String) {
|
||||||
|
|
@ -35,9 +34,33 @@ suspend fun unblockUser(userId: String) {
|
||||||
} catch (e: SerializationException) {
|
} catch (e: SerializationException) {
|
||||||
// Not an error
|
// Not an error
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val user = RevoltAPI.userCache[userId] ?: return
|
suspend fun friendUser(username: String) {
|
||||||
RevoltAPI.userCache[userId] = user.copy(relationship = "None")
|
val response = RevoltHttp.post("/users/friend") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(mapOf("username" to username))
|
||||||
|
}
|
||||||
|
val body = response.bodyAsText()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val error = RevoltJson.decodeFromString(RevoltError.serializer(), body)
|
||||||
|
throw Error(error.type)
|
||||||
|
} catch (e: SerializationException) {
|
||||||
|
// Not an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun acceptFriendRequest(userId: String) {
|
||||||
|
val response = RevoltHttp.put("/users/$userId/friend")
|
||||||
|
.bodyAsText()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val error = RevoltJson.decodeFromString(RevoltError.serializer(), response)
|
||||||
|
throw Error(error.type)
|
||||||
|
} catch (e: SerializationException) {
|
||||||
|
// Not an error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unfriendUser(userId: String) {
|
suspend fun unfriendUser(userId: String) {
|
||||||
|
|
@ -50,7 +73,4 @@ suspend fun unfriendUser(userId: String) {
|
||||||
} catch (e: SerializationException) {
|
} catch (e: SerializationException) {
|
||||||
// Not an error
|
// Not an error
|
||||||
}
|
}
|
||||||
|
|
||||||
val user = RevoltAPI.userCache[userId] ?: return
|
|
||||||
RevoltAPI.userCache[userId] = user.copy(relationship = "None")
|
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,8 @@ sealed class Action {
|
||||||
data class SwitchChannel(val channelId: String) : Action()
|
data class SwitchChannel(val channelId: String) : Action()
|
||||||
data class LinkInfo(val url: String) : Action()
|
data class LinkInfo(val url: String) : Action()
|
||||||
data class EmoteInfo(val emoteId: String) : Action()
|
data class EmoteInfo(val emoteId: String) : Action()
|
||||||
|
data class TopNavigate(val route: String) : Action()
|
||||||
|
data class ChatNavigate(val route: String) : Action()
|
||||||
}
|
}
|
||||||
|
|
||||||
val ActionChannel = Channel<Action>(
|
val ActionChannel = Channel<Action>(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
package chat.revolt.components.screens.settings
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
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.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import chat.revolt.R
|
||||||
|
import chat.revolt.api.RevoltAPI
|
||||||
|
import chat.revolt.api.routes.user.acceptFriendRequest
|
||||||
|
import chat.revolt.api.routes.user.blockUser
|
||||||
|
import chat.revolt.api.routes.user.friendUser
|
||||||
|
import chat.revolt.api.routes.user.openDM
|
||||||
|
import chat.revolt.api.routes.user.unblockUser
|
||||||
|
import chat.revolt.api.routes.user.unfriendUser
|
||||||
|
import chat.revolt.api.schemas.User
|
||||||
|
import chat.revolt.callbacks.Action
|
||||||
|
import chat.revolt.callbacks.ActionChannel
|
||||||
|
import chat.revolt.internals.Platform
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun UserButtons(
|
||||||
|
user: User,
|
||||||
|
dismissSheet: suspend () -> Unit
|
||||||
|
) {
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val context = LocalContext.current
|
||||||
|
val clipboard = LocalClipboardManager.current
|
||||||
|
|
||||||
|
var menuOpen by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
if (user.id == null) return Row {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
friendUser("${user.username}#${user.discriminator}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_add_friend))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
when (user.relationship) {
|
||||||
|
"None" -> {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
friendUser("${user.username}#${user.discriminator}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_add_friend))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"User" -> {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
ActionChannel.send(Action.TopNavigate("settings/profile"))
|
||||||
|
// We must now close the bottom sheet,
|
||||||
|
// else we will crash if we try to open this sheet again
|
||||||
|
dismissSheet()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_edit_profile))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Friend" -> {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
val dm = openDM(user.id)
|
||||||
|
if (dm.id != null) {
|
||||||
|
if (RevoltAPI.channelCache[dm.id] == null)
|
||||||
|
RevoltAPI.channelCache[dm.id] = dm
|
||||||
|
ActionChannel.send(Action.SwitchChannel(dm.id))
|
||||||
|
dismissSheet()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.user_info_sheet_failed_to_open_dm),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_send_message))
|
||||||
|
}
|
||||||
|
// Remove friend (in overflow menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
"Outgoing" -> {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
unfriendUser(user.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_cancel_request))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Incoming" -> {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
acceptFriendRequest(user.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_accept_request))
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
unfriendUser(user.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.error,
|
||||||
|
contentColor = MaterialTheme.colorScheme.onError,
|
||||||
|
),
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_decline_request))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Blocked" -> {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
unblockUser(user.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_unblock))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when (user.relationship) {
|
||||||
|
"Friend", "Incoming", "Outgoing", "None" -> {
|
||||||
|
Column { // Prevent the dropdown menu from counting towards arrangement spacing
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
menuOpen = true
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.MoreVert,
|
||||||
|
contentDescription = stringResource(R.string.menu)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
DropdownMenu(expanded = menuOpen, onDismissRequest = { menuOpen = false }) {
|
||||||
|
when (user.relationship) {
|
||||||
|
"Friend" -> {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_remove_friend))
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
unfriendUser(user.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_block))
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
blockUser(user.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_copy_id))
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
clipboard.setText(AnnotatedString(user.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = {
|
||||||
|
Text(stringResource(R.string.user_info_sheet_report))
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
scope.launch {
|
||||||
|
ActionChannel.send(Action.ChatNavigate("report/user/${user.id}"))
|
||||||
|
|
||||||
|
if (Platform.needsShowClipboardNotification()) {
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.copied),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.DismissibleDrawerSheet
|
import androidx.compose.material3.DismissibleDrawerSheet
|
||||||
import androidx.compose.material3.DismissibleNavigationDrawer
|
import androidx.compose.material3.DismissibleNavigationDrawer
|
||||||
import androidx.compose.material3.DrawerState
|
import androidx.compose.material3.DrawerState
|
||||||
|
|
@ -439,6 +440,14 @@ fun ChatRouterScreen(
|
||||||
emoteInfoSheetTarget = action.emoteId
|
emoteInfoSheetTarget = action.emoteId
|
||||||
showEmoteInfoSheet = true
|
showEmoteInfoSheet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is Action.TopNavigate -> {
|
||||||
|
topNav.navigate(action.route)
|
||||||
|
}
|
||||||
|
|
||||||
|
is Action.ChatNavigate -> {
|
||||||
|
navController.navigate(action.route)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -586,7 +595,11 @@ fun ChatRouterScreen(
|
||||||
) {
|
) {
|
||||||
UserInfoSheet(
|
UserInfoSheet(
|
||||||
userId = userContextSheetTarget,
|
userId = userContextSheetTarget,
|
||||||
serverId = userContextSheetServer
|
serverId = userContextSheetServer,
|
||||||
|
dismissSheet = {
|
||||||
|
userContextSheetState.hide()
|
||||||
|
showUserContextSheet = false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -954,6 +967,7 @@ fun Sidebar(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ChannelNavigator(
|
fun ChannelNavigator(
|
||||||
navController: NavHostController,
|
navController: NavHostController,
|
||||||
|
|
@ -1032,6 +1046,22 @@ fun ChannelNavigator(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialog("report/user/{userId}") { backStackEntry ->
|
||||||
|
val userId = backStackEntry.arguments?.getString("userId")
|
||||||
|
if (userId != null) {
|
||||||
|
AlertDialog(onDismissRequest = {
|
||||||
|
navController.popBackStack()
|
||||||
|
}) {
|
||||||
|
Text("Report user $userId")
|
||||||
|
Button(onClick = {
|
||||||
|
navController.popBackStack()
|
||||||
|
}) {
|
||||||
|
Text("Close")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@ fun ProfileSettingsScreen(
|
||||||
},
|
},
|
||||||
label = {
|
label = {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.user_context_sheet_category_bio),
|
text = stringResource(id = R.string.user_info_sheet_category_bio),
|
||||||
style = MaterialTheme.typography.labelLarge,
|
style = MaterialTheme.typography.labelLarge,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,11 @@ fun MemberListSheet(
|
||||||
) {
|
) {
|
||||||
UserInfoSheet(
|
UserInfoSheet(
|
||||||
userId = userContextSheetTarget,
|
userId = userContextSheetTarget,
|
||||||
serverId = serverId
|
serverId = serverId,
|
||||||
|
dismissSheet = {
|
||||||
|
userContextSheetState.hide()
|
||||||
|
showUserContextSheet = false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,15 @@ import chat.revolt.components.chat.RoleChip
|
||||||
import chat.revolt.components.generic.NonIdealState
|
import chat.revolt.components.generic.NonIdealState
|
||||||
import chat.revolt.components.generic.WebMarkdown
|
import chat.revolt.components.generic.WebMarkdown
|
||||||
import chat.revolt.components.screens.settings.RawUserOverview
|
import chat.revolt.components.screens.settings.RawUserOverview
|
||||||
|
import chat.revolt.components.screens.settings.UserButtons
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserInfoSheet(userId: String, serverId: String? = null) {
|
fun UserInfoSheet(
|
||||||
|
userId: String,
|
||||||
|
serverId: String? = null,
|
||||||
|
dismissSheet: suspend () -> Unit
|
||||||
|
) {
|
||||||
val user = RevoltAPI.userCache[userId]
|
val user = RevoltAPI.userCache[userId]
|
||||||
|
|
||||||
val member = serverId?.let { RevoltAPI.members.getMember(it, userId) }
|
val member = serverId?.let { RevoltAPI.members.getMember(it, userId) }
|
||||||
|
|
@ -73,12 +78,12 @@ fun UserInfoSheet(userId: String, serverId: String? = null) {
|
||||||
},
|
},
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.user_context_sheet_user_not_found)
|
text = stringResource(R.string.user_info_sheet_user_not_found)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
description = {
|
description = {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.user_context_sheet_user_not_found_description)
|
text = stringResource(R.string.user_info_sheet_user_not_found_description)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -94,9 +99,14 @@ fun UserInfoSheet(userId: String, serverId: String? = null) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 8.dp)
|
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 8.dp)
|
||||||
) {
|
) {
|
||||||
|
UserButtons(
|
||||||
|
user,
|
||||||
|
dismissSheet
|
||||||
|
)
|
||||||
|
|
||||||
member?.roles?.let {
|
member?.roles?.let {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.user_context_sheet_category_roles),
|
text = stringResource(id = R.string.user_info_sheet_category_roles),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
modifier = Modifier.padding(vertical = 10.dp)
|
modifier = Modifier.padding(vertical = 10.dp)
|
||||||
)
|
)
|
||||||
|
|
@ -121,7 +131,7 @@ fun UserInfoSheet(userId: String, serverId: String? = null) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.user_context_sheet_category_bio),
|
text = stringResource(id = R.string.user_info_sheet_category_bio),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
modifier = Modifier.padding(vertical = 10.dp)
|
modifier = Modifier.padding(vertical = 10.dp)
|
||||||
)
|
)
|
||||||
|
|
@ -133,12 +143,12 @@ fun UserInfoSheet(userId: String, serverId: String? = null) {
|
||||||
)
|
)
|
||||||
} else if (profile != null) {
|
} else if (profile != null) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.user_context_sheet_bio_empty),
|
text = stringResource(id = R.string.user_info_sheet_bio_empty),
|
||||||
color = LocalContentColor.current.copy(alpha = 0.6f)
|
color = LocalContentColor.current.copy(alpha = 0.6f)
|
||||||
)
|
)
|
||||||
} else if (profileNotFound) {
|
} else if (profileNotFound) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.user_context_sheet_bio_not_found),
|
text = stringResource(id = R.string.user_info_sheet_bio_not_found),
|
||||||
color = LocalContentColor.current.copy(alpha = 0.6f)
|
color = LocalContentColor.current.copy(alpha = 0.6f)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -270,12 +270,25 @@
|
||||||
<string name="server_context_sheet_actions_leave_confirm_no">Stay</string>
|
<string name="server_context_sheet_actions_leave_confirm_no">Stay</string>
|
||||||
<string name="server_context_sheet_actions_leave_silently">Leave Silently</string>
|
<string name="server_context_sheet_actions_leave_silently">Leave Silently</string>
|
||||||
|
|
||||||
<string name="user_context_sheet_user_not_found">Can\'t resolve this user</string>
|
<string name="user_info_sheet_user_not_found">Can\'t resolve this user</string>
|
||||||
<string name="user_context_sheet_user_not_found_description">This user may have been deleted or you may not have permission to view them.</string>
|
<string name="user_info_sheet_user_not_found_description">This user may have been deleted or you may not have permission to view them.</string>
|
||||||
<string name="user_context_sheet_category_bio">Bio</string>
|
<string name="user_info_sheet_category_bio">Bio</string>
|
||||||
<string name="user_context_sheet_bio_empty">This user hasn\'t set a bio yet.</string>
|
<string name="user_info_sheet_bio_empty">This user hasn\'t set a bio yet.</string>
|
||||||
<string name="user_context_sheet_bio_not_found">This user\'s bio could not be fetched. Please verify you share a server or are friends.</string>
|
<string name="user_info_sheet_bio_not_found">This user\'s bio could not be fetched. Please verify you share a server or are friends.</string>
|
||||||
<string name="user_context_sheet_category_roles">Roles</string>
|
<string name="user_info_sheet_category_roles">Roles</string>
|
||||||
|
<string name="user_info_sheet_add_friend">Add Friend</string>
|
||||||
|
<string name="user_info_sheet_send_message">Send Message</string>
|
||||||
|
<string name="user_info_sheet_remove_friend">Remove Friend</string>
|
||||||
|
<string name="user_info_sheet_accept_request">Accept</string>
|
||||||
|
<string name="user_info_sheet_decline_request">Decline</string>
|
||||||
|
<string name="user_info_sheet_cancel_request">Cancel Request</string>
|
||||||
|
<string name="user_info_sheet_block">Block</string>
|
||||||
|
<string name="user_info_sheet_unblock">Unblock</string>
|
||||||
|
<string name="user_info_sheet_edit_profile">Edit Profile</string>
|
||||||
|
<string name="user_info_sheet_report">Report</string>
|
||||||
|
<string name="user_info_sheet_copy_id">Copy ID</string>
|
||||||
|
<string name="user_info_sheet_failed_to_open_dm">Could not open DM with this user.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="add_server_sheet_title">Add a server</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">Join by invite code or link</string>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue