From 151e69ff28e9f546eba65a291a86ba88ee76d86e Mon Sep 17 00:00:00 2001 From: Hendrik Hogertz Date: Sun, 15 Feb 2026 07:52:18 +0100 Subject: [PATCH] Avoid reusing category thumbnail images in all recipes preview mosaic Track which recipe IDs are used as category thumbnails and prefer different images for the all recipes 2x2 mosaic, falling back to category thumbnails only when not enough other images are available. Co-Authored-By: Claude Sonnet 4.5 --- Nextcloud Cookbook iOS Client/AppState.swift | 2 ++ .../Recipes/AllRecipesCategoryCardView.swift | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Nextcloud Cookbook iOS Client/AppState.swift b/Nextcloud Cookbook iOS Client/AppState.swift index 35b1bfb..2b444b3 100644 --- a/Nextcloud Cookbook iOS Client/AppState.swift +++ b/Nextcloud Cookbook iOS Client/AppState.swift @@ -17,6 +17,7 @@ import UIKit @Published var recipeDetails: [Int: RecipeDetail] = [:] @Published var timers: [String: RecipeTimer] = [:] @Published var categoryImages: [String: UIImage] = [:] + @Published var categoryImageRecipeIds: Set = [] @Published var recentRecipes: [Recipe] = [] @Published var categoryAccessDates: [String: Date] = [:] @Published var manualCategoryOrder: [String] = [] @@ -320,6 +321,7 @@ import UIKit for recipe in recipes { if let image = await getImage(id: recipe.recipe_id, size: .THUMB, fetchMode: .preferLocal) { self.categoryImages[categoryName] = image + self.categoryImageRecipeIds.insert(recipe.recipe_id) return } } diff --git a/Nextcloud Cookbook iOS Client/Views/Recipes/AllRecipesCategoryCardView.swift b/Nextcloud Cookbook iOS Client/Views/Recipes/AllRecipesCategoryCardView.swift index 3192667..54c6f79 100644 --- a/Nextcloud Cookbook iOS Client/Views/Recipes/AllRecipesCategoryCardView.swift +++ b/Nextcloud Cookbook iOS Client/Views/Recipes/AllRecipesCategoryCardView.swift @@ -72,15 +72,29 @@ struct AllRecipesCategoryCardView: View { allRecipes.shuffle() // Filter to recipes that have an image URL, then pick 4 + // Prefer recipes not already used as category thumbnails + let categoryImageIds = appState.categoryImageRecipeIds var candidates: [Recipe] = [] + var fallbackCandidates: [Recipe] = [] var seenIds: Set = [] for recipe in allRecipes { guard let url = recipe.imageUrl, !url.isEmpty else { continue } guard !seenIds.contains(recipe.recipe_id) else { continue } seenIds.insert(recipe.recipe_id) - candidates.append(recipe) + if categoryImageIds.contains(recipe.recipe_id) { + fallbackCandidates.append(recipe) + } else { + candidates.append(recipe) + } if candidates.count >= 4 { break } } + // Fill remaining slots from fallback if needed + if candidates.count < 4 { + for recipe in fallbackCandidates { + candidates.append(recipe) + if candidates.count >= 4 { break } + } + } var images: [UIImage] = [] for recipe in candidates {