From 9479e86b66ec0fd702e57f1de5f04d421e84e782 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 14 Feb 2024 16:52:25 -0500 Subject: [PATCH] Enabled citation via @ on chats --- .../amethyst/ui/actions/NewPostView.kt | 28 ++----- .../ui/screen/loggedIn/ChannelScreen.kt | 80 +++++++++++++++---- .../ui/screen/loggedIn/ChatroomScreen.kt | 37 ++++++++- 3 files changed, 104 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt index b2b9462ed..733b11233 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt @@ -50,8 +50,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.windowInsetsPadding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.shape.RoundedCornerShape @@ -99,7 +97,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.CenterVertically -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.FocusRequester @@ -158,9 +155,9 @@ import com.vitorpamplona.amethyst.ui.note.RegularPostIcon import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.MyTextField +import com.vitorpamplona.amethyst.ui.screen.loggedIn.ShowUserSuggestionList import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer -import com.vitorpamplona.amethyst.ui.screen.loggedIn.UserLine import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer @@ -526,23 +523,11 @@ fun NewPostView( } } - val userSuggestions = postViewModel.userSuggestions - if (userSuggestions.isNotEmpty()) { - LazyColumn( - contentPadding = - PaddingValues( - top = 10.dp, - ), - modifier = Modifier.heightIn(0.dp, 300.dp), - ) { - itemsIndexed( - userSuggestions, - key = { _, item -> item.pubkeyHex }, - ) { _, item -> - UserLine(item, accountViewModel) { postViewModel.autocompleteWithUser(item) } - } - } - } + ShowUserSuggestionList( + postViewModel, + accountViewModel, + modifier = Modifier.heightIn(0.dp, 300.dp), + ) BottomRowActions(postViewModel) } @@ -649,7 +634,6 @@ private fun PollField(postViewModel: NewPostViewModel) { } } -@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class) @Composable private fun MessageField(postViewModel: NewPostViewModel) { val focusRequester = remember { FocusRequester() } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt index 82e2ef638..8d2a49c30 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt @@ -38,10 +38,12 @@ import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.selection.LocalTextSelectionColors +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Cancel import androidx.compose.material.icons.filled.EditNote @@ -112,6 +114,7 @@ import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.ServerOption import com.vitorpamplona.amethyst.ui.actions.UploadFromGallery +import com.vitorpamplona.amethyst.ui.actions.UrlUserTagTransformation import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.SensitivityWarning @@ -269,7 +272,13 @@ fun ChannelScreen( val replyTo = remember { mutableStateOf(null) } Column( - modifier = remember { Modifier.fillMaxHeight().padding(vertical = 0.dp).weight(1f, true) }, + modifier = + remember { + Modifier + .fillMaxHeight() + .padding(vertical = 0.dp) + .weight(1f, true) + }, ) { if (channel is LiveActivitiesChannel) { ShowVideoStreaming(channel, accountViewModel) @@ -340,7 +349,11 @@ fun DisplayReplyingToNote( onCancel: () -> Unit, ) { Row( - Modifier.padding(horizontal = 10.dp).animateContentSize(), + Modifier + .padding(horizontal = 10.dp) + .heightIn(max = 100.dp) + .verticalScroll(rememberScrollState()) + .animateContentSize(), verticalAlignment = Alignment.CenterVertically, ) { if (replyingNote != null) { @@ -363,7 +376,10 @@ fun DisplayReplyingToNote( Icon( imageVector = Icons.Default.Cancel, null, - modifier = Modifier.padding(end = 5.dp).size(30.dp), + modifier = + Modifier + .padding(end = 5.dp) + .size(30.dp), tint = MaterialTheme.colorScheme.placeholderText, ) } @@ -379,13 +395,13 @@ fun EditFieldRow( accountViewModel: AccountViewModel, onSendNewMessage: () -> Unit, ) { - Row( + Column( modifier = EditFieldModifier, - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, ) { val context = LocalContext.current + ShowUserSuggestionList(channelScreenModel, accountViewModel) + MyTextField( value = channelScreenModel.message, onValueChange = { channelScreenModel.updateMessage(it) }, @@ -394,7 +410,7 @@ fun EditFieldRow( capitalization = KeyboardCapitalization.Sentences, ), shape = EditFieldBorder, - modifier = Modifier.weight(1f, true), + modifier = Modifier.fillMaxWidth(), placeholder = { Text( text = stringResource(R.string.reply_here), @@ -431,6 +447,7 @@ fun EditFieldRow( focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, ), + visualTransformation = UrlUserTagTransformation(MaterialTheme.colorScheme.primary), ) } } @@ -725,7 +742,11 @@ fun ShortChannelHeader( } Column( - modifier = Modifier.padding(start = 10.dp).height(35.dp).weight(1f), + modifier = + Modifier + .padding(start = 10.dp) + .height(35.dp) + .weight(1f), verticalArrangement = Arrangement.Center, ) { Row(verticalAlignment = Alignment.CenterVertically) { @@ -738,7 +759,10 @@ fun ShortChannelHeader( } Row( - modifier = Modifier.height(Size35dp).padding(start = 5.dp), + modifier = + Modifier + .height(Size35dp) + .padding(start = 5.dp), verticalAlignment = Alignment.CenterVertically, ) { if (channel is PublicChatChannel) { @@ -1028,7 +1052,12 @@ fun LiveFlag() { fontWeight = FontWeight.Bold, fontSize = 16.sp, modifier = - remember { Modifier.clip(SmallBorder).background(Color.Red).padding(horizontal = 5.dp) }, + remember { + Modifier + .clip(SmallBorder) + .background(Color.Red) + .padding(horizontal = 5.dp) + }, ) } @@ -1039,7 +1068,12 @@ fun EndedFlag() { color = Color.White, fontWeight = FontWeight.Bold, modifier = - remember { Modifier.clip(SmallBorder).background(Color.Black).padding(horizontal = 5.dp) }, + remember { + Modifier + .clip(SmallBorder) + .background(Color.Black) + .padding(horizontal = 5.dp) + }, ) } @@ -1050,7 +1084,12 @@ fun OfflineFlag() { color = Color.White, fontWeight = FontWeight.Bold, modifier = - remember { Modifier.clip(SmallBorder).background(Color.Black).padding(horizontal = 5.dp) }, + remember { + Modifier + .clip(SmallBorder) + .background(Color.Black) + .padding(horizontal = 5.dp) + }, ) } @@ -1064,7 +1103,12 @@ fun ScheduledFlag(starts: Long?) { color = Color.White, fontWeight = FontWeight.Bold, modifier = - remember { Modifier.clip(SmallBorder).background(Color.Black).padding(horizontal = 5.dp) }, + remember { + Modifier + .clip(SmallBorder) + .background(Color.Black) + .padding(horizontal = 5.dp) + }, ) } @@ -1073,7 +1117,10 @@ private fun NoteCopyButton(note: Channel) { var popupExpanded by remember { mutableStateOf(false) } Button( - modifier = Modifier.padding(horizontal = 3.dp).width(50.dp), + modifier = + Modifier + .padding(horizontal = 3.dp) + .width(50.dp), onClick = { popupExpanded = true }, shape = ButtonBorder, colors = @@ -1116,7 +1163,10 @@ private fun EditButton( } Button( - modifier = Modifier.padding(horizontal = 3.dp).width(50.dp), + modifier = + Modifier + .padding(horizontal = 3.dp) + .width(50.dp), onClick = { wantsToPost = true }, contentPadding = ZeroPadding, ) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt index c205ff87c..2606d3a52 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt @@ -25,11 +25,13 @@ import androidx.compose.animation.Crossfade import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -92,6 +94,7 @@ import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.PostButton import com.vitorpamplona.amethyst.ui.actions.ServerOption import com.vitorpamplona.amethyst.ui.actions.UploadFromGallery +import com.vitorpamplona.amethyst.ui.actions.UrlUserTagTransformation import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.DisplayRoomSubject @@ -363,13 +366,13 @@ fun PrivateMessageEditFieldRow( accountViewModel: AccountViewModel, onSendNewMessage: () -> Unit, ) { - Row( + Column( modifier = EditFieldModifier, - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, ) { val context = LocalContext.current + ShowUserSuggestionList(channelScreenModel, accountViewModel) + MyTextField( value = channelScreenModel.message, onValueChange = { channelScreenModel.updateMessage(it) }, @@ -378,7 +381,7 @@ fun PrivateMessageEditFieldRow( capitalization = KeyboardCapitalization.Sentences, ), shape = EditFieldBorder, - modifier = Modifier.weight(1f, true), + modifier = Modifier.fillMaxWidth(), placeholder = { Text( text = stringResource(R.string.reply_here), @@ -461,10 +464,36 @@ fun PrivateMessageEditFieldRow( focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, ), + visualTransformation = UrlUserTagTransformation(MaterialTheme.colorScheme.primary), ) } } +@Composable +fun ShowUserSuggestionList( + channelScreenModel: NewPostViewModel, + accountViewModel: AccountViewModel, + modifier: Modifier = Modifier.heightIn(0.dp, 200.dp), +) { + val userSuggestions = channelScreenModel.userSuggestions + if (userSuggestions.isNotEmpty()) { + LazyColumn( + contentPadding = + PaddingValues( + top = 10.dp, + ), + modifier = modifier, + ) { + itemsIndexed( + userSuggestions, + key = { _, item -> item.pubkeyHex }, + ) { _, item -> + UserLine(item, accountViewModel) { channelScreenModel.autocompleteWithUser(item) } + } + } + } +} + @Composable fun NewFeatureNIP24AlertDialog( accountViewModel: AccountViewModel,