Refactors user suggestion views

This commit is contained in:
Vitor Pamplona 2025-01-02 17:58:06 -05:00
parent 2772bdff8b
commit ff9509b649
6 changed files with 113 additions and 115 deletions

View File

@ -26,7 +26,6 @@ import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
@ -37,8 +36,6 @@ import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
@ -46,7 +43,6 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CurrencyBitcoin import androidx.compose.material.icons.filled.CurrencyBitcoin
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.LocalTextStyle
@ -98,14 +94,13 @@ import com.vitorpamplona.amethyst.ui.components.LoadUrlPreview
import com.vitorpamplona.amethyst.ui.components.VideoView import com.vitorpamplona.amethyst.ui.components.VideoView
import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.note.ShowUserSuggestionList
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ImageVideoDescription import com.vitorpamplona.amethyst.ui.screen.loggedIn.ImageVideoDescription
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.UserLine
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.Size5dp
@ -415,8 +410,9 @@ fun EditPostView(
} }
} }
ShowUserSuggestionListForEdit( ShowUserSuggestionList(
postViewModel, postViewModel.userSuggestions,
postViewModel::autocompleteWithUser,
accountViewModel, accountViewModel,
modifier = Modifier.heightIn(0.dp, 300.dp), modifier = Modifier.heightIn(0.dp, 300.dp),
) )
@ -429,34 +425,6 @@ fun EditPostView(
} }
} }
@Composable
fun ShowUserSuggestionListForEdit(
editPostViewModel: EditPostViewModel,
accountViewModel: AccountViewModel,
modifier: Modifier = Modifier.heightIn(0.dp, 200.dp),
) {
val userSuggestions = editPostViewModel.userSuggestions
if (userSuggestions.isNotEmpty()) {
LazyColumn(
contentPadding =
PaddingValues(
top = 10.dp,
),
modifier = modifier,
) {
itemsIndexed(
userSuggestions,
key = { _, item -> item.pubkeyHex },
) { _, item ->
UserLine(item, accountViewModel) { editPostViewModel.autocompleteWithUser(item) }
HorizontalDivider(
thickness = DividerThickness,
)
}
}
}
}
@Composable @Composable
private fun BottomRowActions(postViewModel: EditPostViewModel) { private fun BottomRowActions(postViewModel: EditPostViewModel) {
val scrollState = rememberScrollState() val scrollState = rememberScrollState()

View File

@ -0,0 +1,94 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.ui.note
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
@Composable
fun ShowUserSuggestionList(
userSuggestions: List<User>,
onSelect: (User) -> Unit,
accountViewModel: AccountViewModel,
modifier: Modifier = Modifier.heightIn(0.dp, 200.dp),
) {
if (userSuggestions.isNotEmpty()) {
LazyColumn(
contentPadding =
PaddingValues(
top = 10.dp,
),
modifier = modifier,
) {
itemsIndexed(
userSuggestions,
key = { _, item -> item.pubkeyHex },
) { _, item ->
UserLine(item, accountViewModel) { onSelect(item) }
HorizontalDivider(
thickness = DividerThickness,
)
}
}
}
}
@Composable
fun UserLine(
baseUser: User,
accountViewModel: AccountViewModel,
onClick: () -> Unit,
) {
Row(
modifier =
Modifier.fillMaxWidth().clickable(onClick = onClick).padding(
start = 12.dp,
end = 12.dp,
top = 10.dp,
bottom = 10.dp,
),
) {
ClickableUserPicture(baseUser, 55.dp, accountViewModel, Modifier, null)
Column(
modifier = Modifier.padding(start = 10.dp).weight(1f),
) {
Row(verticalAlignment = Alignment.CenterVertically) { UsernameDisplay(baseUser, accountViewModel = accountViewModel) }
AboutDisplay(baseUser)
}
}
}

View File

@ -157,10 +157,10 @@ import com.vitorpamplona.amethyst.ui.note.LoadCityName
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.note.PollIcon import com.vitorpamplona.amethyst.ui.note.PollIcon
import com.vitorpamplona.amethyst.ui.note.RegularPostIcon import com.vitorpamplona.amethyst.ui.note.RegularPostIcon
import com.vitorpamplona.amethyst.ui.note.ShowUserSuggestionList
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.note.ZapSplitIcon import com.vitorpamplona.amethyst.ui.note.ZapSplitIcon
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.MyTextField import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.MyTextField
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chatrooms.ShowUserSuggestionList
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
@ -569,7 +569,8 @@ fun NewPostScreen(
} }
ShowUserSuggestionList( ShowUserSuggestionList(
postViewModel, postViewModel.userSuggestions,
postViewModel::autocompleteWithUser,
accountViewModel, accountViewModel,
modifier = Modifier.heightIn(0.dp, 300.dp), modifier = Modifier.heightIn(0.dp, 300.dp),
) )
@ -578,21 +579,6 @@ fun NewPostScreen(
} }
} }
} }
// Dialog(
// onDismissRequest = {
// scope.launch {
// postViewModel.sendDraftSync(relayList = relayList)
// onClose()
// }
// },
// properties =
// DialogProperties(
// usePlatformDefaultWidth = false,
// dismissOnClickOutside = false,
// decorFitsSystemWindows = false,
// ),
// ) {
// }
} }
@Composable @Composable

View File

@ -130,6 +130,7 @@ import com.vitorpamplona.amethyst.ui.note.LikeReaction
import com.vitorpamplona.amethyst.ui.note.LoadChannel import com.vitorpamplona.amethyst.ui.note.LoadChannel
import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture
import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay
import com.vitorpamplona.amethyst.ui.note.ShowUserSuggestionList
import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.UserPicture
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.note.ZapReaction import com.vitorpamplona.amethyst.ui.note.ZapReaction
@ -478,7 +479,11 @@ fun EditFieldRow(
) { ) {
val context = LocalContext.current val context = LocalContext.current
ShowUserSuggestionList(channelScreenModel, accountViewModel) ShowUserSuggestionList(
channelScreenModel.userSuggestions,
channelScreenModel::autocompleteWithUser,
accountViewModel,
)
MyTextField( MyTextField(
value = channelScreenModel.message, value = channelScreenModel.message,

View File

@ -99,6 +99,7 @@ import com.vitorpamplona.amethyst.ui.note.IncognitoIconOff
import com.vitorpamplona.amethyst.ui.note.IncognitoIconOn import com.vitorpamplona.amethyst.ui.note.IncognitoIconOn
import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures
import com.vitorpamplona.amethyst.ui.note.QuickActionAlertDialog import com.vitorpamplona.amethyst.ui.note.QuickActionAlertDialog
import com.vitorpamplona.amethyst.ui.note.ShowUserSuggestionList
import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.note.UserCompose
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForDMs import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForDMs
@ -108,7 +109,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold
import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.PostButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.UserLine
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.BottomTopHeight import com.vitorpamplona.amethyst.ui.theme.BottomTopHeight
import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DividerThickness
@ -560,7 +560,11 @@ fun PrivateMessageEditFieldRow(
) { ) {
val context = LocalContext.current val context = LocalContext.current
ShowUserSuggestionList(channelScreenModel, accountViewModel) ShowUserSuggestionList(
channelScreenModel.userSuggestions,
channelScreenModel::autocompleteWithUser,
accountViewModel,
)
MyTextField( MyTextField(
value = channelScreenModel.message, value = channelScreenModel.message,
@ -655,34 +659,6 @@ fun PrivateMessageEditFieldRow(
} }
} }
@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) }
HorizontalDivider(
thickness = DividerThickness,
)
}
}
}
}
@Composable @Composable
fun NewFeatureNIP17AlertDialog( fun NewFeatureNIP17AlertDialog(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,

View File

@ -63,19 +63,15 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.FeatureSetType
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.ui.navigation.AppBottomBar import com.vitorpamplona.amethyst.ui.navigation.AppBottomBar
import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.navigation.Route import com.vitorpamplona.amethyst.ui.navigation.Route
import com.vitorpamplona.amethyst.ui.note.AboutDisplay
import com.vitorpamplona.amethyst.ui.note.ClearTextIcon import com.vitorpamplona.amethyst.ui.note.ClearTextIcon
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.note.SearchIcon import com.vitorpamplona.amethyst.ui.note.SearchIcon
import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.note.UserCompose
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForSearchAndDisplayIfNotFound import com.vitorpamplona.amethyst.ui.note.elements.ObserveRelayListForSearchAndDisplayIfNotFound
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold import com.vitorpamplona.amethyst.ui.screen.loggedIn.DisappearingScaffold
@ -398,30 +394,3 @@ fun HashtagLine(
} }
} }
} }
@Composable
fun UserLine(
baseUser: User,
accountViewModel: AccountViewModel,
onClick: () -> Unit,
) {
Row(
modifier =
Modifier.fillMaxWidth().clickable(onClick = onClick).padding(
start = 12.dp,
end = 12.dp,
top = 10.dp,
bottom = 10.dp,
),
) {
ClickableUserPicture(baseUser, 55.dp, accountViewModel, Modifier, null)
Column(
modifier = Modifier.padding(start = 10.dp).weight(1f),
) {
Row(verticalAlignment = Alignment.CenterVertically) { UsernameDisplay(baseUser, accountViewModel = accountViewModel) }
AboutDisplay(baseUser)
}
}
}