-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProductsList.swift
60 lines (52 loc) · 1.85 KB
/
ProductsList.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import SwiftUI
import Northwind
@available(iOS 16.0, macOS 13, *)
struct ProductsList: View {
/// The database is passed down by the Application struct in the environment.
@Environment(\.database) private var database
/// The products are passed in as a binding, as the detail needs to
/// communicate with it.
@Binding var products : [ Product ]
/// We track the currently selected product
@Binding var selectedProduct : Product.ID?
/// The current search string.
@State private var searchString = ""
#if !os(macOS)
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
#endif
var body: some View {
List(products, selection: $selectedProduct) { product in
ProductCell(product: product)
}
.searchable(text: $searchString)
.task(id: searchString) {
do {
// Here we are using a query builder to filter by column. Alternatively
// one can use an arbitrary Swift closure using `filter`.
let searchString = searchString // strict concurrency
products = try await database.products.fetch(orderBy: \.productName) {
$0.productName.contains(
searchString.trimmingCharacters(in: .whitespacesAndNewlines),
caseInsensitive: true
)
}
// Pre-select the first match if none is selected.
#if os(macOS)
if selectedProduct == nil, let product = products.first {
selectedProduct = product.id
}
#else
if horizontalSizeClass != .compact { // this waits for the tap
if selectedProduct == nil, let product = products.first {
selectedProduct = product.id
}
}
#endif
}
catch { // really, do proper error handling :-)
print("Fetch failed:", error)
}
}
.navigationTitle("Products")
}
}