refactor: Update ShareTargetActivity and ChannelSideDrawer for improved user context handling
This commit refines the user context handling in ShareTargetActivity and ChannelSideDrawer components. - Modified the onOpenUserInfoSheet callback in ShareTargetActivity to accept a user ID parameter. - Enhanced ChannelSideDrawer to utilize the updated onOpenUserInfoSheet callback for better user context interactions. - Adjusted the ModalBottomSheet state in ChannelSideDrawer to skip partially expanded states for improved user experience. - Cleaned up unused code and improved overall readability in the affected files.
This commit is contained in:
parent
48513b761b
commit
d639048b5c
|
|
@ -352,7 +352,7 @@ fun ShareTargetScreen(
|
|||
hasUnread = false,
|
||||
onDestinationChanged = { selectedChannel = channel.id },
|
||||
onOpenChannelContextSheet = {},
|
||||
onOpenUserInfoSheet = {}
|
||||
onOpenUserInfoSheet = {_ ->}
|
||||
)
|
||||
|
||||
else -> ChannelItem(
|
||||
|
|
|
|||
|
|
@ -192,7 +192,9 @@ fun ChannelSideDrawer(
|
|||
}
|
||||
|
||||
if (userContextSheetTarget != null) {
|
||||
val userContextSheetState = rememberModalBottomSheetState()
|
||||
val userContextSheetState = rememberModalBottomSheetState(
|
||||
skipPartiallyExpanded = true,
|
||||
)
|
||||
ModalBottomSheet(
|
||||
sheetState = userContextSheetState,
|
||||
onDismissRequest = {
|
||||
|
|
@ -826,8 +828,8 @@ private fun ColumnScope.DirectMessagesChannelListRenderer(
|
|||
onDestinationChanged = { dest ->
|
||||
onDestinationChanged(dest)
|
||||
},
|
||||
onOpenChannelContextSheet = onOpenUserInfoSheet,
|
||||
onOpenUserInfoSheet = onOpenUserInfoSheet
|
||||
onOpenChannelContextSheet = {},
|
||||
onOpenUserInfoSheet = {userId -> onOpenUserInfoSheet(userId)}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,95 +250,5 @@ fun UserButtons(
|
|||
|
||||
"BlockedOther" -> Box(Modifier.weight(1f))
|
||||
}
|
||||
|
||||
if (user.relationship != "User") {
|
||||
Row { // Prevent the dropdown menu from counting towards arrangement spacing
|
||||
DropdownMenu(
|
||||
expanded = menuOpen,
|
||||
onDismissRequest = { menuOpen = false }
|
||||
) {
|
||||
when (user.relationship) {
|
||||
"Friend" -> {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(stringResource(R.string.user_info_sheet_remove_friend))
|
||||
},
|
||||
onClick = {
|
||||
scope.launch {
|
||||
try {
|
||||
unfriendUser(user.id)
|
||||
} catch (e: Exception) {
|
||||
if (e.message == "NoEffect") return@launch
|
||||
logcat(LogPriority.ERROR) { e.asLog() }
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
when (user.relationship) {
|
||||
"Blocked" -> {}
|
||||
|
||||
else -> DropdownMenuItem(
|
||||
text = {
|
||||
Text(stringResource(R.string.user_info_sheet_block))
|
||||
},
|
||||
onClick = {
|
||||
scope.launch {
|
||||
try {
|
||||
blockUser(user.id)
|
||||
} catch (e: Exception) {
|
||||
if (e.message == "NoEffect") return@launch
|
||||
logcat(LogPriority.ERROR) { e.asLog() }
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
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.ReportUser(user.id))
|
||||
|
||||
if (Platform.needsShowClipboardNotification()) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.copied),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
menuOpen = true
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_more_vert_24dp),
|
||||
contentDescription = stringResource(R.string.menu)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ private fun NotificationOptionButton(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun NotificationRadioRow(
|
||||
fun NotificationRadioRow(
|
||||
title: String,
|
||||
type: NotificationType,
|
||||
channelId: String,
|
||||
|
|
|
|||
|
|
@ -1,24 +1,29 @@
|
|||
package chat.peptide.sheets
|
||||
|
||||
import android.text.format.DateUtils
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
|
||||
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
|
||||
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.SmallFloatingActionButton
|
||||
|
|
@ -29,35 +34,42 @@ 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.graphics.Brush
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.peptide.R
|
||||
import chat.peptide.api.PeptideAPI
|
||||
import chat.peptide.api.internals.BrushCompat
|
||||
import chat.peptide.api.internals.ULID
|
||||
import chat.peptide.api.internals.solidColor
|
||||
import chat.peptide.api.routes.user.fetchUserProfile
|
||||
import chat.peptide.api.routes.user.blockUser
|
||||
import chat.peptide.api.routes.user.getOrFetchUser
|
||||
import chat.peptide.api.schemas.Profile
|
||||
import chat.peptide.api.routes.user.unfriendUser
|
||||
import chat.peptide.api.schemas.ChannelType
|
||||
import chat.peptide.api.schemas.NotificationSettings
|
||||
import chat.peptide.api.settings.Experiments
|
||||
import chat.peptide.api.settings.FeatureFlags
|
||||
import chat.peptide.composables.chat.RoleListEntry
|
||||
import chat.peptide.composables.chat.UserBadgeList
|
||||
import chat.peptide.composables.chat.UserBadgeRow
|
||||
import chat.peptide.api.settings.NotificationType
|
||||
import chat.peptide.api.settings.SyncedSettings
|
||||
import chat.peptide.callbacks.Action
|
||||
import chat.peptide.callbacks.ActionChannel
|
||||
import chat.peptide.composables.generic.NonIdealState
|
||||
import chat.peptide.composables.generic.SheetButton
|
||||
import chat.peptide.composables.generic.UserAvatar
|
||||
import chat.peptide.composables.markdown.RichMarkdown
|
||||
import chat.peptide.composables.screens.settings.RawUserOverview
|
||||
import chat.peptide.composables.screens.settings.UserButtons
|
||||
import chat.peptide.composables.sheets.SheetTile
|
||||
import kotlinx.datetime.Instant
|
||||
import chat.peptide.internals.Platform
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import logcat.LogPriority
|
||||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -82,20 +94,6 @@ fun UserInfoSheet(
|
|||
|
||||
val server = PeptideAPI.serverCache[serverId]
|
||||
|
||||
var profile by remember { mutableStateOf<Profile?>(null) }
|
||||
var profileNotFound by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(resolvedUser) {
|
||||
try {
|
||||
resolvedUser?.id?.let { fetchUserProfile(it) }?.let { profile = it }
|
||||
} catch (e: Exception) {
|
||||
if (e.message == "NotFound") {
|
||||
profileNotFound = true
|
||||
}
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedUser == null) {
|
||||
NonIdealState(
|
||||
icon = {
|
||||
|
|
@ -144,288 +142,363 @@ fun UserInfoSheet(
|
|||
}
|
||||
}
|
||||
|
||||
LazyVerticalStaggeredGrid(
|
||||
columns = StaggeredGridCells.Fixed(2),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalItemSpacing = 16.dp,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
item(key = "overview", span = StaggeredGridItemSpan.FullLine) {
|
||||
Box {
|
||||
RawUserOverview(resolvedUser!!, profile, internalPadding = false)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.padding(top = 8.dp, end = 8.dp)
|
||||
) {
|
||||
if (Experiments.enableServerIdentityOptions.isEnabled) {
|
||||
SmallFloatingActionButton(
|
||||
onClick = { showServerIdentityOptions = true },
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_psychology_alt_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
// Page state: 0 = main, 1 = notifications
|
||||
var page by remember { mutableStateOf(0) }
|
||||
|
||||
if (FeatureFlags.userCardsGranted) {
|
||||
SmallFloatingActionButton(
|
||||
onClick = { showUserCard = true },
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_badge_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
AnimatedContent(
|
||||
targetState = page,
|
||||
transitionSpec = {
|
||||
if (targetState > initialState) {
|
||||
slideInHorizontally(animationSpec = tween(200)) { it } togetherWith
|
||||
slideOutHorizontally(animationSpec = tween(200)) { -it }
|
||||
} else {
|
||||
slideInHorizontally(animationSpec = tween(200)) { -it } togetherWith
|
||||
slideOutHorizontally(animationSpec = tween(200)) { it }
|
||||
}
|
||||
}
|
||||
|
||||
member?.roles?.let {
|
||||
item(key = "roles") {
|
||||
SheetTile(
|
||||
header = {
|
||||
Text(stringResource(R.string.user_info_sheet_category_roles))
|
||||
},
|
||||
contentPreview = {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
it
|
||||
.map { roleId -> server?.roles?.get(roleId) }
|
||||
.sortedBy { it?.rank ?: 0.0 }
|
||||
.take(3)
|
||||
.forEach { role ->
|
||||
role?.let {
|
||||
RoleListEntry(
|
||||
label = role.name ?: "null",
|
||||
brush = role.colour?.let { BrushCompat.parseColour(it) }
|
||||
?: Brush.solidColor(LocalContentColor.current)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
it
|
||||
.map { roleId -> server?.roles?.get(roleId) }
|
||||
.sortedBy { it?.rank ?: 0.0 }
|
||||
.forEach { role ->
|
||||
role?.let {
|
||||
RoleListEntry(
|
||||
label = role.name ?: "null",
|
||||
brush = role.colour?.let { BrushCompat.parseColour(it) }
|
||||
?: Brush.solidColor(LocalContentColor.current)
|
||||
}, label = "User info actions pager"
|
||||
) { current ->
|
||||
val scope = rememberCoroutineScope()
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val context = LocalContext.current
|
||||
LazyVerticalStaggeredGrid(
|
||||
columns = StaggeredGridCells.Fixed(2),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalItemSpacing = 16.dp,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
if (current == 0) {
|
||||
item(key = "overview", span = StaggeredGridItemSpan.FullLine) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(MaterialTheme.colorScheme.surfaceBright)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
UserAvatar(
|
||||
username = resolvedUser!!.displayName ?: resolvedUser!!.username
|
||||
?: stringResource(R.string.unknown),
|
||||
avatar = resolvedUser!!.avatar,
|
||||
userId = resolvedUser!!.id!!,
|
||||
size = 64.dp
|
||||
)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = resolvedUser!!.displayName ?: resolvedUser!!.username
|
||||
?: stringResource(R.string.unknown),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
resolvedUser!!.username?.let { uname ->
|
||||
Text(
|
||||
text = "@" + uname,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val accountAt = resolvedUser!!.id?.let {
|
||||
DateUtils.getRelativeTimeSpanString(
|
||||
ULID.asTimestamp(resolvedUser!!.id!!),
|
||||
System.currentTimeMillis(),
|
||||
DateUtils.MINUTE_IN_MILLIS
|
||||
).toString()
|
||||
}
|
||||
val joinedAt = member?.joinedAt?.let {
|
||||
DateUtils.getRelativeTimeSpanString(
|
||||
Instant.parse(member.joinedAt).toEpochMilliseconds(),
|
||||
System.currentTimeMillis(),
|
||||
DateUtils.MINUTE_IN_MILLIS
|
||||
).toString()
|
||||
}
|
||||
|
||||
item(key = "joined") {
|
||||
SheetTile(
|
||||
header = {
|
||||
Text(stringResource(R.string.user_info_sheet_category_joined))
|
||||
},
|
||||
contentPreview = {
|
||||
if (joinedAt != null && server?.name != null) {
|
||||
Text(
|
||||
text = joinedAt,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
|
||||
Text(
|
||||
text = server.name,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
|
||||
accountAt?.let { _ ->
|
||||
Text(
|
||||
text = accountAt,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.user_info_sheet_category_joined_peptide),
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
if (joinedAt != null && server?.name != null) {
|
||||
Text(
|
||||
text = joinedAt,
|
||||
style = MaterialTheme.typography.displaySmall
|
||||
)
|
||||
|
||||
Text(
|
||||
text = server.name,
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
|
||||
accountAt?.let { _ ->
|
||||
Text(
|
||||
text = accountAt,
|
||||
style = MaterialTheme.typography.displaySmall
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.user_info_sheet_category_joined_peptide),
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((resolvedUser?.badges ?: 0) > 0) {
|
||||
item(key = "info") {
|
||||
SheetTile(
|
||||
header = {
|
||||
Text(stringResource(R.string.user_info_sheet_category_badges))
|
||||
},
|
||||
contentPreview = {
|
||||
resolvedUser?.badges?.let { UserBadgeRow(badges = it) }
|
||||
}
|
||||
) {
|
||||
resolvedUser?.badges?.let { UserBadgeList(badges = it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedUser?.status?.text != null) {
|
||||
item(key = "status") {
|
||||
SheetTile(
|
||||
header = {
|
||||
Text(stringResource(R.string.user_info_sheet_category_status))
|
||||
},
|
||||
contentPreview = {
|
||||
Text(
|
||||
text = resolvedUser!!.status!!.text ?: "",
|
||||
fontSize = 14.sp,
|
||||
maxLines = 5,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = resolvedUser!!.status!!.text ?: "",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedUser?.bot != null) {
|
||||
val resolvedOwner = resolvedUser!!.bot!!.owner?.let { PeptideAPI.userCache[it] }
|
||||
|
||||
item(key = "bot-owner") {
|
||||
SheetTile(
|
||||
header = {
|
||||
Text(stringResource(R.string.user_info_sheet_category_owner))
|
||||
},
|
||||
contentPreview = {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
resolvedOwner?.let {
|
||||
UserAvatar(
|
||||
username = it.displayName ?: it.username
|
||||
?: stringResource(R.string.unknown),
|
||||
avatar = it.avatar,
|
||||
userId = it.id!!,
|
||||
size = 32.dp
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = it.displayName ?: it.username
|
||||
?: stringResource(R.string.unknown),
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
} ?: run {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.icn_error_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.unknown),
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
if (Experiments.enableServerIdentityOptions.isEnabled || FeatureFlags.userCardsGranted) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (Experiments.enableServerIdentityOptions.isEnabled) {
|
||||
SmallFloatingActionButton(onClick = {
|
||||
showServerIdentityOptions = true
|
||||
}) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_psychology_alt_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
if (FeatureFlags.userCardsGranted) {
|
||||
SmallFloatingActionButton(onClick = {
|
||||
showUserCard = true
|
||||
}) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_badge_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolvedUser!!.status?.text?.takeIf { it.isNotBlank() }?.let { st ->
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Text(
|
||||
text = st,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
resolvedOwner?.let {
|
||||
RawUserOverview(it, null, internalPadding = false)
|
||||
} ?: run {
|
||||
NonIdealState(
|
||||
icon = {
|
||||
}
|
||||
|
||||
// Primary actions block (View Profile, Message, Notification Options, Copy DM ID)
|
||||
item(key = "primary-actions", span = StaggeredGridItemSpan.FullLine) {
|
||||
if (current == 0) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(MaterialTheme.colorScheme.surfaceBright)
|
||||
) {
|
||||
SheetButton(
|
||||
headlineContent = { Text(text = stringResource(id = R.string.overview_screen_settings)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_settings_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = { /* open profile */ }
|
||||
)
|
||||
HorizontalDivider()
|
||||
SheetButton(
|
||||
headlineContent = { Text(text = stringResource(id = R.string.message_friends)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_new_message),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = { /* open DM screen */ }
|
||||
)
|
||||
HorizontalDivider()
|
||||
SheetButton(
|
||||
headlineContent = { Text(text = stringResource(id = R.string.channel_info_sheet_options_notifications_manage)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_notification_settings_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = { page = 1 }
|
||||
)
|
||||
HorizontalDivider()
|
||||
SheetButton(
|
||||
headlineContent = { Text(text = stringResource(id = R.string.channel_context_sheet_actions_copy_id)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_identifier_copy_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
resolvedUser?.id?.let { userId ->
|
||||
scope.launch {
|
||||
clipboardManager.setText(AnnotatedString(userId))
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.copied),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Danger block (Close DM, Report User)
|
||||
item(key = "danger-actions", span = StaggeredGridItemSpan.FullLine) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(MaterialTheme.colorScheme.surfaceBright)
|
||||
) {
|
||||
SheetButton(
|
||||
headlineContent = { Text(text = stringResource(id = R.string.user_info_sheet_block)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.icn_error_24dp),
|
||||
painter = painterResource(R.drawable.icn_block_24dp),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.user_info_sheet_owner_not_found)
|
||||
onClick = {
|
||||
scope.launch {
|
||||
try {
|
||||
resolvedUser?.id?.let { userId ->
|
||||
blockUser(userId)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e.message == "NoEffect") return@launch
|
||||
logcat(LogPriority.ERROR) { e.asLog() }
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier,
|
||||
dangerous = true
|
||||
)
|
||||
if(resolvedUser?.relationship == "Friend"){
|
||||
HorizontalDivider()
|
||||
SheetButton(
|
||||
headlineContent = { Text(stringResource(R.string.user_info_sheet_remove_friend)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_group_remove_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
resolvedUser?.id?.let {userId ->
|
||||
scope.launch {
|
||||
try {
|
||||
unfriendUser(userId)
|
||||
} catch (e: Exception) {
|
||||
if (e.message == "NoEffect") return@launch
|
||||
logcat(LogPriority.ERROR) { e.asLog() }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
dangerous = true
|
||||
)
|
||||
}
|
||||
HorizontalDivider()
|
||||
SheetButton(
|
||||
headlineContent = { Text(text = stringResource(id = R.string.report)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.icn_psychology_alt_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
resolvedUser?.id?.let { userId ->
|
||||
scope.launch {
|
||||
ActionChannel.send(Action.ReportUser(userId))
|
||||
|
||||
if (Platform.needsShowClipboardNotification()) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.copied),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
dangerous = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (profile?.content.isNullOrBlank().not()) {
|
||||
item(key = "bio", span = StaggeredGridItemSpan.FullLine) {
|
||||
SheetTile(
|
||||
header = {
|
||||
Text(stringResource(R.string.user_info_sheet_category_bio))
|
||||
},
|
||||
contentPreview = {
|
||||
RichMarkdown(input = profile?.content!!)
|
||||
}
|
||||
) {
|
||||
SelectionContainer(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
||||
RichMarkdown(input = profile?.content!!)
|
||||
// Removed joined, badges, and bio sections per request
|
||||
|
||||
item(key = "actions", span = StaggeredGridItemSpan.FullLine) {
|
||||
UserButtons(resolvedUser!!, dismissSheet)
|
||||
}
|
||||
} else {
|
||||
item(key = "notifications", span = StaggeredGridItemSpan.FullLine) {
|
||||
// Notifications page
|
||||
Column {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(12.dp),
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_arrow_left_24dp),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.clickable { page = 0 }
|
||||
.align(Alignment.CenterStart)
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
text = stringResource(id = R.string.channel_info_sheet_options_notifications_manage),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(MaterialTheme.colorScheme.surfaceBright)
|
||||
) {
|
||||
|
||||
// Radio options
|
||||
val dmChannelId = PeptideAPI.channelCache.values.firstOrNull { ch ->
|
||||
ch.channelType == ChannelType.DirectMessage && ch.user == resolvedUser!!.id
|
||||
}?.id
|
||||
|
||||
var selected by remember {
|
||||
mutableStateOf(
|
||||
NotificationType.fromStorage(
|
||||
SyncedSettings.notifications.channel[dmChannelId ?: ""]
|
||||
).storageValue
|
||||
)
|
||||
}
|
||||
|
||||
fun updateSelection(newValue: NotificationType) {
|
||||
selected = newValue.storageValue
|
||||
val currentSettings = SyncedSettings.notifications
|
||||
val updated = NotificationSettings(
|
||||
server = currentSettings.server,
|
||||
channel = currentSettings.channel.toMutableMap().apply {
|
||||
if (dmChannelId.isNullOrBlank() || newValue == NotificationType.DEFAULT) {
|
||||
if (!dmChannelId.isNullOrBlank()) remove(dmChannelId)
|
||||
} else {
|
||||
put(dmChannelId, newValue.storageValue)
|
||||
}
|
||||
}
|
||||
)
|
||||
GlobalScope.launch {
|
||||
SyncedSettings.updateNotifications(updated)
|
||||
}
|
||||
}
|
||||
|
||||
NotificationRadioRow(
|
||||
title = stringResource(id = R.string.notification_option_use_default),
|
||||
type = NotificationType.DEFAULT,
|
||||
channelId = dmChannelId ?: "",
|
||||
current = selected,
|
||||
onChange = { updateSelection(NotificationType.DEFAULT) }
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.padding(horizontal = 12.dp))
|
||||
NotificationRadioRow(
|
||||
title = stringResource(id = R.string.notification_option_muted),
|
||||
type = NotificationType.MUTED,
|
||||
channelId = dmChannelId ?: "",
|
||||
current = selected,
|
||||
onChange = { updateSelection(NotificationType.MUTED) }
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.padding(horizontal = 12.dp))
|
||||
NotificationRadioRow(
|
||||
title = stringResource(id = R.string.notification_option_all_messages),
|
||||
type = NotificationType.ALL,
|
||||
channelId = dmChannelId ?: "",
|
||||
current = selected,
|
||||
onChange = { updateSelection(NotificationType.ALL) }
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.padding(horizontal = 12.dp))
|
||||
NotificationRadioRow(
|
||||
title = stringResource(id = R.string.notification_option_mentions_only),
|
||||
type = NotificationType.MENTIONS_ONLY,
|
||||
channelId = dmChannelId ?: "",
|
||||
current = selected,
|
||||
onChange = { updateSelection(NotificationType.MENTIONS_ONLY) }
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.padding(horizontal = 12.dp))
|
||||
NotificationRadioRow(
|
||||
title = stringResource(id = R.string.notification_option_none),
|
||||
type = NotificationType.NONE,
|
||||
channelId = dmChannelId ?: "",
|
||||
current = selected,
|
||||
onChange = { updateSelection(NotificationType.NONE) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item(key = "actions", span = StaggeredGridItemSpan.FullLine) {
|
||||
UserButtons(resolvedUser!!, dismissSheet)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue