Updated Duration Picker during Recipe Editing
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// RecipeKeywordSection.swift
|
||||
// Nextcloud Cookbook iOS Client
|
||||
//
|
||||
// Created by Vincent Meilinger on 03.10.23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - RecipeView Keyword Section
|
||||
|
||||
struct RecipeKeywordSection: View {
|
||||
@ObservedObject var viewModel: RecipeView.ViewModel
|
||||
let columns: [GridItem] = [ GridItem(.flexible(minimum: 50, maximum: 200), spacing: 5) ]
|
||||
|
||||
var body: some View {
|
||||
CollapsibleView(titleColor: .secondary, isCollapsed: !UserSettings.shared.expandKeywordSection) {
|
||||
Group {
|
||||
if !viewModel.observableRecipeDetail.keywords.isEmpty && !viewModel.editMode {
|
||||
RecipeListSection(list: viewModel.observableRecipeDetail.keywords)
|
||||
} else {
|
||||
Text(LocalizedStringKey("No keywords."))
|
||||
}
|
||||
}
|
||||
} title: {
|
||||
HStack {
|
||||
SecondaryLabel(text: LocalizedStringKey("Keywords"))
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - RecipeView Keyword Sheet View
|
||||
|
||||
struct KeywordPickerView: View {
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
@State var title: String
|
||||
@State var searchSuggestions: [RecipeKeyword]
|
||||
@Binding var selection: [String]
|
||||
@State var searchText: String = ""
|
||||
|
||||
var columns: [GridItem] = [GridItem(.adaptive(minimum: 150), spacing: 5)]
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Spacer()
|
||||
Button {
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
} label: {
|
||||
Text("Done")
|
||||
}.padding()
|
||||
}
|
||||
TextField(title, text: $searchText)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
|
||||
ScrollView {
|
||||
LazyVGrid(columns: columns, spacing: 5) {
|
||||
if searchText != "" {
|
||||
KeywordItemView(
|
||||
keyword: searchText,
|
||||
isSelected: selection.contains(searchText)
|
||||
) { keyword in
|
||||
if selection.contains(keyword) {
|
||||
selection.removeAll(where: { s in
|
||||
s == keyword ? true : false
|
||||
})
|
||||
searchSuggestions.removeAll(where: { s in
|
||||
s.name == keyword ? true : false
|
||||
})
|
||||
} else {
|
||||
selection.append(keyword)
|
||||
}
|
||||
}
|
||||
}
|
||||
ForEach(suggestionsFiltered(), id: \.name) { suggestion in
|
||||
KeywordItemView(
|
||||
keyword: suggestion.name,
|
||||
count: suggestion.recipe_count,
|
||||
isSelected: selection.contains(suggestion.name)
|
||||
) { keyword in
|
||||
if selection.contains(keyword) {
|
||||
selection.removeAll(where: { s in
|
||||
s == keyword ? true : false
|
||||
})
|
||||
} else {
|
||||
selection.append(keyword)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Divider().padding()
|
||||
HStack {
|
||||
Text("Selected keywords:")
|
||||
.font(.headline)
|
||||
.padding()
|
||||
Spacer()
|
||||
}
|
||||
LazyVGrid(columns: columns, spacing: 5) {
|
||||
ForEach(selection, id: \.self) { suggestion in
|
||||
KeywordItemView(
|
||||
keyword: suggestion,
|
||||
isSelected: true
|
||||
) { keyword in
|
||||
if selection.contains(keyword) {
|
||||
selection.removeAll(where: { s in
|
||||
s == keyword ? true : false
|
||||
})
|
||||
} else {
|
||||
selection.append(keyword)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.navigationTitle(title)
|
||||
.padding()
|
||||
|
||||
}
|
||||
|
||||
func suggestionsFiltered() -> [RecipeKeyword] {
|
||||
guard searchText != "" else { return searchSuggestions }
|
||||
return searchSuggestions.filter { suggestion in
|
||||
suggestion.name.lowercased().contains(searchText.lowercased())
|
||||
}.sorted(by: { a, b in
|
||||
a.recipe_count > b.recipe_count
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct KeywordItemView: View {
|
||||
var keyword: String
|
||||
var count: Int? = nil
|
||||
var isSelected: Bool
|
||||
var tapped: (String) -> ()
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
if isSelected {
|
||||
Image(systemName: "checkmark.circle.fill")
|
||||
}
|
||||
Text(keyword)
|
||||
.lineLimit(2)
|
||||
Spacer()
|
||||
if let count = count {
|
||||
Text("(\(count))")
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 15)
|
||||
.foregroundStyle(.tertiary)
|
||||
)
|
||||
.onTapGesture {
|
||||
tapped(keyword)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct KeywordPickerView_Previews: PreviewProvider {
|
||||
// Sample keywords for preview
|
||||
static var sampleKeywords = [
|
||||
RecipeKeyword(name: "Vegan", recipe_count: 10),
|
||||
RecipeKeyword(name: "Meat", recipe_count: 5),
|
||||
RecipeKeyword(name: "Gluten-Free", recipe_count: 8),
|
||||
RecipeKeyword(name: "Difficult", recipe_count: 7),
|
||||
RecipeKeyword(name: "Chinese", recipe_count: 3),
|
||||
RecipeKeyword(name: "European", recipe_count: 5),
|
||||
RecipeKeyword(name: "Easy", recipe_count: 1)
|
||||
|
||||
]
|
||||
|
||||
// Sample selection for preview
|
||||
@State static var selection: [String] = ["Vegan"]
|
||||
|
||||
static var previews: some View {
|
||||
KeywordPickerView(title: "Select Keywords", searchSuggestions: sampleKeywords, selection: $selection)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user