Restructure

This commit is contained in:
Alin
2024-10-04 13:15:16 -06:00
parent 512a325c4b
commit b4d676d8a4
9 changed files with 142 additions and 146 deletions
+8 -6
View File
@@ -19,7 +19,7 @@ class AppState: ObservableObject {
@Published var sortedApps: [AppInfo] = [] @Published var sortedApps: [AppInfo] = []
@Published var selectedItems = Set<URL>() @Published var selectedItems = Set<URL>()
@Published var currentView = CurrentDetailsView.empty @Published var currentView = CurrentDetailsView.empty
@Published var currentPage = CurrentPage.installed @Published var currentPage = CurrentPage.applications
@Published var showAlert: Bool = false @Published var showAlert: Bool = false
@Published var sidebar: Bool = true @Published var sidebar: Bool = true
@Published var reload: Bool = false @Published var reload: Bool = false
@@ -193,15 +193,17 @@ enum Arch {
case empty case empty
} }
enum CurrentPage:Int enum CurrentPage:Int, CaseIterable, Identifiable
{ {
case installed case applications
case uninstalled case orphans
var id: Int { rawValue }
var title: String { var title: String {
switch self { switch self {
case .installed: return "Installed" case .applications: return "Applications"
case .uninstalled: return "Uninstalled" case .orphans: return "Orphaned Files"
} }
} }
} }
+1 -1
View File
@@ -144,7 +144,7 @@ func reversePreloader(allApps: [AppInfo], appState: AppState, locations: Locatio
@AppStorage("settings.interface.animationEnabled") var animationEnabled: Bool = true @AppStorage("settings.interface.animationEnabled") var animationEnabled: Bool = true
updateOnMain { updateOnMain {
appState.leftoverProgress.0 = "Finding leftover files, please wait..." appState.leftoverProgress.0 = "Finding orphaned files, please wait..."
} }
ReversePathsSearcher(appState: appState, locations: locations, fsm: fsm, sortedApps: allApps).reversePathsSearch { ReversePathsSearcher(appState: appState, locations: locations, fsm: fsm, sortedApps: allApps).reversePathsSearch {
updateOnMain { updateOnMain {
+15 -15
View File
@@ -91,14 +91,14 @@ func processCLI(arguments: [String], appState: AppState, locations: Locations, f
} }
// Private function to list leftover files for uninstall, using the provided path // Private function to list orphaned files for uninstall, using the provided path
func listLeftoverFiles() { func listLeftoverFiles() {
print("[BETA] Pearcleaner CLI | List Leftover Files:\n") print("[BETA] Pearcleaner CLI | List Orphaned Files:\n")
// Get installed apps for filtering // Get installed apps for filtering
let sortedApps = getSortedApps(paths: fsm.folderPaths) let sortedApps = getSortedApps(paths: fsm.folderPaths)
// Find leftover files // Find orphaned files
let foundPaths = ReversePathsSearcher(locations: locations, fsm: fsm, sortedApps: sortedApps) let foundPaths = ReversePathsSearcher(locations: locations, fsm: fsm, sortedApps: sortedApps)
.reversePathsSearchCLI() .reversePathsSearchCLI()
@@ -106,7 +106,7 @@ func processCLI(arguments: [String], appState: AppState, locations: Locations, f
for path in foundPaths { for path in foundPaths {
print(path.path) print(path.path)
} }
print("\nFound \(foundPaths.count) leftover files.\n") print("\nFound \(foundPaths.count) orphaned files.\n")
} }
// Private function to uninstall the application bundle at a given path // Private function to uninstall the application bundle at a given path
@@ -163,23 +163,23 @@ func processCLI(arguments: [String], appState: AppState, locations: Locations, f
} }
} }
// Private function to remove the leftover files // Private function to remove the orphaned files
func removeLeftoverFiles() { func removeLeftoverFiles() {
print("[BETA] Pearcleaner CLI | Remove Leftover Files:\n") print("[BETA] Pearcleaner CLI | Remove Orphaned Files:\n")
// Get installed apps for filtering // Get installed apps for filtering
let sortedApps = getSortedApps(paths: fsm.folderPaths) let sortedApps = getSortedApps(paths: fsm.folderPaths)
// Find leftover files // Find orphaned files
let foundPaths = ReversePathsSearcher(locations: locations, fsm: fsm, sortedApps: sortedApps) let foundPaths = ReversePathsSearcher(locations: locations, fsm: fsm, sortedApps: sortedApps)
.reversePathsSearchCLI() .reversePathsSearchCLI()
let success = moveFilesToTrashCLI(at: foundPaths) let success = moveFilesToTrashCLI(at: foundPaths)
if success { if success {
print("Leftover files have been moved to the trash successfully.\n") print("Orphaned files have been moved to the trash successfully.\n")
exit(0) exit(0)
} else { } else {
print("Failed to move leftover files to trash.\n") print("Failed to move orphaned files to trash.\n")
exit(1) exit(1)
} }
} }
@@ -197,8 +197,8 @@ func processCLI(arguments: [String], appState: AppState, locations: Locations, f
exit(0) exit(0)
} }
// Handle --listlf or -lf option with a path argument for listing leftover files // Handle --listlf or -lf option with a path argument for listing orphaned files
if options.contains("--list-leftover") || options.contains("-lf") { if options.contains("--list-orphaned") || options.contains("-lo") {
listLeftoverFiles() listLeftoverFiles()
exit(0) exit(0)
} }
@@ -217,8 +217,8 @@ func processCLI(arguments: [String], appState: AppState, locations: Locations, f
exit(0) exit(0)
} }
// Handle --uninstall-lf or -ulf option with a path argument for listing leftover files // Handle --uninstall-lf or -ulf option with a path argument for listing orphaned files
if options.contains("--remove-leftover") || options.contains("-rl") { if options.contains("--remove-orphaned") || options.contains("-ro") {
removeLeftoverFiles() removeLeftoverFiles()
exit(0) exit(0)
} }
@@ -235,10 +235,10 @@ func displayHelp() {
[BETA] Pearcleaner CLI | Usage: [BETA] Pearcleaner CLI | Usage:
--list <path>, -l <path> List application files available for uninstall at the specified path --list <path>, -l <path> List application files available for uninstall at the specified path
--list-leftover, -lf List leftover files available for removal --list-orphaned, -lo List orphaned files available for removal
--uninstall <path>, -u <path> Uninstall only the application bundle at the specified path --uninstall <path>, -u <path> Uninstall only the application bundle at the specified path
--uninstall-all <path>, -ua <path> Uninstall application bundle and ALL related files at the specified path --uninstall-all <path>, -ua <path> Uninstall application bundle and ALL related files at the specified path
--remove-leftover, -rl Remove ALL leftover files (To ignore files, add them to the exception list within Pearcleaner settings) --remove-orphaned, -ro Remove ALL orphaned files (To ignore files, add them to the exception list within Pearcleaner settings)
--help, -h Show this help message --help, -h Show this help message
""") """)
+2 -2
View File
@@ -110,7 +110,7 @@ struct FolderSettingsTab: View {
PearGroupBox(header: { PearGroupBox(header: {
HStack(spacing: 0) { HStack(spacing: 0) {
Text("Exclude these files and folders from leftover search").font(.title2) Text("Exclude these files and folders from leftover search").font(.title2)
InfoButton(text: "Add files or folders that will be ignored when searching for leftover files. Click a path to remove it from the list.") InfoButton(text: "Add files or folders that will be ignored when searching for orphaned files. Click a path to remove it from the list.")
.padding(.leading, 5) .padding(.leading, 5)
Spacer() Spacer()
} }
@@ -287,7 +287,7 @@ class FolderSettingsManager: ObservableObject {
// Leftover files ////////////////////////////////////////////////////////////////////////////////// // Orphaned files //////////////////////////////////////////////////////////////////////////////////
func addPathZ(_ path: String) { func addPathZ(_ path: String) {
let sanitizedPath = path.hasPrefix("/private") ? String(path.dropFirst(8)) : path let sanitizedPath = path.hasPrefix("/private") ? String(path.dropFirst(8)) : path
+1 -1
View File
@@ -29,7 +29,7 @@ struct TipsSettingsTab: View {
Text("6. On the Files view again, you can hit CMD + E to export a list of the found files or from the Tools menubar item") Text("6. On the Files view again, you can hit CMD + E to export a list of the found files or from the Tools menubar item")
Text("7. CMD + U will check for updates manually") Text("7. CMD + U will check for updates manually")
Text("8. CMD + R will refresh the app list. This can also be done from the refresh button in the search bar") Text("8. CMD + R will refresh the app list. This can also be done from the refresh button in the search bar")
Text("9. In the search bar menu button, you will also find Leftover Files which will find files leftover by previously uninstalled applications") Text("9. In the search bar menu button, you will also find Orphaned Files which will find files leftover by previously uninstalled applications")
Text("10. You can enable a menubar icon from Settings") Text("10. You can enable a menubar icon from Settings")
Text("11. You can enable mini mode version of the UI from Settings") Text("11. You can enable mini mode version of the UI from Settings")
Text("12. You can enable a Finder extension from Settings which allows you to uninstall apps by right clicking them in Finder") Text("12. You can enable a Finder extension from Settings which allows you to uninstall apps by right clicking them in Finder")
+5 -4
View File
@@ -88,7 +88,7 @@ struct AppSearchView: View {
Button("More") { Button("More") {
self.showMenu.toggle() self.showMenu.toggle()
} }
.buttonStyle(SimpleButtonStyle(icon: "ellipsis.circle", help: "More", size: 16, rotate: true)) .buttonStyle(SimpleButtonStyle(icon: "ellipsis.circle", help: "More", size: 16, rotate: false))
.popover(isPresented: $showMenu) { .popover(isPresented: $showMenu) {
VStack(alignment: .leading) { VStack(alignment: .leading) {
@@ -97,7 +97,7 @@ struct AppSearchView: View {
selectedSortAlpha.toggle() selectedSortAlpha.toggle()
} }
} }
.buttonStyle(SimpleButtonStyle(icon: "circle.fill", label: "Sorting: \(selectedSortAlpha ? "ABC" : "123")", help: "Can also click on User/System headers to toggle this", size: 5)) .buttonStyle(SimpleButtonStyle(icon: "circle.fill", label: "Sorting: \(selectedSortAlpha ? "Name" : "Size")", help: "Sort app list alphabetically by name or by size", size: 5))
if mini && !menubarEnabled { if mini && !menubarEnabled {
Button("") { Button("") {
@@ -111,7 +111,7 @@ struct AppSearchView: View {
} }
Button("Leftover Files") { Button("Orphaned Files") {
showMenu = false showMenu = false
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) { withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
showPopover = false showPopover = false
@@ -127,7 +127,7 @@ struct AppSearchView: View {
} }
} }
} }
.buttonStyle(SimpleButtonStyle(icon: "circle.fill", label: "Leftover Files", help: "Leftover Files", size: 5)) .buttonStyle(SimpleButtonStyle(icon: "circle.fill", label: "Orphaned Files", help: "Orphaned Files", size: 5))
if #available(macOS 14.0, *) { if #available(macOS 14.0, *) {
@@ -155,6 +155,7 @@ struct AppSearchView: View {
} }
.padding() .padding()
.background(backgroundView(themeManager: themeManager, glass: glass).padding(-80)) .background(backgroundView(themeManager: themeManager, glass: glass).padding(-80))
.frame(width: 150)
} }
} }
+6 -28
View File
@@ -26,8 +26,6 @@ struct FilesView: View {
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
@Binding var showPopover: Bool @Binding var showPopover: Bool
@Binding var search: String @Binding var search: String
// @State private var elapsedTime = 0
// @State private var timer: Timer? = nil
var body: some View { var body: some View {
@@ -59,41 +57,18 @@ struct FilesView: View {
ProgressView().controlSize(.small) ProgressView().controlSize(.small)
} }
// Text("Searching the file system").font(.title3)
// .foregroundStyle((.primary.opacity(0.5)))
//
// ProgressView()
// .progressViewStyle(.linear)
// .frame(width: 400, height: 10)
//
// Text("\(elapsedTime)")
// .font(.title).monospacedDigit()
// .foregroundStyle((.primary.opacity(0.5)))
// .opacity(elapsedTime == 0 ? 0 : 1)
// .contentTransition(.numericText())
Spacer() Spacer()
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.opacity) .transition(.opacity)
// .onAppear {
// self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
// withAnimation {
// self.elapsedTime += 1
// }
// }
// }
// .onDisappear {
// self.timer?.invalidate()
// self.timer = nil
// self.elapsedTime = 0
// }
} else { } else {
// Titlebar // Titlebar
HStack(spacing: 0) { HStack(spacing: 0) {
Spacer() Spacer()
if mini || menubarEnabled {
Button("Close") { Button("Close") {
updateOnMain { updateOnMain {
appState.appInfo = AppInfo.empty appState.appInfo = AppInfo.empty
@@ -104,7 +79,10 @@ struct FilesView: View {
} }
.buttonStyle(SimpleButtonStyle(icon: "x.circle", iconFlip: "x.circle.fill", help: "Close")) .buttonStyle(SimpleButtonStyle(icon: "x.circle", iconFlip: "x.circle.fill", help: "Close"))
} }
.padding(.top, 6)
}
.padding(.top, (mini || menubarEnabled) ? 6 : 30)
.padding(.trailing, (mini || menubarEnabled) ? 6 : 0) .padding(.trailing, (mini || menubarEnabled) ? 6 : 0)
VStack(spacing: 0) { VStack(spacing: 0) {
+29 -16
View File
@@ -29,14 +29,9 @@ struct RegularMode: View {
var body: some View { var body: some View {
// Main App Window // Main App Window
VStack(spacing: 0) { ZStack() {
// Tab View if appState.currentPage == .applications {
CustomTabView(content: [
(
title: "Installed",
icon: "externaldrive",
view: AnyView (
HStack(alignment: .center, spacing: 0) { HStack(alignment: .center, spacing: 0) {
// App List // App List
@@ -90,12 +85,8 @@ struct RegularMode: View {
.zIndex(2) .zIndex(2)
.background(backgroundView(themeManager: themeManager)) .background(backgroundView(themeManager: themeManager))
} }
)
), } else if appState.currentPage == .orphans {
(
title: "Uninstalled",
icon: "externaldrive.badge.minus",
view: AnyView(
ZombieView(showPopover: $showPopover, search: $search) ZombieView(showPopover: $showPopover, search: $search)
.background(backgroundView(themeManager: themeManager)) .background(backgroundView(themeManager: themeManager))
.onAppear { .onAppear {
@@ -108,9 +99,31 @@ struct RegularMode: View {
} }
} }
} }
) }
),
]) VStack(spacing: 0) {
HStack {
Spacer()
Picker("", selection: $appState.currentPage) {
ForEach(CurrentPage.allCases) { page in
Text(page.title)
.font(.title3)
.tag(page)
}
}
.buttonStyle(.borderless)
.padding(2)
.padding(.vertical, 2)
.background {
RoundedRectangle(cornerRadius: 8)
.strokeBorder(.secondary.opacity(0.5), lineWidth: 1)
}
}
.padding(6)
Spacer()
}
} }
.frame(minWidth: 900, minHeight: 600) .frame(minWidth: 900, minHeight: 600)
+4 -2
View File
@@ -64,6 +64,7 @@ struct ZombieView: View {
HStack(spacing: 0) { HStack(spacing: 0) {
Spacer() Spacer()
if mini || menubarEnabled {
Button("Close") { Button("Close") {
updateOnMain { updateOnMain {
appState.appInfo = AppInfo.empty appState.appInfo = AppInfo.empty
@@ -74,7 +75,8 @@ struct ZombieView: View {
} }
.buttonStyle(SimpleButtonStyle(icon: "x.circle", iconFlip: "x.circle.fill", help: "Close")) .buttonStyle(SimpleButtonStyle(icon: "x.circle", iconFlip: "x.circle.fill", help: "Close"))
} }
.padding(.top, 6) }
.padding(.top, (mini || menubarEnabled) ? 6 : 30)
.padding(.trailing, (mini || menubarEnabled) ? 6 : 0) .padding(.trailing, (mini || menubarEnabled) ? 6 : 0)
@@ -94,7 +96,7 @@ struct ZombieView: View {
VStack(alignment: .leading, spacing: 10){ VStack(alignment: .leading, spacing: 10){
HStack { HStack {
Text("Leftover Files").font(.title).fontWeight(.bold) Text("Orphaned Files").font(.title).fontWeight(.bold)
Spacer() Spacer()
} }
Text("Remaining files and folders from previous applications") Text("Remaining files and folders from previous applications")