mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-27 19:16:40 +02:00
Search Bar
This commit is contained in:
@@ -24,6 +24,7 @@ import nostr.postr.events.PrivateDmEvent
|
|||||||
import nostr.postr.events.RecommendRelayEvent
|
import nostr.postr.events.RecommendRelayEvent
|
||||||
import nostr.postr.events.TextNoteEvent
|
import nostr.postr.events.TextNoteEvent
|
||||||
import nostr.postr.toHex
|
import nostr.postr.toHex
|
||||||
|
import nostr.postr.toNpub
|
||||||
|
|
||||||
|
|
||||||
object LocalCache {
|
object LocalCache {
|
||||||
@@ -309,7 +310,11 @@ object LocalCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun findUsersStartingWith(username: String): List<User> {
|
fun findUsersStartingWith(username: String): List<User> {
|
||||||
return users.values.filter { it.info.anyNameStartsWith(username) }
|
return users.values.filter {
|
||||||
|
it.info.anyNameStartsWith(username)
|
||||||
|
|| it.pubkeyHex.startsWith(username, true)
|
||||||
|
|| it.pubkey.toNpub().startsWith(username, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Observers line up here.
|
// Observers line up here.
|
||||||
|
@@ -1,24 +1,21 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.actions
|
package com.vitorpamplona.amethyst.ui.actions
|
||||||
|
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.Button
|
import androidx.compose.material.Button
|
||||||
import androidx.compose.material.ButtonDefaults
|
import androidx.compose.material.ButtonDefaults
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.OutlinedTextField
|
import androidx.compose.material.OutlinedTextField
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
@@ -37,16 +34,14 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.TextRange
|
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.input.TransformedText
|
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.components.UrlPreview
|
import com.vitorpamplona.amethyst.ui.components.UrlPreview
|
||||||
@@ -57,7 +52,7 @@ import com.vitorpamplona.amethyst.ui.components.noProtocolUrlValidator
|
|||||||
import com.vitorpamplona.amethyst.ui.components.videoExtension
|
import com.vitorpamplona.amethyst.ui.components.videoExtension
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.UploadFromGallery
|
import com.vitorpamplona.amethyst.ui.navigation.UploadFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.note.ReplyInformation
|
import com.vitorpamplona.amethyst.ui.note.ReplyInformation
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserDisplay
|
import com.vitorpamplona.amethyst.ui.screen.UserLine
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import nostr.postr.events.TextNoteEvent
|
import nostr.postr.events.TextNoteEvent
|
||||||
|
|
||||||
@@ -169,41 +164,8 @@ fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, account: Account
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
itemsIndexed(userSuggestions, key = { _, item -> item.pubkeyHex }) { index, item ->
|
itemsIndexed(userSuggestions, key = { _, item -> item.pubkeyHex }) { index, item ->
|
||||||
Column(modifier = Modifier.fillMaxWidth().clickable(onClick = {
|
UserLine(item) {
|
||||||
postViewModel.autocompleteWithUser(item)
|
postViewModel.autocompleteWithUser(item)
|
||||||
})) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
start = 12.dp,
|
|
||||||
end = 12.dp,
|
|
||||||
top = 10.dp)
|
|
||||||
) {
|
|
||||||
|
|
||||||
AsyncImage(
|
|
||||||
model = item.profilePicture(),
|
|
||||||
contentDescription = "Profile Image",
|
|
||||||
modifier = Modifier
|
|
||||||
.width(55.dp).height(55.dp)
|
|
||||||
.clip(shape = CircleShape)
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) {
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
||||||
UserDisplay(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
item.info.about?.take(100) ?: "",
|
|
||||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Divider(
|
|
||||||
modifier = Modifier.padding(top = 10.dp),
|
|
||||||
thickness = 0.25.dp
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,3 +240,27 @@ fun PostButton(onPost: () -> Unit = {}, isActive: Boolean, modifier: Modifier =
|
|||||||
Text(text = "Post", color = Color.White)
|
Text(text = "Post", color = Color.White)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SearchButton(onPost: () -> Unit = {}, isActive: Boolean, modifier: Modifier = Modifier) {
|
||||||
|
Button(
|
||||||
|
modifier = modifier,
|
||||||
|
onClick = {
|
||||||
|
if (isActive) {
|
||||||
|
onPost()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(20.dp),
|
||||||
|
colors = ButtonDefaults
|
||||||
|
.buttonColors(
|
||||||
|
backgroundColor = if (isActive) MaterialTheme.colors.primary else Color.Gray
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_search),
|
||||||
|
null,
|
||||||
|
modifier = Modifier.size(26.dp),
|
||||||
|
tint = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -23,10 +23,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
|
||||||
import com.vitorpamplona.amethyst.ui.components.RichTextViewer
|
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import nostr.postr.events.TextNoteEvent
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatroomCompose(baseNote: Note, accountViewModel: AccountViewModel, navController: NavController) {
|
fun ChatroomCompose(baseNote: Note, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
@@ -79,7 +76,7 @@ fun ChatroomCompose(baseNote: Note, accountViewModel: AccountViewModel, navContr
|
|||||||
userToComposeOn?.let {
|
userToComposeOn?.let {
|
||||||
ChannelName(
|
ChannelName(
|
||||||
channelPicture = it.profilePicture(),
|
channelPicture = it.profilePicture(),
|
||||||
channelTitle = { UserDisplay(it) },
|
channelTitle = { UsernameDisplay(it) },
|
||||||
channelLastTime = note.event?.createdAt,
|
channelLastTime = note.event?.createdAt,
|
||||||
channelLastContent = accountViewModel.decrypt(note),
|
channelLastContent = accountViewModel.decrypt(note),
|
||||||
onClick = { navController.navigate("Room/${it.pubkeyHex}") })
|
onClick = { navController.navigate("Room/${it.pubkeyHex}") })
|
||||||
|
@@ -110,7 +110,7 @@ fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Bool
|
|||||||
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
|
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
if (author != null)
|
if (author != null)
|
||||||
UserDisplay(author)
|
UsernameDisplay(author)
|
||||||
|
|
||||||
if (note.event !is RepostEvent) {
|
if (note.event !is RepostEvent) {
|
||||||
Text(
|
Text(
|
||||||
|
@@ -54,7 +54,7 @@ fun UserCompose(baseUser: User, accountViewModel: AccountViewModel, navControlle
|
|||||||
|
|
||||||
Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) {
|
Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
UserDisplay(user)
|
UsernameDisplay(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
|
@@ -7,7 +7,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserDisplay(user: User) {
|
fun UsernameDisplay(user: User) {
|
||||||
if (user.bestUsername() != null || user.bestDisplayName() != null) {
|
if (user.bestUsername() != null || user.bestDisplayName() != null) {
|
||||||
if (user.bestDisplayName().isNullOrBlank()) {
|
if (user.bestDisplayName().isNullOrBlank()) {
|
||||||
Text(
|
Text(
|
@@ -40,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.components.RichTextViewer
|
|||||||
import com.vitorpamplona.amethyst.ui.note.BlankNote
|
import com.vitorpamplona.amethyst.ui.note.BlankNote
|
||||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||||
import com.vitorpamplona.amethyst.ui.note.ReactionsRowState
|
import com.vitorpamplona.amethyst.ui.note.ReactionsRowState
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserDisplay
|
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||||
import com.vitorpamplona.amethyst.ui.note.timeAgoLong
|
import com.vitorpamplona.amethyst.ui.note.timeAgoLong
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ fun NoteMaster(baseNote: Note, accountViewModel: AccountViewModel, navController
|
|||||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
if (author != null)
|
if (author != null)
|
||||||
UserDisplay(author)
|
UsernameDisplay(author)
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen
|
package com.vitorpamplona.amethyst.ui.screen
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@@ -13,7 +12,6 @@ import androidx.compose.foundation.shape.CircleShape
|
|||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Divider
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.OutlinedTextField
|
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextField
|
import androidx.compose.material.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -35,11 +33,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.model.Channel
|
import com.vitorpamplona.amethyst.model.Channel
|
||||||
import com.vitorpamplona.amethyst.model.User
|
|
||||||
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatRoomDataSource
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserDisplay
|
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@@ -13,7 +13,6 @@ import androidx.compose.foundation.shape.CircleShape
|
|||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Divider
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.OutlinedTextField
|
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextField
|
import androidx.compose.material.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -34,7 +33,7 @@ import coil.compose.AsyncImage
|
|||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatRoomDataSource
|
import com.vitorpamplona.amethyst.service.NostrChatRoomDataSource
|
||||||
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
import com.vitorpamplona.amethyst.ui.actions.PostButton
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserDisplay
|
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -126,7 +125,7 @@ fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navContro
|
|||||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
if (author != null)
|
if (author != null)
|
||||||
UserDisplay(author)
|
UsernameDisplay(author)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,57 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen
|
package com.vitorpamplona.amethyst.ui.screen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
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.defaultMinSize
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.text.ClickableText
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material.Divider
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.LocalTextStyle
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.TextField
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Clear
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
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.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.SearchButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -24,7 +66,141 @@ fun SearchScreen(accountViewModel: AccountViewModel, navController: NavControlle
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(vertical = 0.dp)
|
modifier = Modifier.padding(vertical = 0.dp)
|
||||||
) {
|
) {
|
||||||
|
SearchBar(navController)
|
||||||
FeedView(feedViewModel, accountViewModel, navController)
|
FeedView(feedViewModel, accountViewModel, navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SearchBar(navController: NavController) {
|
||||||
|
val searchValue = remember { mutableStateOf(TextFieldValue("")) }
|
||||||
|
val searchResults = remember { mutableStateOf<List<User>>(emptyList()) }
|
||||||
|
|
||||||
|
val isTrailingIconVisible by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
searchValue.value.text.isNotBlank()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//LAST ROW
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(10.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
TextField(
|
||||||
|
value = searchValue.value,
|
||||||
|
onValueChange = {
|
||||||
|
searchValue.value = it
|
||||||
|
searchResults.value = LocalCache.findUsersStartingWith(it.text)
|
||||||
|
},
|
||||||
|
keyboardOptions = KeyboardOptions.Default.copy(
|
||||||
|
capitalization = KeyboardCapitalization.Sentences
|
||||||
|
),
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_search),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
tint = Color.Unspecified
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f, true)
|
||||||
|
.defaultMinSize(minHeight = 20.dp),
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = "npub, hex, username ",
|
||||||
|
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailingIcon = {
|
||||||
|
if (isTrailingIconVisible) {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
searchValue.value = TextFieldValue("")
|
||||||
|
searchResults.value = emptyList()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Clear,
|
||||||
|
contentDescription = "Clear"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchValue.value.text.isNotBlank()) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxHeight(),
|
||||||
|
contentPadding = PaddingValues(
|
||||||
|
top = 10.dp,
|
||||||
|
bottom = 10.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
itemsIndexed(searchResults.value, key = { _, item -> item.pubkeyHex }) { index, item ->
|
||||||
|
UserLine(item) {
|
||||||
|
navController.navigate("User/${item.pubkeyHex}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun UserLine(
|
||||||
|
baseUser: User,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
val userState by baseUser.live.observeAsState()
|
||||||
|
val user = userState?.user ?: return
|
||||||
|
|
||||||
|
Column(modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable(onClick = onClick)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(
|
||||||
|
start = 12.dp,
|
||||||
|
end = 12.dp,
|
||||||
|
top = 10.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
|
||||||
|
AsyncImage(
|
||||||
|
model = user.profilePicture(),
|
||||||
|
contentDescription = "Profile Image",
|
||||||
|
modifier = Modifier
|
||||||
|
.width(55.dp)
|
||||||
|
.height(55.dp)
|
||||||
|
.clip(shape = CircleShape)
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 10.dp)
|
||||||
|
.weight(1f)
|
||||||
|
) {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
UsernameDisplay(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
user.info.about?.take(100) ?: "",
|
||||||
|
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider(
|
||||||
|
modifier = Modifier.padding(top = 10.dp),
|
||||||
|
thickness = 0.25.dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user