fix: filter out empty-text/unknown-category questions from all DAO queries, regenerate app.db, handle deleted cloud question by falling back to random
This commit is contained in:
parent
606d724f12
commit
1b344e7220
|
|
@ -25,7 +25,7 @@ Closer gives couples a shared space for guided connection:
|
||||||
|
|
||||||
- **Daily question**: one prompt at a time, with written, scale, choice, and this-or-that answer modes.
|
- **Daily question**: one prompt at a time, with written, scale, choice, and this-or-that answer modes.
|
||||||
- **Private-first answers**: each person can answer privately before deciding whether to reveal or discuss.
|
- **Private-first answers**: each person can answer privately before deciding whether to reveal or discuss.
|
||||||
- **Question packs**: 20 curated categories across 2,500+ bundled prompts, including communication, conflict, trust, money, stress, intimacy, marriage, parenting, and date night.
|
- **Question packs**: 22 curated categories across 6,000+ bundled prompts, including communication, conflict, trust, money, stress, intimacy, marriage, parenting, and date night.
|
||||||
- **Answer history**: local answer storage, review flows, delete controls, and partner reveal support.
|
- **Answer history**: local answer storage, review flows, delete controls, and partner reveal support.
|
||||||
- **Discussion threads**: question-specific conversation threads and reactions for follow-up.
|
- **Discussion threads**: question-specific conversation threads and reactions for follow-up.
|
||||||
- **Partner pairing**: invite-code pairing, email invite flow, and partner-aware home states.
|
- **Partner pairing**: invite-code pairing, email invite flow, and partner-aware home states.
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -9,31 +9,31 @@ import app.closer.data.local.entity.QuestionEntity
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface QuestionDao {
|
interface QuestionDao {
|
||||||
@Query("SELECT * FROM question WHERE id = :id LIMIT 1")
|
@Query("SELECT * FROM question WHERE id = :id AND status = 'active' AND TRIM(text) <> '' LIMIT 1")
|
||||||
suspend fun getQuestionById(id: String): QuestionEntity?
|
suspend fun getQuestionById(id: String): QuestionEntity?
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE status = 'active' AND is_premium = 0 ORDER BY RANDOM() LIMIT 1")
|
@Query("SELECT * FROM question WHERE status = 'active' AND is_premium = 0 AND TRIM(text) <> '' AND category_id <> 'unknown' ORDER BY RANDOM() LIMIT 1")
|
||||||
suspend fun getDailyQuestion(): QuestionEntity?
|
suspend fun getDailyQuestion(): QuestionEntity?
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE category_id = :categoryId AND status = 'active' ORDER BY depth_level ASC, id ASC")
|
@Query("SELECT * FROM question WHERE category_id = :categoryId AND status = 'active' AND TRIM(text) <> '' ORDER BY depth_level ASC, id ASC")
|
||||||
suspend fun getQuestionsByCategory(categoryId: String): List<QuestionEntity>
|
suspend fun getQuestionsByCategory(categoryId: String): List<QuestionEntity>
|
||||||
|
|
||||||
@Query("SELECT COUNT(*) FROM question WHERE category_id = :categoryId AND status = 'active'")
|
@Query("SELECT COUNT(*) FROM question WHERE category_id = :categoryId AND status = 'active' AND TRIM(text) <> ''")
|
||||||
suspend fun getQuestionCountByCategory(categoryId: String): Int
|
suspend fun getQuestionCountByCategory(categoryId: String): Int
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE type = :type AND status = 'active'")
|
@Query("SELECT * FROM question WHERE type = :type AND status = 'active' AND TRIM(text) <> ''")
|
||||||
suspend fun getQuestionsByType(type: String): List<QuestionEntity>
|
suspend fun getQuestionsByType(type: String): List<QuestionEntity>
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE type IN ('single_choice', 'this_or_that', 'scale') AND status = 'active'")
|
@Query("SELECT * FROM question WHERE type IN ('single_choice', 'this_or_that', 'scale') AND status = 'active' AND TRIM(text) <> ''")
|
||||||
suspend fun getQuestionsForPrediction(): List<QuestionEntity>
|
suspend fun getQuestionsForPrediction(): List<QuestionEntity>
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE sex = :sex AND status = 'active'")
|
@Query("SELECT * FROM question WHERE sex = :sex AND status = 'active' AND TRIM(text) <> ''")
|
||||||
suspend fun getDesireSyncQuestions(sex: String): List<QuestionEntity>
|
suspend fun getDesireSyncQuestions(sex: String): List<QuestionEntity>
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE is_premium = 0 AND status = 'active'")
|
@Query("SELECT * FROM question WHERE is_premium = 0 AND status = 'active' AND TRIM(text) <> ''")
|
||||||
suspend fun getFreeQuestions(): List<QuestionEntity>
|
suspend fun getFreeQuestions(): List<QuestionEntity>
|
||||||
|
|
||||||
@Query("SELECT * FROM question WHERE is_premium = 1 AND status = 'active'")
|
@Query("SELECT * FROM question WHERE is_premium = 1 AND status = 'active' AND TRIM(text) <> ''")
|
||||||
suspend fun getPremiumQuestions(): List<QuestionEntity>
|
suspend fun getPremiumQuestions(): List<QuestionEntity>
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,9 @@ private fun ThisOrThatCard(
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.heightIn(min = 132.dp),
|
||||||
shape = RoundedCornerShape(24.dp),
|
shape = RoundedCornerShape(24.dp),
|
||||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
|
||||||
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
|
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
|
||||||
|
|
@ -364,7 +366,7 @@ private fun HowWellCard(
|
||||||
text = "How Well Do You Know Me",
|
text = "How Well Do You Know Me",
|
||||||
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold),
|
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold),
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
maxLines = 1,
|
maxLines = 2,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ class DailyQuestionViewModel @Inject constructor(
|
||||||
}.onFailure { crashReporter.recordException(it) }.getOrNull()
|
}.onFailure { crashReporter.recordException(it) }.getOrNull()
|
||||||
|
|
||||||
val question = if (assignment != null) {
|
val question = if (assignment != null) {
|
||||||
repository.getQuestionById(assignment.questionId)
|
repository.getQuestionById(assignment.questionId) ?: repository.getDailyQuestion()
|
||||||
} else {
|
} else {
|
||||||
// No assignment yet. Request immediate assignment, but keep the app
|
// No assignment yet. Request immediate assignment, but keep the app
|
||||||
// usable with a local random question in case the call fails.
|
// usable with a local random question in case the call fails.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue