// // RecipeCardView.swift // Nextcloud Cookbook iOS Client // // Created by Vincent Meilinger on 15.09.23. // import Foundation import SwiftUI struct RecipeCardView: View { @EnvironmentObject var appState: AppState @State var recipe: Recipe @State var recipeThumb: UIImage? private var keywordsText: String? { guard let keywords = recipe.keywords, !keywords.isEmpty else { return nil } let items = keywords.components(separatedBy: ",").map { $0.trimmingCharacters(in: .whitespaces) }.filter { !$0.isEmpty } guard !items.isEmpty else { return nil } return items.prefix(3).joined(separator: " \u{00B7} ") } var body: some View { VStack(alignment: .leading, spacing: 0) { // Thumbnail if let recipeThumb = recipeThumb { Image(uiImage: recipeThumb) .resizable() .aspectRatio(contentMode: .fill) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 120, maxHeight: 120) .clipped() } else { LinearGradient( gradient: Gradient(colors: [.ncGradientDark, .ncGradientLight]), startPoint: .topLeading, endPoint: .bottomTrailing ) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 120, maxHeight: 120) .overlay { Image(systemName: "fork.knife") .font(.title2) .foregroundStyle(.white.opacity(0.7)) } } // Text content VStack(alignment: .leading, spacing: 3) { Text(recipe.name) .font(.subheadline) .fontWeight(.medium) .lineLimit(2) .multilineTextAlignment(.leading) if let keywordsText { Text(keywordsText) .font(.caption2) .foregroundStyle(.secondary) .lineLimit(1) } } .padding(.horizontal, 8) .padding(.vertical, 6) } .background(Color.backgroundHighlight) .clipShape(RoundedRectangle(cornerRadius: 14)) .shadow(color: .black.opacity(0.08), radius: 4, y: 2) .task { recipeThumb = await appState.getImage( id: recipe.recipe_id, size: .THUMB, fetchMode: UserSettings.shared.storeThumb ? .preferLocal : .onlyServer ) } .refreshable { recipeThumb = await appState.getImage( id: recipe.recipe_id, size: .THUMB, fetchMode: UserSettings.shared.storeThumb ? .preferServer : .onlyServer ) } } }