- Improves rendering of the completed polls
- Doesn't render quoted polls
This commit is contained in:
@@ -36,6 +36,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
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.layout.width
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
@@ -56,7 +57,13 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.draw.drawWithContent
|
import androidx.compose.ui.draw.drawWithContent
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.drawscope.clipRect
|
import androidx.compose.ui.graphics.drawscope.clipRect
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalFontFamilyResolver
|
||||||
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
|
import androidx.compose.ui.text.TextMeasurer
|
||||||
|
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.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -82,11 +89,10 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size25dp
|
import com.vitorpamplona.amethyst.ui.theme.Size25dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.SmallishBorder
|
import com.vitorpamplona.amethyst.ui.theme.SmallishBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.SpacedBy10dp
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.SpacedBy5dp
|
import com.vitorpamplona.amethyst.ui.theme.SpacedBy5dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||||
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
|
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
|
||||||
import com.vitorpamplona.amethyst.ui.theme.grayText
|
import com.vitorpamplona.amethyst.ui.theme.grayText
|
||||||
@@ -174,11 +180,11 @@ fun InnerRenderPoll(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { code, label ->
|
) { code, label, closed ->
|
||||||
TranslatableRichTextViewer(
|
TranslatableRichTextViewer(
|
||||||
content = label,
|
content = label,
|
||||||
canPreview = canPreview,
|
canPreview = canPreview,
|
||||||
quotesLeft = 1,
|
quotesLeft = if (quotesLeft > 0) 1 else 0,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
tags = tags,
|
tags = tags,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
@@ -221,7 +227,7 @@ fun RenderPollCard(
|
|||||||
pollState: PollResponsesCache,
|
pollState: PollResponsesCache,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
galleryUser: @Composable RowScope.(user: User) -> Unit,
|
galleryUser: @Composable RowScope.(user: User) -> Unit,
|
||||||
labelContent: @Composable ColumnScope.(code: String, label: String) -> Unit,
|
labelContent: @Composable ColumnScope.(code: String, label: String, closed: Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
val card =
|
val card =
|
||||||
remember(event) {
|
remember(event) {
|
||||||
@@ -274,7 +280,7 @@ fun RenderPollCard(
|
|||||||
card: PollCard,
|
card: PollCard,
|
||||||
onRespond: (Set<String>) -> Unit,
|
onRespond: (Set<String>) -> Unit,
|
||||||
resultContent: @Composable RowScope.(user: User) -> Unit,
|
resultContent: @Composable RowScope.(user: User) -> Unit,
|
||||||
labelContent: @Composable ColumnScope.(code: String, label: String) -> Unit,
|
labelContent: @Composable ColumnScope.(code: String, label: String, closed: Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = SpacedBy5dp,
|
verticalArrangement = SpacedBy5dp,
|
||||||
@@ -306,7 +312,7 @@ fun RenderPollCard(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.RenderSingleChoiceOptions(
|
private fun ColumnScope.RenderSingleChoiceOptions(
|
||||||
card: PollCard,
|
card: PollCard,
|
||||||
labelContent: @Composable (ColumnScope.(String, String) -> Unit),
|
labelContent: @Composable (ColumnScope.(String, String, closed: Boolean) -> Unit),
|
||||||
onRespond: (Set<String>) -> Unit,
|
onRespond: (Set<String>) -> Unit,
|
||||||
) {
|
) {
|
||||||
card.options.forEach {
|
card.options.forEach {
|
||||||
@@ -333,7 +339,7 @@ private fun ColumnScope.RenderSingleChoiceOptions(
|
|||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
labelContent(it.code, it.label)
|
labelContent(it.code, it.label, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,7 +349,7 @@ private fun ColumnScope.RenderSingleChoiceOptions(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.RenderMultiChoiceOptions(
|
private fun ColumnScope.RenderMultiChoiceOptions(
|
||||||
card: PollCard,
|
card: PollCard,
|
||||||
labelContent: @Composable (ColumnScope.(String, String) -> Unit),
|
labelContent: @Composable (ColumnScope.(String, String, closed: Boolean) -> Unit),
|
||||||
onRespond: (Set<String>) -> Unit,
|
onRespond: (Set<String>) -> Unit,
|
||||||
) {
|
) {
|
||||||
var multichoice by
|
var multichoice by
|
||||||
@@ -380,7 +386,7 @@ private fun ColumnScope.RenderMultiChoiceOptions(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
) {
|
) {
|
||||||
labelContent(option.code, option.label)
|
labelContent(option.code, option.label, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,11 +407,11 @@ private fun ColumnScope.RenderMultiChoiceOptions(
|
|||||||
private fun RenderResults(
|
private fun RenderResults(
|
||||||
card: PollCard,
|
card: PollCard,
|
||||||
resultContent: @Composable RowScope.(user: User) -> Unit,
|
resultContent: @Composable RowScope.(user: User) -> Unit,
|
||||||
labelContent: @Composable (ColumnScope.(code: String, label: String) -> Unit),
|
labelContent: @Composable (ColumnScope.(code: String, label: String, closed: Boolean) -> Unit),
|
||||||
) {
|
) {
|
||||||
card.options.forEach { pollItem ->
|
card.options.forEach { pollItem ->
|
||||||
RenderClosedItem(pollItem, resultContent) {
|
RenderClosedItem(pollItem, resultContent) {
|
||||||
labelContent(pollItem.code, pollItem.label)
|
labelContent(pollItem.code, pollItem.label, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -418,12 +424,13 @@ private fun RenderClosedItem(
|
|||||||
) {
|
) {
|
||||||
val tally by item.results.collectAsStateWithLifecycle(item.currentResults())
|
val tally by item.results.collectAsStateWithLifecycle(item.currentResults())
|
||||||
|
|
||||||
RenderClosedItem(tally, resultContent, labelContent)
|
RenderClosedItem(tally, item.label, resultContent, labelContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RenderClosedItem(
|
private fun RenderClosedItem(
|
||||||
tally: TallyResults,
|
tally: TallyResults,
|
||||||
|
label: String,
|
||||||
resultContent: @Composable RowScope.(user: User) -> Unit,
|
resultContent: @Composable RowScope.(user: User) -> Unit,
|
||||||
labelContent: @Composable ColumnScope.() -> Unit,
|
labelContent: @Composable ColumnScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -481,18 +488,21 @@ private fun RenderClosedItem(
|
|||||||
content = labelContent,
|
content = labelContent,
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(StdHorzSpacer)
|
Spacer(DoubleHorzSpacer)
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = SpacedBy10dp,
|
|
||||||
) {
|
) {
|
||||||
UserGallery(tally, resultContent)
|
if (label.length < 30) {
|
||||||
|
UserGallery(tally, resultContent)
|
||||||
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "${(tally.percent * 100).toInt()}%",
|
text = "${(tally.percent * 100).toInt()}%",
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.End,
|
||||||
|
modifier = measure100PercentWidthModifier(MaterialTheme.typography.bodyMedium),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -500,6 +510,24 @@ private fun RenderClosedItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun measure100PercentWidthModifier(textStyle: TextStyle): Modifier {
|
||||||
|
val fontFamilyResolver = LocalFontFamilyResolver.current
|
||||||
|
val density = LocalDensity.current
|
||||||
|
val layoutDirection = LocalLayoutDirection.current
|
||||||
|
|
||||||
|
return remember(fontFamilyResolver, density, layoutDirection, textStyle) {
|
||||||
|
val widthPx =
|
||||||
|
TextMeasurer(fontFamilyResolver, density, layoutDirection, 1)
|
||||||
|
.measure("100%", style = textStyle.copy(fontWeight = FontWeight.Bold))
|
||||||
|
.size
|
||||||
|
.width
|
||||||
|
with(density) {
|
||||||
|
Modifier.width(widthPx.toDp())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserGallery(
|
fun UserGallery(
|
||||||
tally: TallyResults,
|
tally: TallyResults,
|
||||||
@@ -510,13 +538,13 @@ fun UserGallery(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy((-10).dp),
|
horizontalArrangement = Arrangement.spacedBy((-10).dp),
|
||||||
) {
|
) {
|
||||||
tally.users.take(6).forEach {
|
tally.users.take(4).forEach {
|
||||||
key(it.pubkeyHex) {
|
key(it.pubkeyHex) {
|
||||||
galleryUser(it)
|
galleryUser(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tally.users.size > 6) {
|
if (tally.users.size > 4) {
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
modifier =
|
modifier =
|
||||||
@@ -526,7 +554,7 @@ fun UserGallery(
|
|||||||
.background(MaterialTheme.colorScheme.secondaryContainer),
|
.background(MaterialTheme.colorScheme.secondaryContainer),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "+" + showCount(tally.users.size - 6),
|
text = "+" + showCount(tally.users.size - 4),
|
||||||
fontSize = 10.sp,
|
fontSize = 10.sp,
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
)
|
)
|
||||||
@@ -575,7 +603,55 @@ fun RenderPollManualPreview() {
|
|||||||
|
|
||||||
ThemeComparisonColumn {
|
ThemeComparisonColumn {
|
||||||
Column(Modifier.padding(10.dp)) {
|
Column(Modifier.padding(10.dp)) {
|
||||||
RenderPollCard(poll, {}, {}) { _, label ->
|
RenderPollCard(poll, {}, {}) { _, label, closed ->
|
||||||
|
Text(
|
||||||
|
text = label,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun RenderPollManualLongPreview() {
|
||||||
|
val poll =
|
||||||
|
PollCard(
|
||||||
|
options =
|
||||||
|
listOf(
|
||||||
|
PollItemCard(
|
||||||
|
code = "1",
|
||||||
|
label = "Yes".repeat(300),
|
||||||
|
results = flow {},
|
||||||
|
currentResults = {
|
||||||
|
TallyResults(
|
||||||
|
percent = 1.0f,
|
||||||
|
isWinning = true,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
PollItemCard(
|
||||||
|
code = "2",
|
||||||
|
label = "No".repeat(300),
|
||||||
|
results = flow {},
|
||||||
|
currentResults = {
|
||||||
|
TallyResults(
|
||||||
|
percent = 0.0f,
|
||||||
|
isWinning = false,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
type = PollType.SINGLE_CHOICE,
|
||||||
|
endsAt = null,
|
||||||
|
isMyPoll = true,
|
||||||
|
haveIVotedFlow = flow {},
|
||||||
|
haveIVoted = { true },
|
||||||
|
)
|
||||||
|
|
||||||
|
ThemeComparisonColumn {
|
||||||
|
Column(Modifier.padding(10.dp)) {
|
||||||
|
RenderPollCard(poll, {}, {}) { _, label, closed ->
|
||||||
Text(
|
Text(
|
||||||
text = label,
|
text = label,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user