Skip to content

Commit 1c6a603

Browse files
committed
+ New empty states for searching
1 parent 8f21fc5 commit 1c6a603

File tree

10 files changed

+617
-28
lines changed

10 files changed

+617
-28
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
},
6+
"symbols" : [
7+
{
8+
"filename" : "custom.apple.terminal.badge.magnifyingglass.svg",
9+
"idiom" : "universal"
10+
}
11+
]
12+
}

Cork/Assets.xcassets/custom.apple.terminal.badge.magnifyingglass.symbolset/custom.apple.terminal.badge.magnifyingglass.svg

Lines changed: 119 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
},
6+
"symbols" : [
7+
{
8+
"filename" : "custom.macwindow.badge.magnifyingglass.svg",
9+
"idiom" : "universal"
10+
}
11+
]
12+
}

Cork/Assets.xcassets/custom.macwindow.badge.magnifyingglass.symbolset/custom.macwindow.badge.magnifyingglass.svg

Lines changed: 131 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
},
6+
"symbols" : [
7+
{
8+
"filename" : "custom.shippingbox.badge.magnifyingglass.svg",
9+
"idiom" : "universal"
10+
}
11+
]
12+
}

Cork/Assets.xcassets/custom.shippingbox.badge.magnifyingglass.symbolset/custom.shippingbox.badge.magnifyingglass.svg

Lines changed: 113 additions & 0 deletions
Loading

Cork/Enums/Packages/Package Types.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import AppIntents
99
import Charts
1010
import CorkShared
1111
import Foundation
12+
import SwiftUI
1213

1314
enum PackageType: String, CustomStringConvertible, Plottable, AppEntity, Codable {
1415
case formula
@@ -23,6 +24,17 @@ enum PackageType: String, CustomStringConvertible, Plottable, AppEntity, Codable
2324
return String(localized: "package-details.type.cask")
2425
}
2526
}
27+
28+
/// Localization keys for description of the package type
29+
var localizableDescription: LocalizedStringKey
30+
{
31+
switch self {
32+
case .formula:
33+
return "package-details.type.formula"
34+
case .cask:
35+
return "package-details.type.cask"
36+
}
37+
}
2638

