Skip to content

Latest commit

ย 

History

History
833 lines (696 loc) ยท 21.6 KB

File metadata and controls

833 lines (696 loc) ยท 21.6 KB

Adding Taco Facts to TacoTracker

This guide shows you how to add personalized user statistics and general taco trivia to the TacoTracker app.


๐Ÿ“‹ Table of Contents

  1. Understanding Fact Types
  2. User Stats Facts (Personalized)
  3. General Trivia Facts
  4. Where to Display Facts
  5. Examples & Ideas

๐ŸŽ“ Understanding Fact Types

User Stats Facts

Personalized statistics based on the user's data:

  • "You've eaten 247 tacos!"
  • "Your most common protein is chicken"
  • "You eat tacos most often on Tuesdays"

Calculated dynamically from meal data.

General Trivia Facts

Universal taco knowledge:

  • "The word 'taco' appeared in English in 1905"
  • "Tacos al pastor were inspired by Lebanese shawarma"
  • "Americans eat 4.5 billion tacos per year"

Static list that rotates randomly.


๐ŸŽฏ User Stats Facts (Personalized)

User stats are calculated on-demand from meal data. They live in your ViewModels and repositories.

Where They Live

User stats are typically calculated in:

  1. StatsScreen.kt - Main statistics display
  2. HomeScreen.kt - Quick stats on dashboard
  3. SaveSuccessScreen.kt - Post-meal summary

Step-by-Step: Add a New User Stat

Example: "Your Spiciest Month"

Let's add a stat showing which month the user ate the most spicy tacos.


Step 1: Add Calculation Function

File: app/src/main/java/com/dinorawrger/tacotracker/ui/StatsScreen.kt

Add a helper function to calculate the stat:

/**
 * Find the month with the most spicy tacos.
 * 
 * @return Pair of (month name, spicy taco count) or null if no spicy tacos
 */
private fun findSpiciestMonth(meals: List<MealWithTacos>): Pair<String, Int>? {
    val spicyKeywords = listOf("jalapeรฑo", "habanero", "serrano", "chipotle", 
                               "hot sauce", "spicy", "picante", "ghost pepper")
    
    val calendar = Calendar.getInstance()
    val monthFormat = SimpleDateFormat("MMMM", Locale.getDefault())  // "January", "February", etc.
    
    // Group meals by month, count spicy tacos
    val tacosByMonth = meals
        .groupBy { meal ->
            calendar.timeInMillis = meal.meal.eatenAtEpochMillis
            monthFormat.format(calendar.time)
        }
        .mapValues { (_, mealsInMonth) ->
            mealsInMonth
                .flatMap { it.tacos }
                .count { taco ->
                    taco.ingredients.any { ingredient ->
                        spicyKeywords.any { keyword ->
                            ingredient.name.contains(keyword, ignoreCase = true)
                        }
                    }
                }
        }
        .filter { it.value > 0 }  // Only months with spicy tacos
    
    // Find month with most spicy tacos
    return tacosByMonth.maxByOrNull { it.value }?.toPair()
}

Step 2: Display the Stat

In your StatsScreen composable:

@Composable
fun StatsScreen(meals: List<MealWithTacos>) {
    // ... existing stats ...
    
    // Calculate spiciest month
    val spiciestMonth = remember(meals) { findSpiciestMonth(meals) }
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
            .padding(16.dp)
    ) {
        // ... existing UI ...
        
        // Spiciest month card
        spiciestMonth?.let { (month, count) ->
            StatCard(
                title = "๐ŸŒถ๏ธ Spiciest Month",
                value = month,
                subtitle = "$count spicy tacos"
            )
        }
    }
}

/**
 * Reusable stat card component.
 */
@Composable
private fun StatCard(
    title: String,
    value: String,
    subtitle: String? = null
) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)
        ) {
            Text(
                text = title,
                style = MaterialTheme.typography.labelMedium,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Text(
                text = value,
                style = MaterialTheme.typography.headlineMedium,
                modifier = Modifier.padding(vertical = 4.dp)
            )
            subtitle?.let {
                Text(
                    text = it,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }
    }
}

Done! The stat now appears on your stats screen. ๐ŸŽ‰


Common User Stat Patterns

Most Common Value

// Most common location
private fun findTopLocation(meals: List<MealWithTacos>): String? {
    return meals
        .groupBy { it.meal.location.trim().lowercase() }
        .filter { it.key.isNotBlank() }
        .maxByOrNull { it.value.size }
        ?.key
        ?.replaceFirstChar { it.titlecase() }
}

Percentage Calculation

// Percentage of meals that are breakfast
private fun calculateBreakfastPercentage(meals: List<MealWithTacos>): Int {
    if (meals.isEmpty()) return 0
    
    val breakfastCount = meals.count { 
        it.meal.mealType.equals("Breakfast", ignoreCase = true) 
    }
    
    return (breakfastCount * 100 / meals.size)
}

Average Calculation

// Average tacos per meal
private fun calculateAverageTacosPerMeal(meals: List<MealWithTacos>): Double {
    if (meals.isEmpty()) return 0.0
    
    val totalTacos = meals.sumOf { it.meal.totalTacos }
    return totalTacos.toDouble() / meals.size
}

Date/Time Analysis

// Most active day of week
private fun findMostActiveDayOfWeek(meals: List<MealWithTacos>): String? {
    val calendar = Calendar.getInstance()
    val dayFormat = SimpleDateFormat("EEEE", Locale.getDefault())  // "Monday", "Tuesday", etc.
    
    return meals
        .groupBy { meal ->
            calendar.timeInMillis = meal.meal.eatenAtEpochMillis
            dayFormat.format(calendar.time)
        }
        .maxByOrNull { it.value.size }
        ?.key
}

Streak Calculation

// Longest streak of consecutive days with tacos
private fun calculateLongestStreak(meals: List<MealWithTacos>): Int {
    if (meals.isEmpty()) return 0
    
    val calendar = Calendar.getInstance()
    val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
    
    // Get unique dates (ignore time)
    val dates = meals
        .map { meal ->
            calendar.timeInMillis = meal.meal.eatenAtEpochMillis
            dateFormat.format(calendar.time)
        }
        .distinct()
        .sorted()
    
    var maxStreak = 1
    var currentStreak = 1
    
    for (i in 1 until dates.size) {
        val prevDate = dateFormat.parse(dates[i - 1])!!
        val currDate = dateFormat.parse(dates[i])!!
        
        val daysBetween = ((currDate.time - prevDate.time) / (1000 * 60 * 60 * 24)).toInt()
        
        if (daysBetween == 1) {
            currentStreak++
            maxStreak = maxOf(maxStreak, currentStreak)
        } else {
            currentStreak = 1
        }
    }
    
    return maxStreak
}

Time Range Stats

// Total tacos in the last 30 days
private fun calculateLast30Days(meals: List<MealWithTacos>): Int {
    val thirtyDaysAgo = System.currentTimeMillis() - (30L * 24 * 60 * 60 * 1000)
    
    return meals
        .filter { it.meal.eatenAtEpochMillis >= thirtyDaysAgo }
        .sumOf { it.meal.totalTacos }
}

๐Ÿ“œ General Trivia Facts

General trivia facts are static strings that rotate randomly. Perfect for loading screens, home screen widgets, or "did you know?" sections.

Step-by-Step: Add Trivia System

Step 1: Create a Facts Data Class

File: app/src/main/java/com/dinorawrger/tacotracker/data/TacoFacts.kt (CREATE NEW)

package com.dinorawrger.tacotracker.data

/**
 * Collection of taco trivia, history, and culinary facts.
 */
object TacoFacts {
    
    /**
     * Categories of facts for organization.
     */
    enum class Category {
        HISTORY,
        CULINARY,
        CULTURAL,
        STATISTICS,
        FUN
    }
    
    /**
     * Single fact with optional category.
     */
    data class Fact(
        val text: String,
        val category: Category = Category.FUN
    )
    
    /**
     * All available facts.
     * Add new facts to this list!
     */
    private val allFacts = listOf(
        // HISTORY
        Fact(
            "The word 'taco' first appeared in English text in 1905.",
            Category.HISTORY
        ),
        Fact(
            "Tacos have been eaten in Mexico for thousands of years, dating back to the Aztecs.",
            Category.HISTORY
        ),
        Fact(
            "The first known mention of tacos in Mexico City dates to the 18th century.",
            Category.HISTORY
        ),
        Fact(
            "Tacos al pastor were inspired by Lebanese immigrants who brought shawarma to Mexico.",
            Category.HISTORY
        ),
        
        // CULINARY
        Fact(
            "Authentic Mexican tacos are typically served on small corn tortillas, not flour.",
            Category.CULINARY
        ),
        Fact(
            "The perfect taco should be eaten in 2-3 bites - any more and it's too big!",
            Category.CULINARY
        ),
        Fact(
            "Traditional tacos are topped with cilantro and onions, not lettuce and cheese.",
            Category.CULINARY
        ),
        Fact(
            "Corn tortillas are naturally gluten-free and have been made the same way for millennia.",
            Category.CULINARY
        ),
        Fact(
            "The spiciest pepper commonly used in tacos is the habanero, which can reach 350,000 Scoville units.",
            Category.CULINARY
        ),
        
        // CULTURAL
        Fact(
            "In Mexico, tacos are often eaten for breakfast, not just lunch or dinner.",
            Category.CULTURAL
        ),
        Fact(
            "Taco Tuesday became popular in the US in the 1980s as a restaurant promotion.",
            Category.CULTURAL
        ),
        Fact(
            "Mexico City has over 20,000 taco stands - more than any other city in the world.",
            Category.CULTURAL
        ),
        Fact(
            "October 4th is National Taco Day in the United States.",
            Category.CULTURAL
        ),
        
        // STATISTICS
        Fact(
            "Americans eat approximately 4.5 billion tacos per year.",
            Category.STATISTICS
        ),
        Fact(
            "The average American eats about 14 tacos per year.",
            Category.STATISTICS
        ),
        Fact(
            "Carne asada is the most popular taco filling in the United States.",
            Category.STATISTICS
        ),
        
        // FUN
        Fact(
            "The world's largest taco weighed 1,654 pounds and was made in Mexicali in 2003.",
            Category.FUN
        ),
        Fact(
            "A taco emoji (๐ŸŒฎ) was added to Unicode in 2015 after a popular petition.",
            Category.FUN
        ),
        Fact(
            "The taco shell as we know it was invented in the 1940s in California.",
            Category.FUN
        ),
        Fact(
            "There are over 40 different types of tacos recognized in Mexican cuisine.",
            Category.FUN
        ),
        Fact(
            "The word 'taco' literally means 'plug' or 'wad' in Spanish.",
            Category.FUN
        ),
        Fact(
            "Fish tacos originated in Baja California and became popular worldwide in the 1980s.",
            Category.FUN
        )
    )
    
    /**
     * Get a random fact.
     */
    fun getRandom(): Fact = allFacts.random()
    
    /**
     * Get a random fact from a specific category.
     */
    fun getRandomByCategory(category: Category): Fact? {
        return allFacts.filter { it.category == category }.randomOrNull()
    }
    
    /**
     * Get all facts.
     */
    fun getAll(): List<Fact> = allFacts
    
    /**
     * Get all facts from a category.
     */
    fun getAllByCategory(category: Category): List<Fact> {
        return allFacts.filter { it.category == category }
    }
}

Step 2: Display Facts in UI

Example: Add to Home Screen

File: app/src/main/java/com/dinorawrger/tacotracker/ui/HomeScreen.kt

@Composable
fun HomeScreen(
    meals: List<MealWithTacos>,
    onNewEntry: () -> Unit,
    onViewHistory: () -> Unit,
    onViewStats: () -> Unit,
    onViewFavorites: () -> Unit
) {
    // Get a random fact (changes each time screen recomposes)
    val randomFact = remember { TacoFacts.getRandom() }
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
            .padding(16.dp)
    ) {
        // ... existing home screen content ...
        
        // Fact of the day card
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(vertical = 8.dp),
            colors = CardDefaults.cardColors(
                containerColor = MaterialTheme.colorScheme.secondaryContainer
            )
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(16.dp)
            ) {
                Row(
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = "๐Ÿ’ก",
                        style = MaterialTheme.typography.headlineMedium,
                        modifier = Modifier.padding(end = 8.dp)
                    )
                    Text(
                        text = "Did You Know?",
                        style = MaterialTheme.typography.titleMedium,
                        color = MaterialTheme.colorScheme.onSecondaryContainer
                    )
                }
                
                Spacer(modifier = Modifier.height(8.dp))
                
                Text(
                    text = randomFact.text,
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.onSecondaryContainer
                )
            }
        }
    }
}

Example: Rotating Facts

For a fact that changes periodically (like daily):

@Composable
fun DailyFact() {
    // Get fact based on day of year (changes daily)
    val dayOfYear = remember {
        Calendar.getInstance().get(Calendar.DAY_OF_YEAR)
    }
    
    val dailyFact = remember(dayOfYear) {
        val allFacts = TacoFacts.getAll()
        allFacts[dayOfYear % allFacts.size]
    }
    
    Card(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.tertiaryContainer
        )
    ) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(
                text = "๐ŸŒฎ Taco Fact of the Day",
                style = MaterialTheme.typography.titleSmall,
                color = MaterialTheme.colorScheme.onTertiaryContainer
            )
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                text = dailyFact.text,
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onTertiaryContainer
            )
        }
    }
}

Step 3: Add More Facts

Just add new Fact() objects to the allFacts list in TacoFacts.kt:

private val allFacts = listOf(
    // ... existing facts ...
    
    Fact(
        "Your new amazing taco fact here!",
        Category.FUN
    ),
    Fact(
        "Another interesting fact about tacos!",
        Category.HISTORY
    )
)

๐ŸŽจ Where to Display Facts

1. Home Screen Dashboard

// Quick stats + daily fact
Column {
    QuickStatsCard(meals)
    DailyFact()
}

2. Loading Screens

// Show fact while data loads
if (isLoading) {
    LoadingWithFact()
}

@Composable
fun LoadingWithFact() {
    val fact = remember { TacoFacts.getRandom() }
    
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalAlignment = Arrangement.Center
    ) {
        CircularProgressIndicator()
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            text = "Did you know?",
            style = MaterialTheme.typography.titleMedium
        )
        Text(
            text = fact.text,
            style = MaterialTheme.typography.bodyMedium,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(horizontal = 32.dp, vertical = 8.dp)
        )
    }
}

3. Post-Meal Success Screen

// Show fact after logging a meal
SaveSuccessScreen(
    summary = summary,
    fact = TacoFacts.getRandom(),
    // ... other params
)

4. Stats Screen Footer

// End of stats with fun fact
Column {
    // ... all your stats ...
    
    Divider(modifier = Modifier.padding(vertical = 16.dp))
    
    Text(
        text = "๐ŸŽ“ Taco Trivia",
        style = MaterialTheme.typography.titleMedium
    )
    
    TacoFacts.getAll().take(3).forEach { fact ->
        TriviaItem(fact)
    }
}

5. Settings Screen

// "About" section with random fact
Section("About Taco Tracker") {
    Text("Version 1.0")
    Spacer(modifier = Modifier.height(8.dp))
    Text(
        text = TacoFacts.getRandom().text,
        style = MaterialTheme.typography.bodySmall,
        color = MaterialTheme.colorScheme.onSurfaceVariant
    )
}

