feat: rework message context sheet

Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
Infi 2023-06-14 17:20:24 +02:00
parent d9cb89c589
commit df0393ffc9
3 changed files with 205 additions and 150 deletions

View File

@ -8,9 +8,11 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -24,25 +26,28 @@ fun SheetClickable(
icon: @Composable (Modifier) -> Unit, icon: @Composable (Modifier) -> Unit,
label: @Composable (TextStyle) -> Unit, label: @Composable (TextStyle) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
dangerous: Boolean = false,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
Box(modifier = modifier.padding(vertical = 4.dp)) { CompositionLocalProvider(LocalContentColor provides if (dangerous) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onBackground) {
Row( Box(modifier = modifier.padding(vertical = 4.dp)) {
modifier = Modifier Row(
.clip(MaterialTheme.shapes.medium) modifier = Modifier
.clickable(onClick = onClick) .clip(MaterialTheme.shapes.medium)
.padding(all = 4.dp) .clickable(onClick = onClick)
.fillMaxWidth() .padding(all = 4.dp)
.padding(horizontal = 16.dp, vertical = 8.dp), .fillMaxWidth()
verticalAlignment = Alignment.CenterVertically .padding(horizontal = 16.dp, vertical = 8.dp),
) { verticalAlignment = Alignment.CenterVertically
icon(Modifier.padding(end = 16.dp)) ) {
label( icon(Modifier.padding(end = 16.dp))
MaterialTheme.typography.bodyMedium.copy( label(
color = MaterialTheme.colorScheme.onBackground, MaterialTheme.typography.bodyMedium.copy(
fontWeight = FontWeight.SemiBold, color = LocalContentColor.current,
fontWeight = FontWeight.SemiBold,
)
) )
) }
} }
} }
} }

View File

@ -160,7 +160,7 @@ fun ChannelScreen(
} }
if (messageContextSheetShown) { if (messageContextSheetShown) {
val messageContextSheetState = rememberModalBottomSheetState() val messageContextSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
ModalBottomSheet( ModalBottomSheet(
sheetState = messageContextSheetState, sheetState = messageContextSheetState,

View File

@ -14,12 +14,19 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable 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.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -37,6 +44,7 @@ import chat.revolt.components.chat.Message
import chat.revolt.components.generic.SheetClickable import chat.revolt.components.generic.SheetClickable
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun MessageContextSheet( fun MessageContextSheet(
messageId: String, messageId: String,
@ -59,6 +67,140 @@ fun MessageContextSheet(
val clipboardManager = LocalClipboardManager.current val clipboardManager = LocalClipboardManager.current
val coroutineScope = rememberCoroutineScope() 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 {
onHideSheet()
Toast.makeText(
context,
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
Toast.LENGTH_SHORT
).show()
}
return@SheetClickable
}
Toast.makeText(
context,
context.getString(R.string.copied),
Toast.LENGTH_SHORT
).show()
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 {
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))
Toast.makeText(
context,
context.getString(R.string.message_context_sheet_actions_copy_link_copied),
Toast.LENGTH_SHORT
).show()
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))
Toast.makeText(
context,
context.getString(R.string.message_context_sheet_actions_copy_id_copied),
Toast.LENGTH_SHORT
).show()
coroutineScope.launch {
onHideSheet()
}
}
}
}
}
Column( Column(
modifier = Modifier modifier = Modifier
.padding(horizontal = 16.dp, vertical = 8.dp) .padding(horizontal = 16.dp, vertical = 8.dp)
@ -128,122 +270,29 @@ fun MessageContextSheet(
} }
} }
SheetClickable( if (message.author == RevoltAPI.selfId) {
icon = { modifier -> SheetClickable(
Icon( icon = { modifier ->
painter = painterResource(id = R.drawable.ic_content_copy_24dp), Icon(
contentDescription = null, imageVector = Icons.Default.Edit,
modifier = modifier contentDescription = null,
) modifier = modifier
}, )
label = { style -> },
Text( label = { style ->
text = stringResource(id = R.string.message_context_sheet_actions_copy), Text(
style = style text = stringResource(id = R.string.message_context_sheet_actions_edit),
) style = style
}, )
) { },
if (message.content.isNullOrEmpty()) { ) {
coroutineScope.launch {
onHideSheet()
Toast.makeText(
context,
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
Toast.LENGTH_SHORT
).show()
}
return@SheetClickable
}
Toast.makeText(
context,
context.getString(R.string.copied),
Toast.LENGTH_SHORT
).show()
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 { coroutineScope.launch {
UiCallbacks.editMessage(messageId)
onHideSheet() 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))
Toast.makeText(
context,
context.getString(R.string.message_context_sheet_actions_copy_link_copied),
Toast.LENGTH_SHORT
).show()
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))
Toast.makeText(
context,
context.getString(R.string.message_context_sheet_actions_copy_id_copied),
Toast.LENGTH_SHORT
).show()
coroutineScope.launch {
onHideSheet()
}
}
SheetClickable( SheetClickable(
icon = { modifier -> icon = { modifier ->
Icon( Icon(
@ -273,22 +322,19 @@ fun MessageContextSheet(
SheetClickable( SheetClickable(
icon = { modifier -> icon = { modifier ->
Icon( Icon(
imageVector = Icons.Default.Edit, painter = painterResource(id = R.drawable.ic_share_24dp),
contentDescription = null, contentDescription = null,
modifier = modifier modifier = modifier
) )
}, },
label = { style -> label = { style ->
Text( Text(
text = stringResource(id = R.string.message_context_sheet_actions_edit), text = stringResource(id = R.string.share),
style = style style = style
) )
}, },
) { ) {
coroutineScope.launch { showShareSheet = true
UiCallbacks.editMessage(messageId)
onHideSheet()
}
} }
SheetClickable( SheetClickable(
@ -305,6 +351,7 @@ fun MessageContextSheet(
style = style style = style
) )
}, },
dangerous = true
) { ) {
Toast.makeText( Toast.makeText(
context, context,
@ -317,23 +364,26 @@ fun MessageContextSheet(
} }
} }
SheetClickable( if (message.author != RevoltAPI.selfId) {
icon = { modifier -> SheetClickable(
Icon( icon = { modifier ->
painter = painterResource(id = R.drawable.ic_flag_24dp), Icon(
contentDescription = null, painter = painterResource(id = R.drawable.ic_flag_24dp),
modifier = modifier contentDescription = null,
) modifier = modifier
}, )
label = { style -> },
Text( label = { style ->
text = stringResource(id = R.string.message_context_sheet_actions_report), Text(
style = style text = stringResource(id = R.string.message_context_sheet_actions_report),
) style = style
}, )
) { },
coroutineScope.launch { dangerous = true
onReportMessage() ) {
coroutineScope.launch {
onReportMessage()
}
} }
} }
} }