Young Devs Bin
๐Ÿ”ง Dev Log

Onboarding Tutorial, History Cap, and Play Store Prep in Tagmind

ยท4 min readยท#android#kotlin#compose#room#ux#tagmind

What Was Built

A full-day session focused on getting Tagmind ready for Play Store submission. The work fell into three buckets: onboarding, data management, and UX polish.


4-Page Onboarding Tutorial

The app now shows a tutorial on first launch. Each page covers one core feature with an actual mini UI mockup drawn in Compose โ€” not static screenshots, but live composables that mirror the real app's look.

Pages:

  1. Welcome โ€” app name, tagline, AutoAwesome icon
  2. Create & Organize Notes โ€” mini Home screen showing folder header with highlighted + button, note rows
  3. Ask AI โ€” mini search UI with provider chips, query bar, Ask button, and answer card
  4. Save AI Answers โ€” answer card with both "Add to note" and "Save as note" buttons highlighted

The tutorial only runs once. After the user taps "Get Started", a DataStore flag is set and the app goes straight to Home on every subsequent launch. Settings โ†’ Data has a "Tutorial" row that navigates back to the tutorial without setting the completion flag again.

Implementation details:

  • OnboardingPrefs (DataStore Preferences) stores a single boolean
  • OnboardingViewModel reads it with SharingStarted.Eagerly โ€” critical to avoid a blank screen flash on first launch after storage clear
  • NavGraph reads isComplete before rendering any route; shows an empty Box until the DataStore emits (avoids null flash)
  • comingFromSettings flag in NavGraph controls whether finishing the tutorial marks it complete or just pops back

Layout bug fixed: The outer Column had verticalArrangement = Arrangement.Center which centered all content. Fixed to Arrangement.Top with padding(top = 64.dp, bottom = 160.dp) and verticalScroll so content fills from the top and can scroll on small screens.

Skip button z-order bug: The fillMaxSize() content column was declared after the Skip button in the Box, so it rendered on top and swallowed all taps. Fixed by moving the Skip button to the end of the Box so it always sits on the top layer.


LLM History Size Management

Before this session, search history had a time-based purge (30 days, runs on SearchViewModel init) but no count cap. A user asking 10 questions a day would accumulate 300 entries in a month.

Added: insert-then-trim pattern

// LlmHistoryRepositoryImpl
override suspend fun saveHistory(...) {
    dao.insert(...)
    dao.trimToLimit(MAX_HISTORY_ENTRIES)  // runs after every insert
}
 
companion object {
    private const val MAX_HISTORY_ENTRIES = 200
}
-- LlmHistoryDao
DELETE FROM llm_history
WHERE id NOT IN (
    SELECT id FROM llm_history ORDER BY timestamp DESC LIMIT :limit
)

The trim runs synchronously after every insert โ€” one extra SQL query, always enforced, no background scheduler needed. Combined with the existing 30-day purge, the table is now doubly bounded.


Clear AI History in Settings

Added a "Clear AI History" row to Settings โ†’ Data (yellow color to distinguish from the red "Clear All Notes"). Tapping shows a confirmation dialog explaining the action is permanent and cannot be undone.

This required threading LlmHistoryRepository into SettingsViewModel โ€” a minimal addition since the repository was already used elsewhere.


Search Bar X Button

When a user taps a history card, the query field fills with the old question. Previously there was no easy way to clear it โ€” you'd have to manually select all and delete. Added a Close icon that appears whenever query.isNotEmpty(), positioned between the text field and the Ask button. Tapping it calls viewModel.onQueryChange("").


Seed Data Replaced

Replaced all developer-themed seed data (Kotlin Flow, MVVM architecture, Atomic Habits) with food/recipe content:

CategoryNotes
RecipesClassic Smash Burger, Caesar Salad, Spaghetti Carbonara, Avocado Toast, Chicken Stir Fry, Banana Pancakes, Chocolate Lava Cake
Meal PrepWeekly meal prep โ€” Sunday, High-protein lunch box
FavoritesPizza places to try, Breakfast spots I love
GroceryWeekly grocery list

12 LLM history entries seeded across Claude (7) and ChatGPT (5) โ€” enough to test provider filtering, scrolling, and the 200-entry trim cap.


Play Store Screenshot Guide

Documented the 6 screens to capture and two methods for recording a promo video (scrcpy for PC mirroring + recording, or Android 11+ built-in screen recorder). Recommended video structure: 30 seconds, onboarding โ†’ note creation โ†’ AI search โ†’ save answer flow.


What's Next

  • Play Store listing copy and feature graphic (1024ร—500px)
  • LLM tag suggestion in the note editor
  • Widget for quick note capture from the home screen