for-android/app/src/main/java/chat/peptide/sheets/ServerContextSheet.kt

299 lines
11 KiB
Kotlin

package chat.peptide.sheets
import android.content.Intent
import android.widget.Toast
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.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
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.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.unit.dp
import androidx.core.net.toUri
import chat.peptide.R
import chat.peptide.api.PeptideAPI
import chat.peptide.api.routes.server.leaveOrDeleteServer
import chat.peptide.composables.generic.PepTextButton
import chat.peptide.composables.generic.SheetButton
import chat.peptide.composables.generic.SquareButton
import chat.peptide.composables.markdown.RichMarkdown
import chat.peptide.composables.screens.settings.ServerOverview
import chat.peptide.composables.sheets.SheetSelection
import chat.peptide.internals.Platform
import kotlinx.coroutines.launch
@Composable
fun ServerContextSheet(
serverId: String,
onReportServer: () -> Unit,
onHideSheet: suspend () -> Unit
) {
val server = PeptideAPI.serverCache[serverId]
if (server == null) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
) {
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
}
return
}
val coroutineScope = rememberCoroutineScope()
val clipboardManager = LocalClipboardManager.current
val context = LocalContext.current
var showLeaveConfirmation by remember { mutableStateOf(false) }
var leaveSilently by remember { mutableStateOf(false) }
if (showLeaveConfirmation) {
AlertDialog(
onDismissRequest = {
showLeaveConfirmation = false
},
title = {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm,
server.name ?: stringResource(R.string.unknown)
)
)
},
text = {
Column {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm_eyebrow
)
)
Row(
Modifier
.fillMaxWidth()
.padding(start = 0.dp, end = 0.dp, top = 16.dp, bottom = 0.dp),
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = leaveSilently,
onCheckedChange = { leaveSilently = it }
)
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_silently
),
modifier = Modifier.padding(start = 4.dp)
)
}
}
},
confirmButton = {
SquareButton(
onClick = {
coroutineScope.launch {
onHideSheet()
}
coroutineScope.launch {
leaveOrDeleteServer(serverId, leaveSilently)
}
}
) {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm_yes
)
)
}
},
dismissButton = {
PepTextButton(
onClick = {
showLeaveConfirmation = false
}
) {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm_no
)
)
}
}
)
}
Column(Modifier.verticalScroll(rememberScrollState())) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 4.dp),
) {
ServerOverview(server)
SelectionContainer {
RichMarkdown(
input = if (server.description?.isBlank() == false) {
server.description
} else {
stringResource(
R.string.server_context_sheet_description_empty
)
}
)
}
if (server.owner == PeptideAPI.selfId) {
Box(
modifier = Modifier
.clip(MaterialTheme.shapes.medium)
.background(MaterialTheme.colorScheme.primary)
) {
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimary) {
SheetSelection(
icon = {},
title = {
Text(
text = stringResource(id = R.string.server_context_sheet_moderators_early_disclaimer_title)
)
},
description = {
Text(
text = stringResource(id = R.string.server_context_sheet_moderators_early_disclaimer_body)
)
},
arrowTint = LocalContentColor.current.copy(alpha = 0.5f),
) {
context.startActivity(
Intent(
Intent.ACTION_VIEW,
"${PeptideAPI.getCurrentAppUrl()}/server/${server.id}/settings".toUri()
)
)
}
}
}
}
HorizontalDivider()
}
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_identifier_copy_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_copy_id)
)
},
onClick = {
if (server.id == null) return@SheetButton
clipboardManager.setText(AnnotatedString(server.id))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(
context,
context.getString(R.string.server_context_sheet_actions_copy_id_copied),
Toast.LENGTH_SHORT
).show()
}
coroutineScope.launch {
onHideSheet()
}
}
)
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_mark_chat_read_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_mark_read)
)
},
onClick = {
coroutineScope.launch {
server.id?.let {
PeptideAPI.unreads.markServerAsRead(it, sync = true)
}
onHideSheet()
}
}
)
if (server.owner != PeptideAPI.selfId) {
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_report_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_report),
)
},
dangerous = true,
onClick = {
onReportServer()
}
)
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_door_open_24dp),
contentDescription = null,
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_leave)
)
},
dangerous = true,
onClick = {
showLeaveConfirmation = true
}
)
}
}
}