2739
/// Parent folder for this package type
2840
var parentFolder: URL {

Cork/Localizable.xcstrings

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7138,6 +7138,16 @@
71387138
}
71397139
}
71407140
},
7141+
"action.search-again" : {
7142+
"localizations" : {
7143+
"en" : {
7144+
"stringUnit" : {
7145+
"state" : "translated",
7146+
"value" : "Search Again"
7147+
}
7148+
}
7149+
}
7150+
},
71417151
"action.show" : {
71427152
"localizations" : {
71437153
"cs" : {
@@ -11340,6 +11350,16 @@
1134011350
}
1134111351
}
1134211352
},
11353+
"add-package.search.results.casks.none-found" : {
11354+
"localizations" : {
11355+
"en" : {
11356+
"stringUnit" : {
11357+
"state" : "translated",
11358+
"value" : "No Casks found"
11359+
}
11360+
}
11361+
}
11362+
},
1134311363
"add-package.search.results.formulae" : {
1134411364
"localizations" : {
1134511365
"cs" : {
@@ -11428,6 +11448,26 @@
1142811448
}
1142911449
}
1143011450
},
11451+
"add-package.search.results.formulae.none-found" : {
11452+
"localizations" : {
11453+
"en" : {
11454+
"stringUnit" : {
11455+
"state" : "translated",
11456+
"value" : "No Formulae found"
11457+
}
11458+
}
11459+
}
11460+
},
11461+
"add-package.search.results.packages.none-found" : {
11462+
"localizations" : {
11463+
"en" : {
11464+
"stringUnit" : {
11465+
"state" : "translated",
11466+
"value" : "No results found"
11467+
}
11468+
}
11469+
}
11470+
},
1143111471
"add-package.searching-%@" : {
1143211472
"localizations" : {
1143311473
"cs" : {
@@ -13801,6 +13841,16 @@
1380113841
}
1380213842
}
1380313843
},
13844+
"add.package.search.results.packages.none-found.description" : {
13845+
"localizations" : {
13846+
"en" : {
13847+
"stringUnit" : {
13848+
"state" : "translated",
13849+
"value" : "Try searching for another package"
13850+
}
13851+
}
13852+
}
13853+
},
1380413854
"add.package.uninstall.requires-sudo-password.terminal-instructions-%@" : {
1380513855
"localizations" : {
1380613856
"cs" : {

Cork/Views/Installation/Sub-Views/Presenting Search Results.swift

Lines changed: 100 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,57 @@ struct PresentingSearchResultsView: View
2828
@State private var isCasksSectionCollapsed: Bool = false
2929

3030
@State var isSearchFieldFocused: Bool = true
31+
32+
var wereAnyPackagesFound: Bool
33+
{
34+
if searchResultTracker.foundFormulae.isEmpty && searchResultTracker.foundCasks.isEmpty
35+
{
36+
return false
37+
}
38+
else
39+
{
40+
return true
41+
}
42+
}
3143

3244
var body: some View
3345
{
3446
VStack
3547
{
3648
List(selection: $foundPackageSelection)
3749
{
38-
SearchResultsSection(
39-
sectionType: .formula,
40-
packageList: searchResultTracker.foundFormulae
41-
)
42-
43-
SearchResultsSection(
44-
sectionType: .cask,
45-
packageList: searchResultTracker.foundCasks
46-
)
50+
if !wereAnyPackagesFound
51+
{
52+
if #available(macOS 14.0, *)
53+
{
54+
ContentUnavailableView {
55+
Label("add-package.search.results.packages.none-found", image: "custom.shippingbox.badge.magnifyingglass")
56+
} description: {
57+
Text("add.package.search.results.packages.none-found.description")
58+
} actions: {
59+
EmptyView()
60+
}
61+
62+
} else {
63+
VStack(alignment: .center, spacing: 5) {
64+
Text("add-package.search.results.packages.none-found")
65+
66+
restartSearchButton
67+
}
68+
}
69+
}
70+
else
71+
{
72+
SearchResultsSection(
73+
sectionType: .formula,
74+
packageList: searchResultTracker.foundFormulae
75+
)
76+
77+
SearchResultsSection(
78+
sectionType: .cask,
79+
packageList: searchResultTracker.foundCasks
80+
)
81+
}
4782
}
4883
.listStyle(.bordered(alternatesRowBackgrounds: true))
4984
.frame(minHeight: 200)
@@ -59,15 +94,16 @@ struct PresentingSearchResultsView: View
5994
{
6095
searchForPackageButton
6196
}
62-
63-
ToolbarItem(placement: .primaryAction) {
97+
98+
ToolbarItem(placement: .primaryAction)
99+
{
64100
startInstallProcessButton
65101
}
66-
102+
67103
ToolbarItemGroup(placement: .automatic)
68104
{
69105
previewPackageButton
70-
106+
71107
startInstallProcessButton
72108
}
73109
}
@@ -90,7 +126,7 @@ struct PresentingSearchResultsView: View
90126
}
91127
.disabled(foundPackageSelection == nil)
92128
}
93-
129+
94130
@ViewBuilder
95131
var searchForPackageButton: some View
96132
{
@@ -103,7 +139,7 @@ struct PresentingSearchResultsView: View
103139
.keyboardShortcut(.defaultAction)
104140
.disabled(packageRequested.isEmpty || !isSearchFieldFocused)
105141
}
106-
142+
107143
@ViewBuilder
108144
var startInstallProcessButton: some View
109145
{
@@ -118,6 +154,17 @@ struct PresentingSearchResultsView: View
118154
.keyboardShortcut(.defaultAction)
119155
.disabled(foundPackageSelection == nil)
120156
}
157+
158+
@ViewBuilder
159+
var restartSearchButton: some View
160+
{
161+
Button
162+
{
163+
packageInstallationProcessStep = .ready
164+
} label: {
165+
Text("action.search-again")
166+
}
167+
}
121168

122169
private func getRequestedPackages()
123170
{
@@ -149,30 +196,55 @@ struct PresentingSearchResultsView: View
149196

150197
private struct SearchResultsSection: View
151198
{
152-
fileprivate enum SectionType
153-
{
154-
case formula, cask
155-
}
156-
157-
let sectionType: SectionType
199+
let sectionType: PackageType
158200

159201
let packageList: [BrewPackage]
160202

161203
@State private var isSectionCollapsed: Bool = false
162204

163205
var body: some View
164206
{
165-
Section
207+
if packageList.isEmpty
208+
{
209+
Group
210+
{
211+
if #available(macOS 14.0, *)
212+
{
213+
switch sectionType
214+
{
215+
case .formula:
216+
SmallerContentUnavailableView(label: "add-package.search.results.formulae.none-found", image: "custom.apple.terminal.badge.magnifyingglass")
217+
case .cask:
218+
SmallerContentUnavailableView(label: "add-package.search.results.casks.none-found", image: "custom.macwindow.badge.magnifyingglass")
219+
}
220+
}
221+
else
222+
{
223+
switch sectionType
224+
{
225+
case .formula:
226+
Text("add-package.search.results.formulae.none-found")
227+
case .cask:
228+
Text("add-package.search.results.casks.none-found")
229+
}
230+
}
231+
}
232+
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
233+
}
234+
else
166235
{
167-
if !isSectionCollapsed
236+
Section
168237
{
169-
ForEach(packageList)
170-
{ package in
171-
SearchResultRow(searchedForPackage: package, context: .searchResults, downloadCount: nil)
238+
if !isSectionCollapsed
239+
{
240+
ForEach(packageList)
241+
{ package in
242+
SearchResultRow(searchedForPackage: package, context: .searchResults, downloadCount: nil)
243+
}
172244
}
245+
} header: {
246+
CollapsibleSectionHeader(headerText: sectionType == .formula ? "add-package.search.results.formulae" : "add-package.search.results.casks", isCollapsed: $isSectionCollapsed)
173247
}
174-
} header: {
175-
CollapsibleSectionHeader(headerText: sectionType == .formula ? "add-package.search.results.formulae" : "add-package.search.results.casks", isCollapsed: $isSectionCollapsed)
176248
}
177249
}
178250
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//
2+
// Inline Content Unavailable View.swift
3+
// Cork
4+
//
5+
// Created by David Bureš - P on 14.04.2025.
6+
//
7+
8+
import SwiftUI
9+
10+
struct InlineContentUnavailableView: View
11+
{
12+
let label: LocalizedStringKey
13+
let image: String
14+
15+
var body: some View
16+
{
17+
HStack(alignment: .center, spacing: 5)
18+
{
19+
Image(image)
20+
.resizable()
21+
.aspectRatio(contentMode: .fit)
22+
.frame(width: 30)
23+
.foregroundStyle(.tertiary)
24+
25+
Text(label)
26+
.font(.headline)
27+
.foregroundStyle(.secondary)
28+
}
29+
}
30+
}
31+
32+
struct SmallerContentUnavailableView: View
33+
{
34+
let label: LocalizedStringKey
35+
let image: String
36+
37+
var body: some View
38+
{
39+
VStack(alignment: .center, spacing: 5)
40+
{
41+
Image(image)
42+
.resizable()
43+
.aspectRatio(contentMode: .fit)
44+
.frame(width: 40)
45+
.foregroundStyle(.tertiary)
46+
47+
Text(label)
48+
.font(.headline)
49+
.foregroundStyle(.secondary)
50+
}
51+
}
52+
}
53+
54+
#Preview {
55+
InlineContentUnavailableView(label: "add-package.search.results.casks.none-found", image: "custom.macwindow.badge.magnifyingglass")
56+
}

0 commit comments

Comments
 (0)