Refinements to ShopStr's event rendering.
This commit is contained in:
@@ -833,6 +833,44 @@ private fun DialogContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
fun InlineCarrousel(
|
||||||
|
allImages: ImmutableList<String>,
|
||||||
|
imageUrl: String
|
||||||
|
) {
|
||||||
|
val pagerState: PagerState = rememberPagerState() { allImages.size }
|
||||||
|
|
||||||
|
LaunchedEffect(key1 = pagerState, key2 = imageUrl) {
|
||||||
|
launch {
|
||||||
|
val page = allImages.indexOf(imageUrl)
|
||||||
|
if (page > -1) {
|
||||||
|
pagerState.scrollToPage(page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allImages.size > 1) {
|
||||||
|
SlidingCarousel(
|
||||||
|
pagerState = pagerState
|
||||||
|
) { index ->
|
||||||
|
AsyncImage(
|
||||||
|
model = allImages[index],
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AsyncImage(
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CopyToClipboard(
|
private fun CopyToClipboard(
|
||||||
content: ZoomableContent
|
content: ZoomableContent
|
||||||
|
|||||||
@@ -1206,7 +1206,8 @@ private fun RenderNoteRow(
|
|||||||
RenderClassifieds(
|
RenderClassifieds(
|
||||||
noteEvent,
|
noteEvent,
|
||||||
baseNote,
|
baseNote,
|
||||||
accountViewModel
|
accountViewModel,
|
||||||
|
nav
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3896,7 +3897,7 @@ private fun LongFormHeader(noteEvent: LongTextNoteEvent, note: Note, accountView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RenderClassifieds(noteEvent: ClassifiedsEvent, note: Note, accountViewModel: AccountViewModel) {
|
private fun RenderClassifieds(noteEvent: ClassifiedsEvent, note: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
val image = remember(noteEvent) { noteEvent.image() }
|
val image = remember(noteEvent) { noteEvent.image() }
|
||||||
val title = remember(noteEvent) { noteEvent.title() }
|
val title = remember(noteEvent) { noteEvent.title() }
|
||||||
val summary = remember(noteEvent) { noteEvent.summary() ?: noteEvent.content.take(200).ifBlank { null } }
|
val summary = remember(noteEvent) { noteEvent.summary() ?: noteEvent.content.take(200).ifBlank { null } }
|
||||||
@@ -3933,18 +3934,23 @@ private fun RenderClassifieds(noteEvent: ClassifiedsEvent, note: Note, accountVi
|
|||||||
text = it,
|
text = it,
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
price?.let {
|
price?.let {
|
||||||
val priceTag = remember(noteEvent) {
|
val priceTag = remember(noteEvent) {
|
||||||
|
val newAmount = price.amount.toBigDecimalOrNull()?.let {
|
||||||
|
showAmount(it)
|
||||||
|
} ?: price.amount
|
||||||
|
|
||||||
if (price.frequency != null && price.currency != null) {
|
if (price.frequency != null && price.currency != null) {
|
||||||
"${price.amount} ${price.currency}/${price.frequency}"
|
"$newAmount ${price.currency}/${price.frequency}"
|
||||||
} else if (price.currency != null) {
|
} else if (price.currency != null) {
|
||||||
"${price.amount} ${price.currency}"
|
"$newAmount ${price.currency}"
|
||||||
} else {
|
} else {
|
||||||
price.amount
|
newAmount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3956,7 +3962,6 @@ private fun RenderClassifieds(noteEvent: ClassifiedsEvent, note: Note, accountVi
|
|||||||
modifier = remember {
|
modifier = remember {
|
||||||
Modifier
|
Modifier
|
||||||
.clip(SmallBorder)
|
.clip(SmallBorder)
|
||||||
.background(Color.Black)
|
|
||||||
.padding(start = 5.dp)
|
.padding(start = 5.dp)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -3977,16 +3982,46 @@ private fun RenderClassifieds(noteEvent: ClassifiedsEvent, note: Note, accountVi
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
location?.let {
|
/*
|
||||||
Text(
|
Column {
|
||||||
text = it,
|
location?.let {
|
||||||
style = MaterialTheme.typography.bodySmall,
|
Text(
|
||||||
color = Color.Gray,
|
text = it,
|
||||||
maxLines = 1,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
overflow = TextOverflow.Ellipsis,
|
color = Color.Gray,
|
||||||
modifier = Modifier.padding(start = 5.dp)
|
maxLines = 1,
|
||||||
)
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.padding(start = 5.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 3.dp)
|
||||||
|
.width(50.dp),
|
||||||
|
onClick = {
|
||||||
|
note.author?.let {
|
||||||
|
accountViewModel.createChatRoomFor(it) {
|
||||||
|
nav("Room/$it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentPadding = ZeroPadding,
|
||||||
|
colors = ButtonDefaults
|
||||||
|
.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_dm),
|
||||||
|
stringResource(R.string.send_a_direct_message),
|
||||||
|
modifier = Modifier.size(20.dp),
|
||||||
|
tint = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
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.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@@ -17,14 +18,18 @@ 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.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.Divider
|
||||||
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.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.ProvideTextStyle
|
import androidx.compose.material3.ProvideTextStyle
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
import androidx.compose.material3.pullrefresh.PullRefreshIndicator
|
import androidx.compose.material3.pullrefresh.PullRefreshIndicator
|
||||||
import androidx.compose.material3.pullrefresh.pullRefresh
|
import androidx.compose.material3.pullrefresh.pullRefresh
|
||||||
import androidx.compose.material3.pullrefresh.rememberPullRefreshState
|
import androidx.compose.material3.pullrefresh.rememberPullRefreshState
|
||||||
@@ -38,15 +43,18 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
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.drawBehind
|
import androidx.compose.ui.draw.drawBehind
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
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.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import androidx.compose.ui.text.style.TextDirection
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
@@ -55,6 +63,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.InlineCarrousel
|
||||||
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
|
||||||
import com.vitorpamplona.amethyst.ui.note.AudioHeader
|
import com.vitorpamplona.amethyst.ui.note.AudioHeader
|
||||||
import com.vitorpamplona.amethyst.ui.note.AudioTrackHeader
|
import com.vitorpamplona.amethyst.ui.note.AudioTrackHeader
|
||||||
@@ -87,13 +96,18 @@ import com.vitorpamplona.amethyst.ui.note.RenderPostApproval
|
|||||||
import com.vitorpamplona.amethyst.ui.note.RenderRepost
|
import com.vitorpamplona.amethyst.ui.note.RenderRepost
|
||||||
import com.vitorpamplona.amethyst.ui.note.RenderTextEvent
|
import com.vitorpamplona.amethyst.ui.note.RenderTextEvent
|
||||||
import com.vitorpamplona.amethyst.ui.note.Reward
|
import com.vitorpamplona.amethyst.ui.note.Reward
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.routeToMessage
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.showAmount
|
||||||
import com.vitorpamplona.amethyst.ui.note.timeAgo
|
import com.vitorpamplona.amethyst.ui.note.timeAgo
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ChannelHeader
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ChannelHeader
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ThinSendButton
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.EditFieldBorder
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.EditFieldTrailingIconModifier
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.SmallBorder
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.lessImportantLink
|
import com.vitorpamplona.amethyst.ui.theme.lessImportantLink
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.amethyst.ui.theme.selectedNote
|
import com.vitorpamplona.amethyst.ui.theme.selectedNote
|
||||||
@@ -117,6 +131,7 @@ import com.vitorpamplona.quartz.events.PinListEvent
|
|||||||
import com.vitorpamplona.quartz.events.PollNoteEvent
|
import com.vitorpamplona.quartz.events.PollNoteEvent
|
||||||
import com.vitorpamplona.quartz.events.RelaySetEvent
|
import com.vitorpamplona.quartz.events.RelaySetEvent
|
||||||
import com.vitorpamplona.quartz.events.RepostEvent
|
import com.vitorpamplona.quartz.events.RepostEvent
|
||||||
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableSet
|
import kotlinx.collections.immutable.toImmutableSet
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -388,7 +403,7 @@ fun NoteMaster(
|
|||||||
} else if (noteEvent is LongTextNoteEvent) {
|
} else if (noteEvent is LongTextNoteEvent) {
|
||||||
RenderLongFormHeaderForThread(noteEvent)
|
RenderLongFormHeaderForThread(noteEvent)
|
||||||
} else if (noteEvent is ClassifiedsEvent) {
|
} else if (noteEvent is ClassifiedsEvent) {
|
||||||
RenderClassifiedsReaderForThread(noteEvent, note, accountViewModel)
|
RenderClassifiedsReaderForThread(noteEvent, note, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
@@ -517,52 +532,64 @@ fun NoteMaster(
|
|||||||
private fun RenderClassifiedsReaderForThread(
|
private fun RenderClassifiedsReaderForThread(
|
||||||
noteEvent: ClassifiedsEvent,
|
noteEvent: ClassifiedsEvent,
|
||||||
note: Note,
|
note: Note,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel,
|
||||||
|
nav: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val image = remember(noteEvent) { noteEvent.image() }
|
val images = remember(noteEvent) { noteEvent.images().toImmutableList() }
|
||||||
val title = remember(noteEvent) { noteEvent.title() }
|
val title = remember(noteEvent) { noteEvent.title() }
|
||||||
val summary =
|
val summary = remember(noteEvent) {
|
||||||
remember(noteEvent) { noteEvent.summary() ?: noteEvent.content.take(200).ifBlank { null } }
|
val sum = noteEvent.summary()
|
||||||
|
if (sum != noteEvent.content) {
|
||||||
|
sum
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
val price = remember(noteEvent) { noteEvent.price() }
|
val price = remember(noteEvent) { noteEvent.price() }
|
||||||
val location = remember(noteEvent) { noteEvent.location() }
|
val location = remember(noteEvent) { noteEvent.location() }
|
||||||
|
|
||||||
Row(modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 12.dp)) {
|
Row(modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 12.dp)) {
|
||||||
Column {
|
Column {
|
||||||
Row() {
|
if (images.isNotEmpty()) {
|
||||||
image?.let {
|
Row() {
|
||||||
AsyncImage(
|
InlineCarrousel(
|
||||||
model = it,
|
images,
|
||||||
contentDescription = stringResource(
|
images.first()
|
||||||
R.string.preview_card_image_for,
|
|
||||||
it
|
|
||||||
),
|
|
||||||
contentScale = ContentScale.FillWidth,
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
)
|
||||||
} ?: CreateImageHeader(note, accountViewModel)
|
}
|
||||||
|
} else {
|
||||||
|
CreateImageHeader(note, accountViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp),
|
Modifier.padding(top = 10.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
title?.let {
|
title?.let {
|
||||||
Text(
|
Text(
|
||||||
text = it,
|
text = it,
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
maxLines = 1,
|
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
price?.let {
|
||||||
|
Row(
|
||||||
|
Modifier.padding(top = 5.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
val newAmount = price.amount.toBigDecimalOrNull()?.let {
|
||||||
|
showAmount(it)
|
||||||
|
} ?: price.amount
|
||||||
|
|
||||||
price?.let {
|
|
||||||
val priceTag = remember(noteEvent) {
|
val priceTag = remember(noteEvent) {
|
||||||
if (price.frequency != null && price.currency != null) {
|
if (price.frequency != null && price.currency != null) {
|
||||||
"${price.amount} ${price.currency}/${price.frequency}"
|
"$newAmount ${price.currency}/${price.frequency}"
|
||||||
} else if (price.currency != null) {
|
} else if (price.currency != null) {
|
||||||
"${price.amount} ${price.currency}"
|
"$newAmount ${price.currency}"
|
||||||
} else {
|
} else {
|
||||||
price.amount
|
newAmount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,19 +598,22 @@ private fun RenderClassifiedsReaderForThread(
|
|||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
modifier = remember {
|
modifier = Modifier.weight(1f)
|
||||||
Modifier
|
|
||||||
.clip(SmallBorder)
|
|
||||||
.background(Color.Black)
|
|
||||||
.padding(start = 5.dp)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
location?.let {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
summary?.let {
|
summary?.let {
|
||||||
Row(
|
Row(
|
||||||
Modifier.padding(start = 10.dp, end = 10.dp, top = 5.dp),
|
Modifier.padding(top = 5.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
@@ -596,19 +626,78 @@ private fun RenderClassifiedsReaderForThread(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
location?.let {
|
Row(
|
||||||
Row(
|
Modifier
|
||||||
Modifier.padding(start = 10.dp, end = 10.dp, top = 5.dp),
|
.padding(start = 20.dp, end = 20.dp, bottom = 5.dp, top = 15.dp)
|
||||||
verticalAlignment = Alignment.CenterVertically
|
.fillMaxWidth(),
|
||||||
) {
|
verticalAlignment = Alignment.CenterVertically
|
||||||
Text(
|
) {
|
||||||
text = it,
|
Icon(
|
||||||
style = MaterialTheme.typography.bodySmall,
|
painter = painterResource(R.drawable.ic_dm),
|
||||||
color = Color.Gray,
|
stringResource(R.string.send_a_direct_message),
|
||||||
maxLines = 1,
|
modifier = Modifier.size(20.dp),
|
||||||
overflow = TextOverflow.Ellipsis
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = StdHorzSpacer)
|
||||||
|
|
||||||
|
Text(stringResource(id = R.string.send_the_seller_a_message))
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 10.dp, end = 10.dp, bottom = 5.dp, top = 5.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
val sellerName = note.author?.bestDisplayName() ?: note.author?.bestUsername()
|
||||||
|
|
||||||
|
val msg = if (sellerName != null) {
|
||||||
|
stringResource(
|
||||||
|
id = R.string.hi_seller_is_this_still_available,
|
||||||
|
sellerName
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
stringResource(id = R.string.hi_there_is_this_still_available)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var message by remember {
|
||||||
|
mutableStateOf(TextFieldValue(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField(
|
||||||
|
value = message,
|
||||||
|
onValueChange = {
|
||||||
|
message = it
|
||||||
|
},
|
||||||
|
keyboardOptions = KeyboardOptions.Default.copy(
|
||||||
|
capitalization = KeyboardCapitalization.Sentences
|
||||||
|
),
|
||||||
|
shape = EditFieldBorder,
|
||||||
|
modifier = Modifier.weight(1f, true),
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.reply_here),
|
||||||
|
color = MaterialTheme.colorScheme.placeholderText
|
||||||
|
)
|
||||||
|
},
|
||||||
|
textStyle = LocalTextStyle.current.copy(textDirection = TextDirection.Content),
|
||||||
|
trailingIcon = {
|
||||||
|
ThinSendButton(
|
||||||
|
isActive = message.text.isNotBlank(),
|
||||||
|
modifier = EditFieldTrailingIconModifier
|
||||||
|
) {
|
||||||
|
note.author?.let {
|
||||||
|
nav(routeToMessage(it, msg, accountViewModel))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = TextFieldDefaults.colors(
|
||||||
|
focusedIndicatorColor = Color.Transparent,
|
||||||
|
unfocusedIndicatorColor = Color.Transparent
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -664,4 +664,7 @@
|
|||||||
|
|
||||||
<string name="payment_required_title">Message from %1$s</string>
|
<string name="payment_required_title">Message from %1$s</string>
|
||||||
<string name="thread_title">Thread</string>
|
<string name="thread_title">Thread</string>
|
||||||
|
<string name="send_the_seller_a_message">Send the seller a message</string>
|
||||||
|
<string name="hi_seller_is_this_still_available">Hi %1$s, is this still available?</string>
|
||||||
|
<string name="hi_there_is_this_still_available">Hi there, is this still available?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class ClassifiedsEvent(
|
|||||||
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||||
fun title() = tags.firstOrNull { it.size > 1 && it[0] == "title" }?.get(1)
|
fun title() = tags.firstOrNull { it.size > 1 && it[0] == "title" }?.get(1)
|
||||||
fun image() = tags.firstOrNull { it.size > 1 && it[0] == "image" }?.get(1)
|
fun image() = tags.firstOrNull { it.size > 1 && it[0] == "image" }?.get(1)
|
||||||
|
fun images() = tags.filter { it.size > 1 && it[0] == "image" }.map { it[1] }
|
||||||
fun summary() = tags.firstOrNull { it.size > 1 && it[0] == "summary" }?.get(1)
|
fun summary() = tags.firstOrNull { it.size > 1 && it[0] == "summary" }?.get(1)
|
||||||
fun price() = tags.firstOrNull { it.size > 1 && it[0] == "price" }?.let {
|
fun price() = tags.firstOrNull { it.size > 1 && it[0] == "price" }?.let {
|
||||||
Price(it[1], it.getOrNull(2), it.getOrNull(3))
|
Price(it[1], it.getOrNull(2), it.getOrNull(3))
|
||||||
|
|||||||
Reference in New Issue
Block a user