411 lines
14 KiB
Kotlin
411 lines
14 KiB
Kotlin
package chat.revolt.sheets
|
|
|
|
import android.widget.Toast
|
|
import androidx.compose.foundation.background
|
|
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.rememberScrollState
|
|
import androidx.compose.foundation.verticalScroll
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.filled.Delete
|
|
import androidx.compose.material.icons.filled.Edit
|
|
import androidx.compose.material3.CircularProgressIndicator
|
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.ModalBottomSheet
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.material3.rememberModalBottomSheetState
|
|
import androidx.compose.material3.surfaceColorAtElevation
|
|
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.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 chat.revolt.R
|
|
import chat.revolt.api.REVOLT_APP
|
|
import chat.revolt.api.RevoltAPI
|
|
import chat.revolt.callbacks.UiCallbacks
|
|
import chat.revolt.components.chat.Message
|
|
import chat.revolt.components.generic.SheetClickable
|
|
import chat.revolt.internals.Platform
|
|
import kotlinx.coroutines.launch
|
|
|
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
@Composable
|
|
fun MessageContextSheet(
|
|
messageId: String,
|
|
onHideSheet: suspend () -> Unit,
|
|
onReportMessage: () -> Unit,
|
|
) {
|
|
val message = RevoltAPI.messageCache[messageId]
|
|
if (message == null) {
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.height(200.dp)
|
|
) {
|
|
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
|
}
|
|
return
|
|
}
|
|
|
|
val context = LocalContext.current
|
|
val clipboardManager = LocalClipboardManager.current
|
|
val coroutineScope = rememberCoroutineScope()
|
|
|
|
var showShareSheet by remember { mutableStateOf(false) }
|
|
|
|
if (showShareSheet) {
|
|
val shareSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
|
|
|
ModalBottomSheet(
|
|
sheetState = shareSheetState,
|
|
onDismissRequest = {
|
|
showShareSheet = false
|
|
},
|
|
) {
|
|
Column(
|
|
modifier = Modifier
|
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
.verticalScroll(rememberScrollState()),
|
|
) {
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_content_copy_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_copy),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
if (message.content.isNullOrEmpty()) {
|
|
coroutineScope.launch {
|
|
shareSheetState.hide()
|
|
onHideSheet()
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
}
|
|
return@SheetClickable
|
|
}
|
|
|
|
if (Platform.needsShowClipboardNotification()) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.copied),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
}
|
|
|
|
coroutineScope.launch {
|
|
shareSheetState.hide()
|
|
}
|
|
coroutineScope.launch {
|
|
clipboardManager.setText(AnnotatedString(message.content))
|
|
onHideSheet()
|
|
}
|
|
}
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_link_variant_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_copy_link),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
if (message.content.isNullOrEmpty()) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
coroutineScope.launch {
|
|
shareSheetState.hide()
|
|
}
|
|
coroutineScope.launch {
|
|
onHideSheet()
|
|
}
|
|
|
|
return@SheetClickable
|
|
}
|
|
|
|
val server = RevoltAPI.serverCache.values.find { server ->
|
|
server.channels?.contains(message.channel) ?: false
|
|
}
|
|
val messageLink =
|
|
"$REVOLT_APP/server/${server?.id}/channel/${message.channel}/${message.id}"
|
|
|
|
clipboardManager.setText(AnnotatedString(messageLink))
|
|
if (Platform.needsShowClipboardNotification()) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.message_context_sheet_actions_copy_link_copied),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
}
|
|
|
|
coroutineScope.launch {
|
|
shareSheetState.hide()
|
|
}
|
|
coroutineScope.launch {
|
|
onHideSheet()
|
|
}
|
|
}
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_content_copy_id_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_copy_id),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
if (message.id == null) return@SheetClickable
|
|
|
|
clipboardManager.setText(AnnotatedString(message.id))
|
|
|
|
if (Platform.needsShowClipboardNotification()) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.message_context_sheet_actions_copy_id_copied),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
}
|
|
|
|
coroutineScope.launch {
|
|
shareSheetState.hide()
|
|
}
|
|
coroutineScope.launch {
|
|
onHideSheet()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Column(
|
|
modifier = Modifier
|
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
.verticalScroll(rememberScrollState()),
|
|
) {
|
|
Box(
|
|
modifier = Modifier
|
|
.clip(MaterialTheme.shapes.medium)
|
|
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(0.dp))
|
|
.padding(bottom = 8.dp)
|
|
) {
|
|
Message(
|
|
message = message.copy(
|
|
tail = false,
|
|
masquerade = null
|
|
),
|
|
truncate = true
|
|
)
|
|
}
|
|
|
|
Spacer(modifier = Modifier.height(8.dp))
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_reply_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_reply),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
coroutineScope.launch {
|
|
UiCallbacks.replyToMessage(messageId)
|
|
onHideSheet()
|
|
}
|
|
}
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_hamburger_plus_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_react),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.comingsoon_toast),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
coroutineScope.launch {
|
|
onHideSheet()
|
|
}
|
|
}
|
|
|
|
if (message.author == RevoltAPI.selfId) {
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
imageVector = Icons.Default.Edit,
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_edit),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
coroutineScope.launch {
|
|
UiCallbacks.editMessage(messageId)
|
|
onHideSheet()
|
|
}
|
|
}
|
|
}
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_eye_off_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_mark_unread),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.comingsoon_toast),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
coroutineScope.launch {
|
|
onHideSheet()
|
|
}
|
|
}
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_share_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.share),
|
|
style = style
|
|
)
|
|
},
|
|
) {
|
|
showShareSheet = true
|
|
}
|
|
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
imageVector = Icons.Default.Delete,
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_delete),
|
|
style = style
|
|
)
|
|
},
|
|
dangerous = true
|
|
) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.comingsoon_toast),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
|
|
coroutineScope.launch {
|
|
onHideSheet()
|
|
}
|
|
}
|
|
|
|
if (message.author != RevoltAPI.selfId) {
|
|
SheetClickable(
|
|
icon = { modifier ->
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_flag_24dp),
|
|
contentDescription = null,
|
|
modifier = modifier
|
|
)
|
|
},
|
|
label = { style ->
|
|
Text(
|
|
text = stringResource(id = R.string.message_context_sheet_actions_report),
|
|
style = style
|
|
)
|
|
},
|
|
dangerous = true
|
|
) {
|
|
coroutineScope.launch {
|
|
onReportMessage()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |