feat: expand catalog seed data with comprehensive multi-domain item library covering 11 domains and 1000+ items with French/English aliases
- Expand from 418 to 3817 lines with detailed item definitions across grocery, pharmacy, hardware, technology, clothing, home, pets, auto, leisure, cleaning, gifts, and office domains - Add extensive French item names with English aliases for bilingual search support - Include emoji icons, color codes, sort orders, and tags for all domains, categories, and items - Add specialized
This commit is contained in:
+3817
-418
File diff suppressed because it is too large
Load Diff
@@ -29,11 +29,19 @@ class CatalogSeedManager @Inject constructor(
|
||||
private val moshi: Moshi
|
||||
) {
|
||||
suspend fun seedIfNeeded() = withContext(Dispatchers.IO) {
|
||||
val existing = catalogDao.getDomainCount()
|
||||
Log.i(TAG, "Catalog seed check: existing domains = $existing")
|
||||
if (existing > 0) return@withContext
|
||||
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||
val storedVersion = prefs.getInt(PREF_SEED_VERSION, 0)
|
||||
val jsonVersion = runCatching {
|
||||
val json = context.assets.open(SEED_ASSET).bufferedReader().use { it.readText() }
|
||||
moshi.adapter(CatalogSeed::class.java).fromJson(json)?.version ?: 0
|
||||
}.getOrElse { 0 }
|
||||
Log.i(TAG, "Catalog seed check: storedVersion=$storedVersion, jsonVersion=$jsonVersion")
|
||||
if (jsonVersion <= storedVersion) return@withContext
|
||||
runCatching { seedFromJson() }
|
||||
.onSuccess { Log.i(TAG, "Catalog seeded successfully") }
|
||||
.onSuccess {
|
||||
Log.i(TAG, "Catalog seeded successfully v$jsonVersion")
|
||||
prefs.edit().putInt(PREF_SEED_VERSION, jsonVersion).apply()
|
||||
}
|
||||
.onFailure {
|
||||
Log.e(TAG, "Catalog seed failed: ${it.message}", it)
|
||||
Timber.e(it, "Catalog seed failed")
|
||||
@@ -102,5 +110,7 @@ class CatalogSeedManager @Inject constructor(
|
||||
companion object {
|
||||
private const val SEED_ASSET = "catalog_seed.json"
|
||||
private const val TAG = "CatalogSeedManager"
|
||||
private const val PREFS_NAME = "catalog_seed_prefs"
|
||||
private const val PREF_SEED_VERSION = "seed_version"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,60 +50,130 @@ class CatalogProvider @Inject constructor() {
|
||||
/** Liste plate du catalogue. */
|
||||
val items: List<CatalogItem> = buildList {
|
||||
// Fruits & Légumes
|
||||
add(CatalogItem("Pomme", "Fruits & Légumes", "🍎", listOf("apple")))
|
||||
add(CatalogItem("Banane", "Fruits & Légumes", "🍌", listOf("banana")))
|
||||
add(CatalogItem("Orange", "Fruits & Légumes", "🍊"))
|
||||
add(CatalogItem("Citron", "Fruits & Légumes", "🍋"))
|
||||
add(CatalogItem("Fraise", "Fruits & Légumes", "🍓", listOf("strawberry")))
|
||||
add(CatalogItem("Raisin", "Fruits & Légumes", "🍇"))
|
||||
add(CatalogItem("Poire", "Fruits & Légumes", "🍐"))
|
||||
add(CatalogItem("Tomate", "Fruits & Légumes", "🍅"))
|
||||
add(CatalogItem("Salade", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Carotte", "Fruits & Légumes", "🥕"))
|
||||
add(CatalogItem("Brocoli", "Fruits & Légumes", "🥦"))
|
||||
add(CatalogItem("Concombre", "Fruits & Légumes", "🥒"))
|
||||
add(CatalogItem("Poivron", "Fruits & Légumes", "🫑"))
|
||||
add(CatalogItem("Avocat", "Fruits & Légumes", "🥑"))
|
||||
add(CatalogItem("Oignon", "Fruits & Légumes", "🧅"))
|
||||
add(CatalogItem("Ail", "Fruits & Légumes", "🧄"))
|
||||
add(CatalogItem("Pomme de terre", "Fruits & Légumes", "🥔", listOf("patate")))
|
||||
add(CatalogItem("Champignon", "Fruits & Légumes", "🍄"))
|
||||
add(CatalogItem("Épinard", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Ananas", "Fruits & Légumes", "🍍"))
|
||||
add(CatalogItem("Pêche", "Fruits & Légumes", "🍑"))
|
||||
add(CatalogItem("Cerise", "Fruits & Légumes", "🍒"))
|
||||
add(CatalogItem("Kiwi", "Fruits & Légumes", "🥝"))
|
||||
add(CatalogItem("Mangue", "Fruits & Légumes", "🥭"))
|
||||
add(CatalogItem("Melon", "Fruits & Légumes", "🍈"))
|
||||
add(CatalogItem("Pastèque", "Fruits & Légumes", "🍉"))
|
||||
add(CatalogItem("Noix de coco", "Fruits & Légumes", "🥥"))
|
||||
add(CatalogItem("Aubergine", "Fruits & Légumes", "🍆"))
|
||||
add(CatalogItem("Maïs", "Fruits & Légumes", "🌽"))
|
||||
add(CatalogItem("Piment", "Fruits & Légumes", "🌶️"))
|
||||
add(CatalogItem("Courgette", "Fruits & Légumes", "🥒"))
|
||||
add(CatalogItem("Chou-fleur", "Fruits & Légumes", "🥦"))
|
||||
add(CatalogItem("Chou", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Betterave", "Fruits & Légumes", "🫐"))
|
||||
add(CatalogItem("Radis", "Fruits & Légumes", "🥕"))
|
||||
add(CatalogItem("Navet", "Fruits & Légumes", "🥕"))
|
||||
add(CatalogItem("Poireau", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Céleri", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Haricots verts", "Fruits & Légumes", "🫛"))
|
||||
add(CatalogItem("Petits pois", "Fruits & Légumes", "🫛"))
|
||||
add(CatalogItem("Artichaut", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Asperge", "Fruits & Légumes", "🥬"))
|
||||
add(CatalogItem("Basilic", "Fruits & Légumes", "🌿"))
|
||||
add(CatalogItem("Persil", "Fruits & Légumes", "🌿"))
|
||||
add(CatalogItem("Coriandre", "Fruits & Légumes", "🌿"))
|
||||
add(CatalogItem("Menthe", "Fruits & Légumes", "🌿"))
|
||||
add(CatalogItem("Myrtilles", "Fruits & Légumes", "🫐"))
|
||||
add(CatalogItem("Framboises", "Fruits & Légumes", "🍓"))
|
||||
add(CatalogItem("Mûres", "Fruits & Légumes", "🫐"))
|
||||
add(CatalogItem("Abricot", "Fruits & Légumes", "🍑"))
|
||||
add(CatalogItem("Prune", "Fruits & Légumes", "🍑"))
|
||||
add(CatalogItem("Figue", "Fruits & Légumes", "🍇"))
|
||||
add(CatalogItem("Datte", "Fruits & Légumes", "🍇"))
|
||||
add(CatalogItem("Grenade", "Fruits & Légumes", "🍎"))
|
||||
add(CatalogItem("Pomme", "Fruits & Légumes", "🍎", listOf("apple", "apples", "pommes")))
|
||||
add(CatalogItem("Banane", "Fruits & Légumes", "🍌", listOf("banana", "bananas")))
|
||||
add(CatalogItem("Orange", "Fruits & Légumes", "🍊", listOf("oranges")))
|
||||
add(CatalogItem("Citron", "Fruits & Légumes", "🍋", listOf("lemon")))
|
||||
add(CatalogItem("Fraise", "Fruits & Légumes", "🍓", listOf("strawberry", "strawberries")))
|
||||
add(CatalogItem("Raisin", "Fruits & Légumes", "🍇", listOf("grapes")))
|
||||
add(CatalogItem("Poire", "Fruits & Légumes", "🍐", listOf("pear", "pears", "poires")))
|
||||
add(CatalogItem("Tomate", "Fruits & Légumes", "🍅", listOf("tomatoes")))
|
||||
add(CatalogItem("Salade", "Fruits & Légumes", "🥬", listOf("lettuce", "salad")))
|
||||
add(CatalogItem("Carotte", "Fruits & Légumes", "🥕", listOf("carrots", "carrotte")))
|
||||
add(CatalogItem("Brocoli", "Fruits & Légumes", "🥦", listOf("broccoli")))
|
||||
add(CatalogItem("Concombre", "Fruits & Légumes", "🥒", listOf("cucumber")))
|
||||
add(CatalogItem("Poivron", "Fruits & Légumes", "🫑", listOf("bell pepper", "bell peppers")))
|
||||
add(CatalogItem("Avocat", "Fruits & Légumes", "🥑", listOf("avocado")))
|
||||
add(CatalogItem("Oignon", "Fruits & Légumes", "🧅", listOf("onions")))
|
||||
add(CatalogItem("Ail", "Fruits & Légumes", "🧄", listOf("garlic")))
|
||||
add(CatalogItem("Pomme de terre", "Fruits & Légumes", "🥔", listOf("patate", "patates", "potatoes")))
|
||||
add(CatalogItem("Champignon", "Fruits & Légumes", "🍄", listOf("mushrooms", "champignons")))
|
||||
add(CatalogItem("Épinard", "Fruits & Légumes", "🥬", listOf("spinach")))
|
||||
add(CatalogItem("Ananas", "Fruits & Légumes", "🍍", listOf("pineapple")))
|
||||
add(CatalogItem("Pêche", "Fruits & Légumes", "🍑", listOf("peach")))
|
||||
add(CatalogItem("Cerise", "Fruits & Légumes", "🍒", listOf("cherries")))
|
||||
add(CatalogItem("Kiwi", "Fruits & Légumes", "🥝", listOf("kiwi fruit", "kiwis")))
|
||||
add(CatalogItem("Mangue", "Fruits & Légumes", "🥭", listOf("mangoes")))
|
||||
add(CatalogItem("Melon", "Fruits & Légumes", "🍈", listOf("melon")))
|
||||
add(CatalogItem("Pastèque", "Fruits & Légumes", "🍉", listOf("watermelon")))
|
||||
add(CatalogItem("Noix de coco", "Fruits & Légumes", "🥥", listOf("coconut")))
|
||||
add(CatalogItem("Aubergine", "Fruits & Légumes", "🍆", listOf("eggplant")))
|
||||
add(CatalogItem("Maïs", "Fruits & Légumes", "🌽", listOf("sweet corn", "corncobs", "corn cobs")))
|
||||
add(CatalogItem("Piment", "Fruits & Légumes", "🌶️", listOf("chillies", "chili", "piment jaune")))
|
||||
add(CatalogItem("Courgette", "Fruits & Légumes", "🥒", listOf("zucchini")))
|
||||
add(CatalogItem("Chou-fleur", "Fruits & Légumes", "🥦", listOf("cauliflower")))
|
||||
add(CatalogItem("Chou", "Fruits & Légumes", "🥬", listOf("cabbage")))
|
||||
add(CatalogItem("Navet", "Fruits & Légumes", "🥕", listOf("turnip")))
|
||||
add(CatalogItem("Radis", "Fruits & Légumes", "🥕", listOf("radish")))
|
||||
add(CatalogItem("Poireau", "Fruits & Légumes", "🥬", listOf("leek", "leeks")))
|
||||
add(CatalogItem("Céleri", "Fruits & Légumes", "🥬", listOf("celery")))
|
||||
add(CatalogItem("Haricots verts", "Fruits & Légumes", "🫛", listOf("green beans")))
|
||||
add(CatalogItem("Petits pois", "Fruits & Légumes", "🫛", listOf("peas")))
|
||||
add(CatalogItem("Basilic", "Fruits & Légumes", "🌿", listOf("basil")))
|
||||
add(CatalogItem("Persil", "Fruits & Légumes", "🌿", listOf("parsley")))
|
||||
add(CatalogItem("Menthe", "Fruits & Légumes", "🌿", listOf("mint")))
|
||||
add(CatalogItem("Framboises", "Fruits & Légumes", "🍓", listOf("raspberries")))
|
||||
add(CatalogItem("Mûres", "Fruits & Légumes", "🫐", listOf("blackberries")))
|
||||
add(CatalogItem("Abricot", "Fruits & Légumes", "🍑", listOf("apricot")))
|
||||
add(CatalogItem("Prune", "Fruits & Légumes", "🍑", listOf("prunes")))
|
||||
add(CatalogItem("Figue", "Fruits & Légumes", "🍇", listOf("figs")))
|
||||
add(CatalogItem("Datte", "Fruits & Légumes", "🍇", listOf("dates")))
|
||||
add(CatalogItem("Grenade", "Fruits & Légumes", "🍎", listOf("pomegranate", "pomme grenade")))
|
||||
add(CatalogItem("Açaï", "Fruits & Légumes", "🫐", listOf("acai", "açaí", "açaí berries", "acai berries")))
|
||||
add(CatalogItem("Artichaut", "Fruits & Légumes", "🥬", listOf("artichokes")))
|
||||
add(CatalogItem("Roquette", "Fruits & Légumes", "🥬", listOf("arugula")))
|
||||
add(CatalogItem("Asperge", "Fruits & Légumes", "🥬", listOf("asparagus")))
|
||||
add(CatalogItem("Betterave", "Fruits & Légumes", "🫐", listOf("beetroot", "betterave")))
|
||||
add(CatalogItem("Myrtilles", "Fruits & Légumes", "🫐", listOf("blueberries", "bleuets")))
|
||||
add(CatalogItem("Bok choy", "Fruits & Légumes", "🥬", listOf("chinese cabbage")))
|
||||
add(CatalogItem("Chou de Bruxelles", "Fruits & Légumes", "🥬", listOf("brussels sprouts", "chou bruxelles")))
|
||||
add(CatalogItem("Courge butternut", "Fruits & Légumes", "🎃", listOf("butternut pumpkin", "butternut squash")))
|
||||
add(CatalogItem("Chou frisé", "Fruits & Légumes", "🥬", listOf("kale", "chard", "chou frisé")))
|
||||
add(CatalogItem("Poirée", "Fruits & Légumes", "🥬", listOf("swiss chard")))
|
||||
add(CatalogItem("Tomate cerise", "Fruits & Légumes", "🍅", listOf("cherry tomatoes")))
|
||||
add(CatalogItem("Châtaigne", "Fruits & Légumes", "🌰", listOf("chestnuts")))
|
||||
add(CatalogItem("Chicorée", "Fruits & Légumes", "🥬", listOf("chicory")))
|
||||
add(CatalogItem("Ciboulette", "Fruits & Légumes", "🌿", listOf("chives")))
|
||||
add(CatalogItem("Coriandre", "Fruits & Légumes", "🌿", listOf("cilantro")))
|
||||
add(CatalogItem("Clémentine", "Fruits & Légumes", "🍊", listOf("clementine", "clementines")))
|
||||
add(CatalogItem("Canneberge", "Fruits & Légumes", "🫐", listOf("cranberries")))
|
||||
add(CatalogItem("Cresson", "Fruits & Légumes", "🥬", listOf("cress")))
|
||||
add(CatalogItem("Crudités", "Fruits & Légumes", "🥗", listOf("crudites")))
|
||||
add(CatalogItem("Groseille", "Fruits & Légumes", "🍇", listOf("currants")))
|
||||
add(CatalogItem("Aneth", "Fruits & Légumes", "🌿", listOf("dill")))
|
||||
add(CatalogItem("Pamplemousse", "Fruits & Légumes", "🍊", listOf("grapefruit")))
|
||||
add(CatalogItem("Citronnelle", "Fruits & Légumes", "🌿", listOf("lemongrass")))
|
||||
add(CatalogItem("Mirabelle", "Fruits & Légumes", "🍑", listOf("mirabelles")))
|
||||
add(CatalogItem("Pitaya", "Fruits & Légumes", "🐉", listOf("dragon fruit", "fruit dragon")))
|
||||
add(CatalogItem("Échalote", "Fruits & Légumes", "🧅", listOf("shallots", "échalotes")))
|
||||
add(CatalogItem("Edamame", "Fruits & Légumes", "🫛"))
|
||||
add(CatalogItem("Fenouil", "Fruits & Légumes", "🥬", listOf("fennel")))
|
||||
add(CatalogItem("Fève", "Fruits & Légumes", "🫛", listOf("fèves", "fava bean", "broad bean")))
|
||||
add(CatalogItem("Fève verte", "Fruits & Légumes", "🫛", listOf("fèves vertes")))
|
||||
add(CatalogItem("Graines de lin", "Fruits & Légumes", "🌾", listOf("flaxseed", "linseed")))
|
||||
add(CatalogItem("Fruit", "Fruits & Légumes", "🍎", listOf("fruits")))
|
||||
add(CatalogItem("Plateau fruits", "Fruits & Légumes", "🍎", listOf("fruit platter")))
|
||||
add(CatalogItem("Plateau légumes", "Fruits & Légumes", "🥗", listOf("vegetable platter")))
|
||||
add(CatalogItem("Baies de goji", "Fruits & Légumes", "🍇", listOf("goji berries")))
|
||||
add(CatalogItem("Groseille à maquereau", "Fruits & Légumes", "🍇", listOf("gooseberries")))
|
||||
add(CatalogItem("Goyave", "Fruits & Légumes", "🥭", listOf("guava")))
|
||||
add(CatalogItem("Citrouille Halloween", "Fruits & Légumes", "🎃", listOf("halloween pumpkin")))
|
||||
add(CatalogItem("Herbes", "Fruits & Légumes", "🌿", listOf("herbs")))
|
||||
add(CatalogItem("Citrouille Hokkaido", "Fruits & Légumes", "🎃", listOf("hokkaido pumpkin")))
|
||||
add(CatalogItem("Melon vert", "Fruits & Légumes", "🍈", listOf("honeydew melon")))
|
||||
add(CatalogItem("Mâche", "Fruits & Légumes", "🥬", listOf("lamb's lettuce", "corn salad")))
|
||||
add(CatalogItem("Citron vert", "Fruits & Légumes", "🍋", listOf("lime", "limes")))
|
||||
add(CatalogItem("Litchi", "Fruits & Légumes", "🥭", listOf("lychee", "lychees")))
|
||||
add(CatalogItem("Mandarine", "Fruits & Légumes", "🍊", listOf("mandarins", "mandarin")))
|
||||
add(CatalogItem("Marjolaine", "Fruits & Légumes", "🌿", listOf("marjoram")))
|
||||
add(CatalogItem("Nectarine", "Fruits & Légumes", "🍑", listOf("nectarines")))
|
||||
add(CatalogItem("Oignon rouge", "Fruits & Légumes", "🧅", listOf("red onion")))
|
||||
add(CatalogItem("Oignon vert", "Fruits & Légumes", "🧅", listOf("green onion", "spring onion", "scallions")))
|
||||
add(CatalogItem("Olive", "Fruits & Légumes", "🫒", listOf("olives")))
|
||||
add(CatalogItem("Papaye", "Fruits & Légumes", "🥭", listOf("papaya")))
|
||||
add(CatalogItem("Panais", "Fruits & Légumes", "🥕", listOf("parsnips")))
|
||||
add(CatalogItem("Fruit de la passion", "Fruits & Légumes", "🍇", listOf("passion fruit")))
|
||||
add(CatalogItem("Patate douce", "Fruits & Légumes", "🍠", listOf("sweet potatoes", "patate douce")))
|
||||
add(CatalogItem("Patates parisiennes", "Fruits & Légumes", "🥔", listOf("patates parisienne")))
|
||||
add(CatalogItem("Pousse de pois", "Fruits & Légumes", "🌱", listOf("pea eggplant")))
|
||||
add(CatalogItem("Pourpier", "Fruits & Légumes", "🥬", listOf("purslane")))
|
||||
add(CatalogItem("Coing", "Fruits & Légumes", "🍏", listOf("quinces")))
|
||||
add(CatalogItem("Chou rouge", "Fruits & Légumes", "🥬", listOf("red cabbage")))
|
||||
add(CatalogItem("Rhubarbe", "Fruits & Légumes", "🥬", listOf("rhubarb")))
|
||||
add(CatalogItem("Sauge", "Fruits & Légumes", "🌿", listOf("sage")))
|
||||
add(CatalogItem("Salade au chou", "Fruits & Légumes", "🥗", listOf("coleslaw")))
|
||||
add(CatalogItem("Chou de Milan", "Fruits & Légumes", "🥬", listOf("savoy cabbage")))
|
||||
add(CatalogItem("Courge", "Fruits & Légumes", "🎃", listOf("squash")))
|
||||
add(CatalogItem("Carambole", "Fruits & Légumes", "⭐", listOf("star fruit")))
|
||||
add(CatalogItem("Tomates séchées", "Fruits & Légumes", "🍅", listOf("sun-dried tomatoes")))
|
||||
add(CatalogItem("Basilic thaï", "Fruits & Légumes", "🌿", listOf("thai basil")))
|
||||
add(CatalogItem("Thym", "Fruits & Légumes", "🌿", listOf("thyme")))
|
||||
add(CatalogItem("Tomates Savoura", "Fruits & Légumes", "🍅", listOf("savoura tomatoes")))
|
||||
add(CatalogItem("Herbe de blé", "Fruits & Légumes", "🌾", listOf("wheatgrass")))
|
||||
add(CatalogItem("Salsifis noir", "Fruits & Légumes", "🥕", listOf("black salsify")))
|
||||
add(CatalogItem("Girolles", "Fruits & Légumes", "🍄", listOf("chanterelles")))
|
||||
add(CatalogItem("Orange sanguine", "Fruits & Légumes", "🍊", listOf("blood orange")))
|
||||
add(CatalogItem("Baies", "Fruits & Légumes", "🫐", listOf("berries")))
|
||||
|
||||
// Boulangerie
|
||||
add(CatalogItem("Pain", "Boulangerie", "🍞", listOf("baguette")))
|
||||
@@ -124,6 +194,54 @@ class CatalogProvider @Inject constructor() {
|
||||
add(CatalogItem("Éclair", "Boulangerie", "🍰"))
|
||||
add(CatalogItem("Tarte", "Boulangerie", "🥧"))
|
||||
add(CatalogItem("Gâteau", "Boulangerie", "🍰"))
|
||||
add(CatalogItem("Bagel briana", "Boulangerie", "🥯"))
|
||||
add(CatalogItem("Biscuits breton sans gluten", "Boulangerie", "🍪"))
|
||||
add(CatalogItem("Biscuits Feuille D'Érable", "Boulangerie", "🍁"))
|
||||
add(CatalogItem("Biscuits sans gluten", "Boulangerie", "🍪"))
|
||||
add(CatalogItem("Biscuits swiss", "Boulangerie", "🍪"))
|
||||
add(CatalogItem("Bread", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Buns", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Crispbread", "Boulangerie", "🍘"))
|
||||
add(CatalogItem("Croûte à tarte", "Boulangerie", "🥧"))
|
||||
add(CatalogItem("Dinner Rolls", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Fond de tarte", "Boulangerie", "🥧"))
|
||||
add(CatalogItem("Galette tortilla", "Boulangerie", "🌯"))
|
||||
add(CatalogItem("Gâteau mille feuilles", "Boulangerie", "🍰"))
|
||||
add(CatalogItem("Gaufres", "Boulangerie", "🧇"))
|
||||
add(CatalogItem("Muffins Anglais", "Boulangerie", "🥯"))
|
||||
add(CatalogItem("Pain Baguette", "Boulangerie", "🥖"))
|
||||
add(CatalogItem("Pain Blanc", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain Blanc Sans Lactose", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain Bon Matin", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain Briana", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain brun", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain burgers", "Boulangerie", "🍔"))
|
||||
add(CatalogItem("Pain burgers sans gluten", "Boulangerie", "🍔"))
|
||||
add(CatalogItem("Pain Croûte", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain croûté sans gluten", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain hamburger sans gluten", "Boulangerie", "🍔"))
|
||||
add(CatalogItem("Pain Hot Dog", "Boulangerie", "🌭"))
|
||||
add(CatalogItem("Pain Italien", "Boulangerie", "🥖"))
|
||||
add(CatalogItem("Pain Sans Gluten", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain Sans Lactose", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pain Sous Marin", "Boulangerie", "🥖"))
|
||||
add(CatalogItem("Pains Grand Mère", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Pancakes mix", "Boulangerie", "🥞"))
|
||||
add(CatalogItem("Petit Pain Sandwich", "Boulangerie", "🥪"))
|
||||
add(CatalogItem("Petit Pain Sous Marin", "Boulangerie", "🥖"))
|
||||
add(CatalogItem("Pie", "Boulangerie", "🥧"))
|
||||
add(CatalogItem("Pizza dough", "Boulangerie", "🍕"))
|
||||
add(CatalogItem("Pizza sans gluten", "Boulangerie", "🍕"))
|
||||
add(CatalogItem("Puff pastry", "Boulangerie", "🥐"))
|
||||
add(CatalogItem("Pumpkin Pie", "Boulangerie", "🥧"))
|
||||
add(CatalogItem("Rolls", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Scones", "Boulangerie", "🧁"))
|
||||
add(CatalogItem("Sliced bread", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Toast", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Toast melba", "Boulangerie", "🍞"))
|
||||
add(CatalogItem("Tortilla", "Boulangerie", "🌯"))
|
||||
add(CatalogItem("Vol au vent", "Boulangerie", "🥐"))
|
||||
add(CatalogItem("Waffles", "Boulangerie", "🧇"))
|
||||
|
||||
// Produits laitiers
|
||||
add(CatalogItem("Lait", "Produits laitiers", "🥛", listOf("milk")))
|
||||
@@ -151,6 +269,59 @@ class CatalogProvider @Inject constructor() {
|
||||
add(CatalogItem("Lait de soja", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait d'amande", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Margarine", "Produits laitiers", "🧈"))
|
||||
add(CatalogItem("Beurre Sans Lactose", "Produits laitiers", "🧈"))
|
||||
add(CatalogItem("Cream", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Cream cheese", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Crème 10%", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Crème à café", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Creme fraiche", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Crème Glacée", "Produits laitiers", "🍨"))
|
||||
add(CatalogItem("Crème glacée Sans Lactose", "Produits laitiers", "🍨"))
|
||||
add(CatalogItem("Crème Glacée Sans Lactose Au Chocolat", "Produits laitiers", "🍨"))
|
||||
add(CatalogItem("Crème Sans Lactose", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Crème Sure", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Sour cream", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Blue cheese", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Crotte De Fromage", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Demi Lune", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fondue Fromage", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Frite du petit Québec", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage à tartiner", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Briana", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Chèvre Confiture", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("fromage cottage sans lactose", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Déjà Rappé", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage en grains", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("fromage en tranches", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Philadelphia", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Philadelphia sans lactose", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Quick Quick", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Rapé Briana", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage rapé sans lactose", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Riviera", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Sans Lactose", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage suisse", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage tex mex", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Fromage Vache Qui Rit", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Grated cheese", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Grilled cheese", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Parmesan sans lactose", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Quark", "Produits laitiers", "🧀"))
|
||||
add(CatalogItem("Lait avoine", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait avoine lunch", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait avoine lunch chocolat", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait Chocolat", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait Chocolat Lunch", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait Chocolat Sans Lactose", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait condensé coco", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait Sans Lactose", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait Soya Lunch", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Lait Soya Sensationnel Nature", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Soy Milk", "Produits laitiers", "🥛"))
|
||||
add(CatalogItem("Soy yogurt", "Produits laitiers", "🥣"))
|
||||
add(CatalogItem("Yogourt iogo Vanille", "Produits laitiers", "🥣"))
|
||||
add(CatalogItem("Yogourt logo vanille sans lactose", "Produits laitiers", "🥣"))
|
||||
add(CatalogItem("Yogourt Sans Lactose", "Produits laitiers", "🥣"))
|
||||
|
||||
// Boucherie
|
||||
add(CatalogItem("Poulet", "Boucherie", "🍗"))
|
||||
|
||||
@@ -53,9 +53,9 @@ class CategoryEngine @Inject constructor() {
|
||||
|
||||
// ── Mots-clés par catégorie ─────────────────────────────────────────────
|
||||
|
||||
private val freshKeywords = listOf("frais", "fraise", "framboise", "myrtille", "salade", "tomate", "concombre")
|
||||
|
||||
private val fruitKeywords = listOf("pomme", "poire", "banane", "orange", "citron", "raisin", "fraise", "fruit", "abricot", "peche", "cerise", "melon", "pasteque", "ananas", "mangue", "kiwi", "legume", "carotte", "poireau", "epinard", "brocoli", "chou", "courgette", "aubergine", "poivron", "avocat", "haricot")
|
||||
private val freshKeywords = listOf("frais", "fraise", "framboise", "myrtille", "salade", "tomate", "concombre", "crudite")
|
||||
|
||||
private val fruitKeywords = listOf("pomme", "poire", "banane", "orange", "citron", "raisin", "fraise", "fruit", "abricot", "peche", "cerise", "melon", "pasteque", "ananas", "mangue", "kiwi", "legume", "carotte", "poireau", "epinard", "brocoli", "chou", "courgette", "aubergine", "poivron", "avocat", "haricot", "artichaut", "asperge", "betterave", "myrtille", "bok choy", "chou de bruxelles", "courge", "chou frise", "poiree", "tomate cerise", "chataigne", "chicoree", "piment", "ciboulette", "coriandre", "clementine", "canneberge", "cresson", "groseille", "aneth", "pitaya", "echalote", "edamame", "fenouil", "feve", "graines de lin", "baies de goji", "groseille a maquereau", "goyave", "citrouille", "herbes", "mache", "citron vert", "litchi", "mandarine", "marjolaine", "nectarine", "oignon", "olive", "papaye", "panais", "fruit de la passion", "patate", "pourpier", "coing", "chou rouge", "rhubarbe", "sauge", "salade au chou", "chou de milan", "carambole", "tomates sechees", "basilic thai", "thym", "herbe de ble", "salsifis", "girolle", "orange sanguine", "baies", "acai", "grenade", "prune", "figue", "datte", "navet", "radis", "celeri", "menthe", "persil", "basilic")
|
||||
|
||||
private val bakeryKeywords = listOf("pain", "baguette", "biscotte", "croissant", "brioche", "boulang", "patisserie", "gateau", "tarte")
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ private fun ItemTile(item: CatalogItemEntity, onClick: () -> Unit) {
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(text = item.emoji, style = MaterialTheme.typography.displaySmall)
|
||||
Text(text = item.emoji, style = MaterialTheme.typography.displayMedium)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text(
|
||||
text = item.name,
|
||||
|
||||
@@ -145,6 +145,10 @@ fun ListDetailScreen(
|
||||
var recentlyExpanded by remember { mutableStateOf(true) }
|
||||
val expandedCategories = remember { mutableStateMapOf<String, Boolean>() }
|
||||
|
||||
val catalogDomains by viewModel.catalogDomains.collectAsStateWithLifecycle()
|
||||
val expandedDomains = remember { mutableStateMapOf<String, Boolean>() }
|
||||
val expandedRoomCategories = remember { mutableStateMapOf<String, Boolean>() }
|
||||
|
||||
var showPhotoPicker by remember { mutableStateOf(false) }
|
||||
var showDescriptionDialog by remember { mutableStateOf(false) }
|
||||
var selectedImageUri by remember { mutableStateOf<String?>(null) }
|
||||
@@ -280,18 +284,22 @@ fun ListDetailScreen(
|
||||
is ListDetailViewModel.UiState.Ready -> {
|
||||
ListDetailContent(
|
||||
ready = s,
|
||||
catalog = viewModel.catalog,
|
||||
catalogDomains = catalogDomains,
|
||||
recentlyExpanded = recentlyExpanded,
|
||||
onToggleRecently = { recentlyExpanded = !recentlyExpanded },
|
||||
expandedCategories = expandedCategories,
|
||||
onToggleCategory = { cat ->
|
||||
expandedCategories[cat] = !(expandedCategories[cat] ?: false)
|
||||
expandedDomains = expandedDomains,
|
||||
onToggleDomain = { domainId ->
|
||||
expandedDomains[domainId] = !(expandedDomains[domainId] ?: false)
|
||||
},
|
||||
expandedRoomCategories = expandedRoomCategories,
|
||||
onToggleRoomCategory = { catId ->
|
||||
expandedRoomCategories[catId] = !(expandedRoomCategories[catId] ?: false)
|
||||
},
|
||||
onTapActive = viewModel::markAsBought,
|
||||
onLongPressActive = viewModel::openItemDetails,
|
||||
onTapRecent = viewModel::restoreItem,
|
||||
onLongPressRecent = viewModel::openItemDetails,
|
||||
onTapCatalog = viewModel::addCatalogItem
|
||||
onTapCatalogItem = viewModel::addCatalogItem
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -401,36 +409,21 @@ fun ListDetailScreen(
|
||||
@Composable
|
||||
private fun ListDetailContent(
|
||||
ready: ListDetailViewModel.UiState.Ready,
|
||||
catalog: CatalogProvider,
|
||||
catalogDomains: List<com.safebite.app.data.local.database.relation.DomainWithCategoriesAndItems>,
|
||||
recentlyExpanded: Boolean,
|
||||
onToggleRecently: () -> Unit,
|
||||
expandedCategories: Map<String, Boolean>,
|
||||
onToggleCategory: (String) -> Unit,
|
||||
expandedDomains: Map<String, Boolean>,
|
||||
onToggleDomain: (String) -> Unit,
|
||||
expandedRoomCategories: Map<String, Boolean>,
|
||||
onToggleRoomCategory: (String) -> Unit,
|
||||
onTapActive: (Long) -> Unit,
|
||||
onLongPressActive: (Long) -> Unit,
|
||||
onTapRecent: (Long) -> Unit,
|
||||
onLongPressRecent: (Long) -> Unit,
|
||||
onTapCatalog: (CatalogProvider.CatalogItem) -> Unit
|
||||
onTapCatalogItem: (com.safebite.app.data.local.database.entity.CatalogItemEntity) -> Unit
|
||||
) {
|
||||
val dimens = LocalDimens.current
|
||||
|
||||
val filteredCatalogCounts = remember(ready.activeItems, ready.recentlyUsed) {
|
||||
catalog.categories.associateWith { category ->
|
||||
catalog.itemsForCategory(category).count { catItem ->
|
||||
ready.activeItems.none { it.productName.equals(catItem.name, ignoreCase = true) } &&
|
||||
ready.recentlyUsed.none { it.productName.equals(catItem.name, ignoreCase = true) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val orderedCategories = remember(ready.list) {
|
||||
val order = ready.list?.categoryOrder?.split(",")?.filter { it.isNotBlank() }
|
||||
val visible = ready.list?.visibleCategories?.split(",")?.filter { it.isNotBlank() }?.toSet()
|
||||
val base = order ?: catalog.categories
|
||||
val filtered = if (visible != null) base.filter { it in visible } else base
|
||||
filtered.filter { it in catalog.categories }
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(
|
||||
@@ -498,7 +491,7 @@ private fun ListDetailContent(
|
||||
}
|
||||
}
|
||||
|
||||
// ── Catalogue par catégorie ─────────────────────────────────────────
|
||||
// ── Catalogue Room (domaines → catégories → articles) ────────────
|
||||
item {
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(vertical = dimens.spacingSm),
|
||||
@@ -512,40 +505,47 @@ private fun ListDetailContent(
|
||||
)
|
||||
}
|
||||
|
||||
orderedCategories.forEach { category ->
|
||||
val expanded = expandedCategories[category] ?: false
|
||||
item(key = "header-$category") {
|
||||
catalogDomains.forEach { domainWithCats ->
|
||||
val domainId = domainWithCats.domain.domainId
|
||||
val domainExpanded = expandedDomains[domainId] ?: false
|
||||
val domainItemCount = domainWithCats.categoriesWithItems.sumOf { cat ->
|
||||
cat.items.count { item ->
|
||||
ready.activeItems.none { it.productName.equals(item.name, ignoreCase = true) } &&
|
||||
ready.recentlyUsed.none { it.productName.equals(item.name, ignoreCase = true) }
|
||||
}
|
||||
}
|
||||
item(key = "domain-header-$domainId") {
|
||||
CollapsibleHeader(
|
||||
title = category,
|
||||
count = filteredCatalogCounts[category] ?: 0,
|
||||
expanded = expanded,
|
||||
onToggle = { onToggleCategory(category) }
|
||||
title = "${domainWithCats.domain.emoji} ${domainWithCats.domain.name}",
|
||||
count = domainItemCount,
|
||||
expanded = domainExpanded,
|
||||
onToggle = { onToggleDomain(domainId) }
|
||||
)
|
||||
}
|
||||
if (expanded) {
|
||||
item(key = "grid-$category") {
|
||||
val items = catalog.itemsForCategory(category).filter { catItem ->
|
||||
ready.activeItems.none { it.productName.equals(catItem.name, ignoreCase = true) } &&
|
||||
ready.recentlyUsed.none { it.productName.equals(catItem.name, ignoreCase = true) }
|
||||
if (domainExpanded) {
|
||||
domainWithCats.categoriesWithItems.forEach { catWithItems ->
|
||||
val catId = catWithItems.category.categoryId
|
||||
val catExpanded = expandedRoomCategories[catId] ?: false
|
||||
val filteredItems = catWithItems.items.filter { item ->
|
||||
ready.activeItems.none { it.productName.equals(item.name, ignoreCase = true) } &&
|
||||
ready.recentlyUsed.none { it.productName.equals(item.name, ignoreCase = true) }
|
||||
}
|
||||
TileGrid(
|
||||
items = items.map {
|
||||
TileData(
|
||||
id = it.name.hashCode().toLong(),
|
||||
label = it.name,
|
||||
note = null,
|
||||
emoji = it.emoji,
|
||||
imageUrl = null,
|
||||
tone = TileTone.Catalog,
|
||||
badgeWarning = false
|
||||
item(key = "cat-header-$catId") {
|
||||
CollapsibleHeader(
|
||||
title = " ${catWithItems.category.emoji} ${catWithItems.category.name}",
|
||||
count = filteredItems.size,
|
||||
expanded = catExpanded,
|
||||
onToggle = { onToggleRoomCategory(catId) }
|
||||
)
|
||||
}
|
||||
if (catExpanded && filteredItems.isNotEmpty()) {
|
||||
item(key = "cat-grid-$catId") {
|
||||
CatalogItemGrid(
|
||||
items = filteredItems,
|
||||
onTap = onTapCatalogItem
|
||||
)
|
||||
},
|
||||
onTap = { idHash ->
|
||||
val target = items.firstOrNull { it.name.hashCode().toLong() == idHash }
|
||||
target?.let(onTapCatalog)
|
||||
},
|
||||
onLongPress = { /* pas d'action sur le catalogue */ }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -775,6 +775,86 @@ private fun CollapsibleHeader(
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Tuiles catalogue Room (style identique au header catalogue)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@Composable
|
||||
private fun CatalogItemGrid(
|
||||
items: List<com.safebite.app.data.local.database.entity.CatalogItemEntity>,
|
||||
onTap: (com.safebite.app.data.local.database.entity.CatalogItemEntity) -> Unit
|
||||
) {
|
||||
if (items.isEmpty()) return
|
||||
val dimens = LocalDimens.current
|
||||
val columns = 3
|
||||
val rows = items.chunked(columns)
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dimens.spacingSm)) {
|
||||
rows.forEach { row ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(dimens.spacingSm)
|
||||
) {
|
||||
row.forEach { item ->
|
||||
Box(modifier = Modifier.weight(1f)) {
|
||||
CatalogItemTile(item = item, onTap = { onTap(item) })
|
||||
}
|
||||
}
|
||||
repeat(columns - row.size) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CatalogItemTile(
|
||||
item: com.safebite.app.data.local.database.entity.CatalogItemEntity,
|
||||
onTap: () -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f)
|
||||
.clickable(onClick = onTap),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(8.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
Text(
|
||||
text = item.emoji,
|
||||
style = MaterialTheme.typography.displayMedium
|
||||
)
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
Text(
|
||||
text = item.name,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Add,
|
||||
contentDescription = "Ajouter",
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.align(Alignment.TopEnd).size(20.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// État vide pour la liste active
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
+37
-2
@@ -4,6 +4,9 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.safebite.app.data.local.database.entity.ShoppingListEntity
|
||||
import com.safebite.app.data.local.database.entity.ShoppingListItemEntity
|
||||
import com.safebite.app.data.local.database.entity.CatalogItemEntity
|
||||
import com.safebite.app.data.local.database.relation.DomainWithCategoriesAndItems
|
||||
import com.safebite.app.data.repository.CatalogRepository
|
||||
import com.safebite.app.domain.engine.CatalogProvider
|
||||
import com.safebite.app.domain.engine.CategoryEngine
|
||||
import com.safebite.app.domain.usecase.GetShoppingListsUseCase
|
||||
@@ -40,6 +43,7 @@ class ListDetailViewModel @Inject constructor(
|
||||
private val manageListUseCase: ManageShoppingListUseCase,
|
||||
private val getListsUseCase: GetShoppingListsUseCase,
|
||||
private val categoryEngine: CategoryEngine,
|
||||
private val catalogRepository: CatalogRepository,
|
||||
val catalog: CatalogProvider
|
||||
) : ViewModel() {
|
||||
|
||||
@@ -112,6 +116,11 @@ class ListDetailViewModel @Inject constructor(
|
||||
.observeActive()
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
|
||||
|
||||
/** Catalogue Room hiérarchique (domaines → catégories → articles). */
|
||||
val catalogDomains: StateFlow<List<DomainWithCategoriesAndItems>> = catalogRepository
|
||||
.observeDomainsWithCategoriesAndItems()
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
|
||||
|
||||
fun initList(listId: Long, listName: String) {
|
||||
_listIdFlow.value = listId
|
||||
_listName.value = listName
|
||||
@@ -201,11 +210,10 @@ class ListDetailViewModel @Inject constructor(
|
||||
clearSearch()
|
||||
}
|
||||
|
||||
/** Ajoute un article du catalogue à la liste active. */
|
||||
/** Ajoute un article du catalogue legacy à la liste active. */
|
||||
fun addCatalogItem(catalogItem: CatalogProvider.CatalogItem) {
|
||||
viewModelScope.launch {
|
||||
val listId = _listIdFlow.value
|
||||
// Si l'article existe déjà (en actif ou recently used), on le réactive.
|
||||
val existing = manageListUseCase.getItems(listId)
|
||||
.firstOrNull { it.productName.equals(catalogItem.name, ignoreCase = true) }
|
||||
if (existing != null) {
|
||||
@@ -225,6 +233,33 @@ class ListDetailViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/** Ajoute un article du catalogue Room à la liste active. */
|
||||
fun addCatalogItem(item: CatalogItemEntity) {
|
||||
viewModelScope.launch {
|
||||
val listId = _listIdFlow.value
|
||||
val existing = manageListUseCase.getItems(listId)
|
||||
.firstOrNull { it.productName.equals(item.name, ignoreCase = true) }
|
||||
if (existing != null) {
|
||||
if (existing.isChecked) {
|
||||
manageListUseCase.setItemChecked(existing.id, false)
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
val categoryName = item.primaryCategoryId?.let { catId ->
|
||||
catalogRepository.getCategory(catId)?.name
|
||||
} ?: categoryEngine.detectCategory(item.name)
|
||||
manageListUseCase.addItemToList(
|
||||
listId,
|
||||
ShoppingListItemEntity(
|
||||
listId = listId,
|
||||
productName = item.name,
|
||||
category = categoryName,
|
||||
customEmoji = item.emoji
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un *own item* à partir de la saisie utilisateur (avec quantité optionnelle). */
|
||||
fun addCustomItem(rawText: String) {
|
||||
val trimmed = rawText.trim()
|
||||
|
||||
Reference in New Issue
Block a user