Skip to content

Commit bff7985

Browse files
committed
Merge branch 'small-fixes.new-selections' into main.small-fixes.list-width
2 parents 3ded791 + 271b014 commit bff7985

25 files changed

Lines changed: 187 additions & 254 deletions

Cork/App State.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class AppState: ObservableObject
4242
@Published var isShowingFatalError: Bool = false
4343
@Published var fatalAlertType: DisplayableAlert? = nil
4444

45+
@Published var isShowingConfirmationDialog: Bool = false
46+
@Published var confirmationDialogType: ConfirmationDialog?
47+
4548
@Published var sheetToShow: DisplayableSheet? = nil
4649

4750
@Published var packageTryingToBeUninstalledWithSudo: BrewPackage?
@@ -101,6 +104,20 @@ class AppState: ObservableObject
101104
self.sheetToShow = nil
102105
}
103106

107+
// MARK: Showing confirmation dialogs
108+
109+
func showConfirmationDialog(ofType confirmationDialogType: ConfirmationDialog)
110+
{
111+
self.confirmationDialogType = confirmationDialogType
112+
self.isShowingConfirmationDialog = true
113+
}
114+
115+
func dismissConfirmationDialog()
116+
{
117+
self.isShowingConfirmationDialog = false
118+
self.confirmationDialogType = nil
119+
}
120+
104121
// MARK: - Notification setup
105122

106123
func setupNotifications() async

Cork/ContentView.swift

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ struct ContentView: View, Sendable
3939
@EnvironmentObject var updateProgressTracker: UpdateProgressTracker
4040

4141
@EnvironmentObject var outdatedPackageTracker: OutdatedPackageTracker
42-
@EnvironmentObject var uninstallationConfirmationTracker: UninstallationConfirmationTracker
4342

4443
@State private var multiSelection: Set<UUID> = .init()
4544
@State private var columnVisibility: NavigationSplitViewVisibility = .doubleColumn
@@ -755,36 +754,42 @@ private extension View
755754
func confirmationDialogs(of view: ContentView) -> some View
756755
{
757756
self
758-
.confirmationDialog(view.uninstallationConfirmationTracker.shouldPurge ? "action.purge.confirm.title.\(view.uninstallationConfirmationTracker.packageThatNeedsConfirmation.name)" : "action.uninstall.confirm.title.\(view.uninstallationConfirmationTracker.packageThatNeedsConfirmation.name)", isPresented: view.$uninstallationConfirmationTracker.isShowingUninstallOrPurgeConfirmation)
759-
{
760-
AsyncButton(role: .destructive)
761-
{
762-
view.uninstallationConfirmationTracker.isShowingUninstallOrPurgeConfirmation = false
763-
764-
try await view.brewData.uninstallSelectedPackage(
765-
package: view.uninstallationConfirmationTracker.packageThatNeedsConfirmation,
766-
cachedPackagesTracker: view.cachedDownloadsTracker,
767-
appState: view.appState,
768-
outdatedPackageTracker: view.outdatedPackageTracker,
769-
shouldRemoveAllAssociatedFiles: view.uninstallationConfirmationTracker.shouldPurge,
770-
shouldApplyUninstallSpinnerToRelevantItemInSidebar: view.uninstallationConfirmationTracker.isCalledFromSidebar
771-
)
772-
} label: {
773-
Text(view.uninstallationConfirmationTracker.shouldPurge ? "action.purge-\(view.uninstallationConfirmationTracker.packageThatNeedsConfirmation.name)" : "action.uninstall-\(view.uninstallationConfirmationTracker.packageThatNeedsConfirmation.name)")
774-
}
775-
.keyboardShortcut(.defaultAction)
776-
.asyncButtonStyle(.plainStyle)
777-
778-
Button(role: .cancel)
757+
.confirmationDialog(view.appState.confirmationDialogType?.title ?? "error.generic", isPresented: view.$appState.isShowingConfirmationDialog, presenting: view.appState.confirmationDialogType, actions: { dialogType in
758+
switch dialogType
779759
{
780-
view.uninstallationConfirmationTracker.dismissConfirmationDialog()
781-
} label: {
782-
Text("action.cancel")
760+
case .uninstallPackage(let packageToUninstall):
761+
AsyncButton
762+
{
763+
try await view.brewData.uninstallSelectedPackage(
764+
package: packageToUninstall,
765+
cachedPackagesTracker: view.cachedDownloadsTracker,
766+
appState: view.appState,
767+
outdatedPackageTracker: view.outdatedPackageTracker,
768+
shouldRemoveAllAssociatedFiles: false
769+
)
770+
} label: {
771+
Text("action.uninstall-\(packageToUninstall.name)")
772+
}
773+
.keyboardShortcut(.defaultAction)
774+
.asyncButtonStyle(.plainStyle)
775+
776+
case .purgePackage(let packageToPurge):
777+
AsyncButton
778+
{
779+
try await view.brewData.uninstallSelectedPackage(
780+
package: packageToPurge,
781+
cachedPackagesTracker: view.cachedDownloadsTracker,
782+
appState: view.appState,
783+
outdatedPackageTracker: view.outdatedPackageTracker,
784+
shouldRemoveAllAssociatedFiles: true
785+
)
786+
} label: {
787+
Text("action.purge-\(packageToPurge.name)")
788+
}
783789
}
784-
.keyboardShortcut(.cancelAction)
785-
} message: {
786-
Text("action.warning.cannot-be-undone")
787-
}
790+
}, message: { dialogType in
791+
Text(dialogType.message)
792+
})
788793
}
789794
}
790795