๐Ÿ’ก Ideas for User Stats

๐Ÿ† Achievement-Style Stats

  • "You've tried 15 different locations"
  • "You've eaten tacos on 42 different days"
  • "You've consumed 1,247 tacos total"

๐Ÿ“Š Comparisons

  • "That's enough tortillas to cover a basketball court!"
  • "You've eaten more tacos this month than last month"
  • "Your taco consumption is 23% above average"

๐ŸŽฏ Patterns & Insights

  • "You eat tacos most often at 12:30 PM"
  • "Your favorite day for tacos is Tuesday"
  • "You prefer corn tortillas 73% of the time"
  • "Your most common ingredient is cilantro"

๐Ÿ“ˆ Trends

  • "Your taco consumption is trending up this month!"
  • "You've had a 7-day taco streak!"
  • "You've eaten tacos 3 weeks in a row"

๐ŸŒฎ Fun Calculations

  • "If you stacked all your tacos, they'd be X feet tall"
  • "You've eaten enough tacos to feed X people"
  • "Your tacos contain enough calories to run X miles"

๐Ÿ’ก Ideas for Trivia Facts

๐Ÿ“œ Historical

  • Origins of different taco styles
  • Evolution of tortilla-making
  • How tacos came to different countries
  • Famous taco moments in history

๐Ÿ‘จโ€๐Ÿณ Culinary

  • Proper taco assembly techniques
  • Regional variations
  • Traditional vs modern ingredients
  • Cooking methods and equipment

๐ŸŒŽ Cultural

  • Taco traditions and celebrations
  • Regional Mexican taco culture
  • Taco etiquette and customs
  • Famous taco destinations

๐Ÿ“Š Statistics

  • Consumption data
  • Popular ingredients
  • Market trends
  • Restaurant statistics

๐ŸŽ‰ Fun & Quirky

  • World records
  • Celebrity taco stories
  • Taco memes and internet culture
  • Unusual taco varieties

๐Ÿงช Testing Your Facts

Check Display

  1. Build and run app
  2. Navigate to where you added facts
  3. Verify formatting looks good
  4. Check that facts rotate correctly

Verify Calculations

// Add temporary logging to test user stats
println("๐Ÿ” Spiciest Month: ${findSpiciestMonth(meals)}")
println("๐Ÿ” Top Location: ${findTopLocation(meals)}")

Test Edge Cases

  • Empty meal list (no data yet)
  • Single meal
  • Unusual data (all same location, etc.)

๐ŸŽจ Styling Tips

Fact Cards

@Composable
fun FactCard(
    emoji: String,
    title: String,
    fact: String,
    backgroundColor: Color = MaterialTheme.colorScheme.secondaryContainer
) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 4.dp),
        colors = CardDefaults.cardColors(containerColor = backgroundColor)
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                text = emoji,
                style = MaterialTheme.typography.headlineMedium,
                modifier = Modifier.padding(end = 12.dp)
            )
            Column {
                Text(
                    text = title,
                    style = MaterialTheme.typography.labelMedium,
                    color = MaterialTheme.colorScheme.onSecondaryContainer
                )
                Text(
                    text = fact,
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.onSecondaryContainer
                )
            }
        }
    }
}

Stat Display Formats

// Large number with label
"${totalTacos.format()} tacos eaten"

// Percentage
"${percentage}% of meals"

// Top item
"#1: $topLocation ($count visits)"

// Date range
"Since ${startDate.format()}"

๐ŸŽ‰ You're Done!

You now have both personalized user stats and general taco trivia in your app!

User Stats: Dynamic, personal, engaging

Trivia Facts: Educational, fun, shareable

Mix and match these throughout your app to create delightful moments of discovery! ๐ŸŒฎโœจ

โšก