fix(questions): update category and pack library screens
This commit is contained in:
parent
888ffa3c1a
commit
0e9606366b
|
|
@ -1,6 +1,8 @@
|
|||
package com.couplesconnect.app.ui.questions
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
@ -10,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
|
@ -22,6 +25,9 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
|
|
@ -59,6 +65,13 @@ private fun QuestionCategoryContent(
|
|||
state: QuestionCategoryUiState,
|
||||
onQuestionSelected: (Question) -> Unit
|
||||
) {
|
||||
var selectedType by remember { mutableStateOf<String?>(null) }
|
||||
val visibleQuestions = remember(state.questions, selectedType) {
|
||||
state.questions.filter { question ->
|
||||
selectedType == null || question.type == selectedType
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -81,22 +94,12 @@ private fun QuestionCategoryContent(
|
|||
item {
|
||||
val title = state.category?.displayName
|
||||
?: categoryId.displayCategoryName()
|
||||
Column(
|
||||
modifier = Modifier.padding(top = 20.dp, bottom = 6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.headlineLarge.copy(fontWeight = FontWeight.SemiBold),
|
||||
color = Color(0xFF27211F)
|
||||
)
|
||||
Text(
|
||||
text = state.category?.description
|
||||
?: "Browse prompts for this kind of conversation.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
}
|
||||
CategoryHero(
|
||||
title = title,
|
||||
category = state.category,
|
||||
questionCount = state.questions.size,
|
||||
modifier = Modifier.padding(top = 20.dp, bottom = 6.dp)
|
||||
)
|
||||
}
|
||||
|
||||
when {
|
||||
|
|
@ -115,23 +118,163 @@ private fun QuestionCategoryContent(
|
|||
}
|
||||
else -> {
|
||||
item {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
CategoryPill("${state.questions.size} prompts")
|
||||
state.category?.access?.let { CategoryPill(it.displayCategoryName()) }
|
||||
}
|
||||
}
|
||||
items(state.questions, key = { it.id }) { question ->
|
||||
QuestionListCard(
|
||||
question = question,
|
||||
onClick = { onQuestionSelected(question) }
|
||||
CategoryFilters(
|
||||
questions = state.questions,
|
||||
selectedType = selectedType,
|
||||
onTypeSelected = { selectedType = it }
|
||||
)
|
||||
}
|
||||
if (visibleQuestions.isEmpty()) {
|
||||
item {
|
||||
CategoryMessageCard(
|
||||
title = "No prompts match",
|
||||
message = "Try another filter to keep browsing."
|
||||
)
|
||||
}
|
||||
} else {
|
||||
visibleQuestions.groupBy { it.depthLevel }.toSortedMap().forEach { (depth, questions) ->
|
||||
item(key = "depth-$depth") {
|
||||
DepthHeader(depth = depth, count = questions.size)
|
||||
}
|
||||
items(questions, key = { it.id }) { question ->
|
||||
QuestionListCard(
|
||||
question = question,
|
||||
onClick = { onQuestionSelected(question) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CategoryHero(
|
||||
title: String,
|
||||
category: QuestionCategory?,
|
||||
questionCount: Int,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.headlineLarge.copy(fontWeight = FontWeight.SemiBold),
|
||||
color = Color(0xFF27211F),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = category?.description
|
||||
?: "Browse prompts for this kind of conversation.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.horizontalScroll(rememberScrollState()),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
CategoryPill("$questionCount ${if (questionCount == 1) "prompt" else "prompts"}", emphasis = true)
|
||||
category?.access?.let { CategoryPill(it.displayCategoryName()) }
|
||||
category?.iconName
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?.let { it.displayCategoryName() }
|
||||
?.takeIf { it != "Question" }
|
||||
?.let { CategoryPill(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CategoryFilters(
|
||||
questions: List<Question>,
|
||||
selectedType: String?,
|
||||
onTypeSelected: (String?) -> Unit
|
||||
) {
|
||||
val types = questions.map { it.type }.distinct().sorted()
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Text(
|
||||
text = "Format",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = Color(0xFF4E4642),
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.horizontalScroll(rememberScrollState()),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
(listOf(null) + types).forEach { option ->
|
||||
FilterPill(
|
||||
label = option?.displayQuestionFilterName() ?: "All",
|
||||
selected = selectedType == option,
|
||||
onClick = { onTypeSelected(option) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.displayQuestionFilterName(): String {
|
||||
return when (this) {
|
||||
"single_choice" -> "Single"
|
||||
"multi_choice" -> "Multi"
|
||||
"this_or_that" -> "Either/or"
|
||||
"scale" -> "Scale"
|
||||
else -> "Written"
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FilterPill(
|
||||
label: String,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.clickable(onClick = onClick),
|
||||
shape = RoundedCornerShape(999.dp),
|
||||
color = if (selected) Color(0xFFF3E8FF) else Color.White.copy(alpha = 0.74f),
|
||||
shadowElevation = if (selected) 2.dp else 0.dp
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
modifier = Modifier.padding(horizontal = 13.dp, vertical = 8.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = if (selected) Color(0xFF5F3A87) else Color(0xFF3E3734),
|
||||
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Medium,
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DepthHeader(depth: Int, count: Int) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 6.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = "Depth $depth",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = Color(0xFF27211F),
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
CategoryPill("$count ${if (count == 1) "prompt" else "prompts"}")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun QuestionListCard(
|
||||
question: Question,
|
||||
|
|
@ -140,13 +283,13 @@ private fun QuestionListCard(
|
|||
Card(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(22.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.84f)),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 5.dp)
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.9f)),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 3.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(17.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
Text(
|
||||
text = question.text,
|
||||
|
|
@ -157,7 +300,6 @@ private fun QuestionListCard(
|
|||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
CategoryPill("Depth ${question.depthLevel}")
|
||||
CategoryPill(question.type.displayQuestionType())
|
||||
if (question.isPremium) {
|
||||
CategoryPill("Premium")
|
||||
|
|
@ -170,16 +312,19 @@ private fun QuestionListCard(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun CategoryPill(label: String) {
|
||||
private fun CategoryPill(
|
||||
label: String,
|
||||
emphasis: Boolean = false
|
||||
) {
|
||||
Surface(
|
||||
shape = RoundedCornerShape(999.dp),
|
||||
color = Color(0xFFF8F4F1)
|
||||
color = if (emphasis) Color(0xFFF3E8FF) else Color(0xFFF8F4F1)
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
modifier = Modifier.padding(horizontal = 11.dp, vertical = 7.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = Color(0xFF3E3734),
|
||||
color = if (emphasis) Color(0xFF5F3A87) else Color(0xFF3E3734),
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,36 @@
|
|||
package com.couplesconnect.app.ui.questions
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Lock
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
|
|
@ -41,6 +44,13 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import com.couplesconnect.app.core.navigation.AppRoute
|
||||
import com.couplesconnect.app.domain.model.QuestionCategory
|
||||
|
||||
private enum class PackFilter(val label: String) {
|
||||
ALL("All"),
|
||||
FREE("Free"),
|
||||
MIXED("Mixed"),
|
||||
PREMIUM("Premium")
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun QuestionPackLibraryScreen(
|
||||
onNavigate: (String) -> Unit = {},
|
||||
|
|
@ -61,6 +71,18 @@ private fun QuestionPackLibraryContent(
|
|||
onPackSelected: (QuestionPackItem) -> Unit,
|
||||
onPaywall: () -> Unit
|
||||
) {
|
||||
var selectedFilter by remember { mutableStateOf(PackFilter.ALL) }
|
||||
val visiblePacks = remember(state.packs, selectedFilter) {
|
||||
state.packs.filter { item ->
|
||||
when (selectedFilter) {
|
||||
PackFilter.ALL -> true
|
||||
PackFilter.FREE -> item.category.access == "free"
|
||||
PackFilter.MIXED -> item.category.access == "mixed"
|
||||
PackFilter.PREMIUM -> item.category.access == "premium"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -112,8 +134,28 @@ private fun QuestionPackLibraryContent(
|
|||
message = "Question packs are not available right now. Try again in a moment."
|
||||
)
|
||||
}
|
||||
visiblePacks.isEmpty() -> {
|
||||
item {
|
||||
PackFilterRow(
|
||||
selected = selectedFilter,
|
||||
onSelected = { selectedFilter = it }
|
||||
)
|
||||
}
|
||||
item {
|
||||
PackMessageCard(
|
||||
title = "Nothing in ${selectedFilter.label.lowercase()} yet",
|
||||
message = "Try another filter to keep browsing."
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
items(state.packs, key = { it.category.id }) { item ->
|
||||
item {
|
||||
PackFilterRow(
|
||||
selected = selectedFilter,
|
||||
onSelected = { selectedFilter = it }
|
||||
)
|
||||
}
|
||||
items(visiblePacks, key = { it.category.id }) { item ->
|
||||
QuestionPackCard(
|
||||
item = item,
|
||||
onClick = {
|
||||
|
|
@ -148,82 +190,164 @@ private fun QuestionPackCard(
|
|||
onClick: () -> Unit
|
||||
) {
|
||||
val containerColor = if (item.isLocked)
|
||||
Color(0xFFF5F0EC).copy(alpha = 0.84f)
|
||||
Color(0xFFFAF7F5).copy(alpha = 0.9f)
|
||||
else
|
||||
Color.White.copy(alpha = 0.84f)
|
||||
Color.White.copy(alpha = 0.9f)
|
||||
val accent = packAccent(item.category.id)
|
||||
|
||||
Card(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(26.dp),
|
||||
shape = RoundedCornerShape(22.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = containerColor),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(18.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(14.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.Top
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(5.dp)
|
||||
.background(if (item.isLocked) Color(0xFFD9D1CE) else accent)
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(17.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.Top
|
||||
) {
|
||||
Text(
|
||||
text = item.category.displayName.ifBlank { item.category.id.displayCategoryName() },
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = if (item.isLocked) Color(0xFF9E9693) else Color(0xFF27211F),
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = item.category.description,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642),
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||
) {
|
||||
Text(
|
||||
text = item.category.displayName.ifBlank { item.category.id.displayCategoryName() },
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = Color(0xFF27211F),
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = item.category.description,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
PackPill(item.promptCountLabel(), emphasis = true)
|
||||
}
|
||||
if (item.isLocked) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Lock,
|
||||
contentDescription = "Premium",
|
||||
tint = Color(0xFFB0A9A6),
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
} else {
|
||||
PackPill("${item.questionCount} prompts")
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.horizontalScroll(rememberScrollState()),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
item.metadataLabels().forEach { label ->
|
||||
PackPill(label, emphasis = label == "Premium")
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (item.isPremium) PackPill("Premium")
|
||||
PackPill(item.category.access.displayCategoryName())
|
||||
PackPill(item.category.iconName.ifBlank { "question" }.displayCategoryName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PackPill(label: String) {
|
||||
private fun PackFilterRow(
|
||||
selected: PackFilter,
|
||||
onSelected: (PackFilter) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.horizontalScroll(rememberScrollState()),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
PackFilter.entries.forEach { filter ->
|
||||
FilterPill(
|
||||
label = filter.label,
|
||||
selected = selected == filter,
|
||||
onClick = { onSelected(filter) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FilterPill(
|
||||
label: String,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.clickable(onClick = onClick),
|
||||
shape = RoundedCornerShape(999.dp),
|
||||
color = if (selected) Color(0xFFF3E8FF) else Color.White.copy(alpha = 0.74f),
|
||||
tonalElevation = 0.dp,
|
||||
shadowElevation = if (selected) 3.dp else 0.dp
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
modifier = Modifier.padding(horizontal = 13.dp, vertical = 8.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = if (selected) Color(0xFF5F3A87) else Color(0xFF3E3734),
|
||||
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Medium,
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PackPill(
|
||||
label: String,
|
||||
emphasis: Boolean = false
|
||||
) {
|
||||
Surface(
|
||||
shape = RoundedCornerShape(999.dp),
|
||||
color = Color(0xFFF8F4F1)
|
||||
color = if (emphasis) Color(0xFFF3E8FF) else Color(0xFFF8F4F1)
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
modifier = Modifier.padding(horizontal = 11.dp, vertical = 7.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = Color(0xFF3E3734),
|
||||
color = if (emphasis) Color(0xFF5F3A87) else Color(0xFF3E3734),
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun QuestionPackItem.promptCountLabel(): String =
|
||||
"$questionCount ${if (questionCount == 1) "prompt" else "prompts"}"
|
||||
|
||||
private fun QuestionPackItem.metadataLabels(): List<String> {
|
||||
val access = when (category.access) {
|
||||
"premium" -> "Premium"
|
||||
"mixed" -> "Mixed access"
|
||||
"free" -> "Free"
|
||||
else -> category.access.displayCategoryName()
|
||||
}
|
||||
return listOf(
|
||||
access,
|
||||
category.iconName.ifBlank { "question" }.displayCategoryName()
|
||||
).filterNot { it == "Question" }.distinct()
|
||||
}
|
||||
|
||||
private fun packAccent(categoryId: String): Color {
|
||||
val palette = listOf(
|
||||
Color(0xFF5F3A87),
|
||||
Color(0xFF5C7C8A),
|
||||
Color(0xFF6F7D4F),
|
||||
Color(0xFF8A5A74),
|
||||
Color(0xFF7A6A3A)
|
||||
)
|
||||
return palette[kotlin.math.abs(categoryId.hashCode()) % palette.size]
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LoadingPackCard() {
|
||||
Card(
|
||||
|
|
|
|||
Loading…
Reference in New Issue