Cork/CorkApp.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ struct CorkApp: App
2929
@StateObject var updateProgressTracker: UpdateProgressTracker = .init()
3030
@StateObject var outdatedPackageTracker: OutdatedPackageTracker = .init()
3131

32-
@StateObject var uninstallationConfirmationTracker: UninstallationConfirmationTracker = .init()
33-
3432
@AppStorage("demoActivatedAt") var demoActivatedAt: Date?
3533
@AppStorage("hasValidatedEmail") var hasValidatedEmail: Bool = false
3634

@@ -87,7 +85,6 @@ struct CorkApp: App
8785
.environmentObject(updateProgressTracker)
8886
.environmentObject(outdatedPackageTracker)
8987
.environmentObject(topPackagesTracker)
90-
.environmentObject(uninstallationConfirmationTracker)
9188
.task
9289
{
9390
NSWindow.allowsAutomaticWindowTabbing = false
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// Confirmation Dialog - Main Window.swift
3+
// Cork
4+
//
5+
// Created by David Bureš - P on 21.04.2025.
6+
//
7+
8+
import Foundation
9+
import SwiftUI
10+
11+
enum ConfirmationDialog: Identifiable, Equatable
12+
{
13+
case uninstallPackage(_ packageToUninstall: BrewPackage)
14+
15+
case purgePackage(_ packageToPurge: BrewPackage)
16+
17+
var id: UUID
18+
{
19+
return .init()
20+
}
21+
22+
var title: LocalizedStringKey
23+
{
24+
switch self
25+
{
26+
case .uninstallPackage(let packageToUninstall):
27+
return "action.uninstall.confirm.title.\(packageToUninstall.name)"
28+
case .purgePackage(let packageToPurge):
29+
return "action.purge.confirm.title.\(packageToPurge.name)"
30+
}
31+
}
32+
33+
var message: LocalizedStringKey
34+
{
35+
switch self {
36+
case .uninstallPackage(_), .purgePackage(_):
37+
return "action.warning.cannot-be-undone"
38+
}
39+
}
40+
}

Cork/Localizable.xcstrings

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20512,6 +20512,9 @@
2051220512
}
2051320513
}
2051420514
}
20515+
},
20516+
"error.generic" : {
20517+
2051520518
},
2051620519
"error.generic-couldnt-decode-json.%@" : {
2051720520
"localizations" : {

Cork/Logic/Discoverability/Load up Top Packages.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ extension TopPackagesTracker
4040
return decoder
4141
}()
4242

43-
async let topFormulae: [TopPackage] = await loadTopFormulae(numberOfDays: numberOfDays, downloadsCutoff: packageDownloadsCutoff, decoder: decoder)
44-
async let topCasks: [TopPackage] = await loadTopCasks(numberOfDays: numberOfDays, downloadsCutoff: packageDownloadsCutoff, decoder: decoder)
43+
async let topFormulae: [BrewPackage] = await loadTopFormulae(numberOfDays: numberOfDays, downloadsCutoff: packageDownloadsCutoff, decoder: decoder)
44+
async let topCasks: [BrewPackage] = await loadTopCasks(numberOfDays: numberOfDays, downloadsCutoff: packageDownloadsCutoff, decoder: decoder)
4545

4646
do
4747
{
@@ -66,7 +66,7 @@ extension TopPackagesTracker
6666

6767
// MARK: - Loading top formulae
6868

69-
private func loadTopFormulae(numberOfDays: Int, downloadsCutoff: Int, decoder: JSONDecoder) async throws -> [TopPackage]
69+
private func loadTopFormulae(numberOfDays: Int, downloadsCutoff: Int, decoder: JSONDecoder) async throws -> [BrewPackage]
7070
{
7171
struct TopFormulaeOutput: Codable
7272
{
@@ -99,7 +99,7 @@ extension TopPackagesTracker
9999

100100
if normalizedDownloadNumber > downloadsCutoff
101101
{
102-
return .init(packageName: rawTopFormula.formula, packageDownloads: normalizedDownloadNumber)
102+
return .init(name: rawTopFormula.formula, type: .formula, installedOn: nil, versions: .init(), sizeInBytes: nil, downloadCount: normalizedDownloadNumber)
103103
}
104104
else
105105
{
@@ -122,7 +122,7 @@ extension TopPackagesTracker
122122

123123
// MARK: - Loading top casks
124124

125-
private func loadTopCasks(numberOfDays: Int, downloadsCutoff: Int, decoder: JSONDecoder) async throws -> [TopPackage]
125+
private func loadTopCasks(numberOfDays: Int, downloadsCutoff: Int, decoder: JSONDecoder) async throws -> [BrewPackage]
126126
{
127127
struct TopCasksOutput: Codable
128128
{
@@ -155,7 +155,7 @@ extension TopPackagesTracker
155155

156156
if normalizedDownloadNumber > downloadsCutoff
157157
{
158-
return .init(packageName: rawTopCask.cask, packageDownloads: normalizedDownloadNumber)
158+
return .init(name: rawTopCask.cask, type: .cask, installedOn: nil, versions: .init(), sizeInBytes: nil, downloadCount: normalizedDownloadNumber)
159159
}
160160
else
161161
{

Cork/Logic/Installation & Removal/Removal/Uninstall Packages.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ extension BrewDataStorage
1717
cachedPackagesTracker: CachedPackagesTracker,
1818
appState: AppState,
1919
outdatedPackageTracker: OutdatedPackageTracker,
20-
shouldRemoveAllAssociatedFiles: Bool,
21-
shouldApplyUninstallSpinnerToRelevantItemInSidebar _: Bool = false
20+
shouldRemoveAllAssociatedFiles: Bool
2221
) async throws
2322
{
2423
/// Store the old navigation selection to see if it got updated in the middle of switching

Cork/Logic/Package Loading/Load Up Installed Packages.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ private extension BrewDataStorage
223223
installedOn: packageURL.creationDate,
224224
versions: versionNamesForPackage,
225225
installedIntentionally: wasPackageInstalledIntentionally,
226-
sizeInBytes: packageURL.directorySize
226+
sizeInBytes: packageURL.directorySize,
227+
downloadCount: nil
227228
)
228229
)
229230

Cork/Logic/Search for Package by ID.swift

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,63 +22,6 @@ private enum PackageRetrievalByUUIDError: LocalizedError
2222
}
2323
}
2424

25-
extension UUID
26-
{
27-
/// Get a package by UUID from a list
28-
func getPackage(tracker: SearchResultTracker) throws -> BrewPackage
29-
{
30-
var filteredPackage: BrewPackage?
31-
32-
AppConstants.shared.logger.log("Formula tracker: \(tracker.foundFormulae.count)")
33-
AppConstants.shared.logger.log("Cask tracker: \(tracker.foundCasks.count)")
34-
35-
if !tracker.foundFormulae.isEmpty
36-
{
37-
filteredPackage = tracker.foundFormulae.filter { $0.id == self }.first
38-
}
39-
40-
if filteredPackage == nil
41-
{
42-
filteredPackage = tracker.foundCasks.filter { $0.id == self }.first
43-
}
44-
45-
if let filteredPackage
46-
{
47-
return filteredPackage
48-
}
49-
else
50-
{
51-
throw PackageRetrievalByUUIDError.couldNotfindAnypackagesInTracker
52-
}
53-
}
54-
55-
/// Get a top package by UUID from top package list
56-
@MainActor
57-
func getPackage(tracker: TopPackagesTracker, packageType: PackageType) throws -> BrewPackage
58-
{
59-
if packageType == .formula
60-
{
61-
guard let foundTopFormula: TopPackage = tracker.topFormulae.filter({ $0.id == self }).first
62-
else
63-
{
64-
throw TopPackageRetrievalError.resultingArrayWasEmptyEvenThoughPackagesWereInIt
65-
}
66-
67-
return .init(name: foundTopFormula.packageName, type: .formula, installedOn: nil, versions: [], sizeInBytes: nil)
68-
}
69-
else
70-
{
71-
guard let foundTopCask: TopPackage = tracker.topCasks.filter({ $0.id == self }).first
72-
else
73-
{
74-
throw TopPackageRetrievalError.resultingArrayWasEmptyEvenThoughPackagesWereInIt
75-
}
76-
77-
return .init(name: foundTopCask.packageName, type: .cask, installedOn: nil, versions: [], sizeInBytes: nil)
78-
}
79-
}
80-
}
81-
8225
enum TopPackageRetrievalError: LocalizedError
8326
{
8427
case resultingArrayWasEmptyEvenThoughPackagesWereInIt

Cork/Models/Discoverability/Top Package.swift

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)