From 171586c31275d14604d56edd09bacb9c8f886e2d Mon Sep 17 00:00:00 2001 From: Infi Date: Sat, 30 Dec 2023 21:50:31 +0100 Subject: [PATCH] feat: "add reaction" button on messages if reactions present Signed-off-by: Infi --- .../chat/revolt/components/chat/Message.kt | 22 +++++++++++- .../chat/views/channel/ChannelScreen.kt | 34 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/chat/revolt/components/chat/Message.kt b/app/src/main/java/chat/revolt/components/chat/Message.kt index 7cc59be6..4d83b59b 100644 --- a/app/src/main/java/chat/revolt/components/chat/Message.kt +++ b/app/src/main/java/chat/revolt/components/chat/Message.kt @@ -19,6 +19,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -40,14 +41,17 @@ import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.runtime.key import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow @@ -174,7 +178,8 @@ fun Message( onAvatarClick: () -> Unit = {}, onNameClick: (() -> Unit)? = null, canReply: Boolean = false, - onReply: () -> Unit = {} + onReply: () -> Unit = {}, + onAddReaction: () -> Unit = {}, ) { val author = RevoltAPI.userCache[message.author] ?: return CircularProgressIndicator() val context = LocalContext.current @@ -500,6 +505,21 @@ fun Message( } } } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .clip(MaterialTheme.shapes.small) + .background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)) + .clickable(onClick = onAddReaction) + .padding(8.dp) + ) { + Icon( + painter = painterResource(R.drawable.ic_hamburger_plus_24dp), + contentDescription = stringResource(R.string.message_context_sheet_actions_react), + modifier = Modifier.size(16.dp) + ) + } } Spacer(modifier = Modifier.height(8.dp)) } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt index d9fbabcd..349109f2 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt @@ -68,6 +68,7 @@ import chat.revolt.activities.RevoltTweenFloat import chat.revolt.activities.RevoltTweenInt import chat.revolt.api.RevoltAPI import chat.revolt.api.internals.ChannelUtils +import chat.revolt.api.routes.channel.react import chat.revolt.api.routes.microservices.autumn.FileArgs import chat.revolt.api.schemas.Channel import chat.revolt.api.schemas.ChannelType @@ -88,6 +89,7 @@ import chat.revolt.internals.markdown.createCodeRule import chat.revolt.internals.markdown.createInlineCodeRule import chat.revolt.sheets.ChannelInfoSheet import chat.revolt.sheets.MessageContextSheet +import chat.revolt.sheets.ReactSheet import com.discord.simpleast.core.simple.SimpleMarkdownRules import com.discord.simpleast.core.simple.SimpleRenderer import kotlinx.coroutines.flow.distinctUntilChanged @@ -118,6 +120,9 @@ fun ChannelScreen( var messageContextSheetShown by remember { mutableStateOf(false) } var messageContextSheetTarget by remember { mutableStateOf("") } + var reactSheetShown by remember { mutableStateOf(false) } + var reactSheetTarget by remember { mutableStateOf("") } + val focusManager = LocalFocusManager.current fun processFileUri(uri: Uri, pickerIdentifier: String? = null) { @@ -229,6 +234,27 @@ fun ChannelScreen( } } + if (reactSheetShown) { + val reactSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + + ModalBottomSheet( + sheetState = reactSheetState, + onDismissRequest = { + reactSheetShown = false + } + ) { + ReactSheet(reactSheetTarget) { + if (it == null) return@ReactSheet + + coroutineScope.launch { + react(channelId, reactSheetTarget, it) + reactSheetState.hide() + reactSheetShown = false + } + } + } + } + Column( modifier = Modifier .imePadding() @@ -363,7 +389,13 @@ fun ChannelScreen( return@Message } viewModel.replyToMessage(message) - } + }, + onAddReaction = { + message.id?.let { + reactSheetShown = true + reactSheetTarget = it + } + }, ) } }