mirror of
https://github.com/exituser/Pearcleaner.git
synced 2026-09-17 04:58:56 +00:00
Fixes
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
"location" : "https://github.com/alienator88/AlinFoundation",
|
"location" : "https://github.com/alienator88/AlinFoundation",
|
||||||
"state" : {
|
"state" : {
|
||||||
"branch" : "main",
|
"branch" : "main",
|
||||||
"revision" : "705a7e5fe3c1374000d2fd29f1c58fa476b0453c"
|
"revision" : "eb160d04a32e1e2fe54bfa3fac1f6a7535d7b2fb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ class AppPathFinder {
|
|||||||
private var appState: AppState
|
private var appState: AppState
|
||||||
private var locations: Locations
|
private var locations: Locations
|
||||||
private var backgroundRun: Bool
|
private var backgroundRun: Bool
|
||||||
// private var reverseAddon: Bool
|
|
||||||
private var undo: Bool
|
private var undo: Bool
|
||||||
private var completion: () -> Void = {}
|
private var completion: () -> Void = {}
|
||||||
private var collection: [URL] = []
|
private var collection: [URL] = []
|
||||||
|
private var containerCollection: [URL] = []
|
||||||
private let collectionAccessQueue = DispatchQueue(label: "com.alienator88.Pearcleaner.appPathFinder.collectionAccess")
|
private let collectionAccessQueue = DispatchQueue(label: "com.alienator88.Pearcleaner.appPathFinder.collectionAccess")
|
||||||
|
|
||||||
init(appInfo: AppInfo = .empty, appState: AppState, locations: Locations, backgroundRun: Bool = false, undo: Bool = false, completion: @escaping () -> Void = {}) {
|
init(appInfo: AppInfo = .empty, appState: AppState, locations: Locations, backgroundRun: Bool = false, undo: Bool = false, completion: @escaping () -> Void = {}) {
|
||||||
@@ -26,7 +26,6 @@ class AppPathFinder {
|
|||||||
self.appState = appState
|
self.appState = appState
|
||||||
self.locations = locations
|
self.locations = locations
|
||||||
self.backgroundRun = backgroundRun
|
self.backgroundRun = backgroundRun
|
||||||
// self.reverseAddon = reverseAddon
|
|
||||||
self.undo = undo
|
self.undo = undo
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
}
|
}
|
||||||
@@ -34,9 +33,11 @@ class AppPathFinder {
|
|||||||
func findPaths() {
|
func findPaths() {
|
||||||
Task(priority: .background) {
|
Task(priority: .background) {
|
||||||
if self.appInfo.webApp {
|
if self.appInfo.webApp {
|
||||||
|
containerCollection = self.getAllContainers(bundleURL: self.appInfo.path)
|
||||||
self.initialURLProcessing()
|
self.initialURLProcessing()
|
||||||
self.finalizeCollection()
|
self.finalizeCollection()
|
||||||
} else {
|
} else {
|
||||||
|
containerCollection = self.getAllContainers(bundleURL: self.appInfo.path)
|
||||||
self.initialURLProcessing()
|
self.initialURLProcessing()
|
||||||
self.collectDirectories()
|
self.collectDirectories()
|
||||||
self.collectFiles()
|
self.collectFiles()
|
||||||
@@ -268,14 +269,14 @@ class AppPathFinder {
|
|||||||
|
|
||||||
private func finalizeCollection() {
|
private func finalizeCollection() {
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
let allContainers = self.getAllContainers(bundleURL: self.appInfo.path)
|
// let allContainers = self.getAllContainers(bundleURL: self.appInfo.path)
|
||||||
let outliers = self.handleOutliers()
|
let outliers = self.handleOutliers()
|
||||||
let outliersEx = self.handleOutliers(include: false)
|
let outliersEx = self.handleOutliers(include: false)
|
||||||
var tempCollection: [URL] = []
|
var tempCollection: [URL] = []
|
||||||
self.collectionAccessQueue.sync {
|
self.collectionAccessQueue.sync {
|
||||||
tempCollection = self.collection
|
tempCollection = self.collection
|
||||||
}
|
}
|
||||||
tempCollection.append(contentsOf: allContainers)
|
tempCollection.append(contentsOf: self.containerCollection)
|
||||||
tempCollection.append(contentsOf: outliers)
|
tempCollection.append(contentsOf: outliers)
|
||||||
|
|
||||||
// Remove URLs based on outliersExcludes
|
// Remove URLs based on outliersExcludes
|
||||||
|
|||||||
+15
-136
@@ -111,10 +111,6 @@ func listAppSupportDirectories() -> [String] {
|
|||||||
// Load app paths on launch
|
// Load app paths on launch
|
||||||
func reversePreloader(allApps: [AppInfo], appState: AppState, locations: Locations, fsm: FolderSettingsManager, completion: @escaping () -> Void = {}) {
|
func reversePreloader(allApps: [AppInfo], appState: AppState, locations: Locations, fsm: FolderSettingsManager, completion: @escaping () -> Void = {}) {
|
||||||
@AppStorage("settings.interface.animationEnabled") var animationEnabled: Bool = true
|
@AppStorage("settings.interface.animationEnabled") var animationEnabled: Bool = true
|
||||||
// appState.operationQueueLeftover.maxConcurrentOperationCount = 10 // Adjust this value as needed
|
|
||||||
// appState.shouldCancelOperations = false
|
|
||||||
// appState.appInfoStore.removeAll()
|
|
||||||
// let sortedAllApps = allApps.sorted { $0.appName.localizedCompare($1.appName) == .orderedAscending }
|
|
||||||
|
|
||||||
updateOnMain {
|
updateOnMain {
|
||||||
appState.leftoverProgress.0 = "Finding leftover files, please wait..."
|
appState.leftoverProgress.0 = "Finding leftover files, please wait..."
|
||||||
@@ -130,88 +126,6 @@ func reversePreloader(allApps: [AppInfo], appState: AppState, locations: Locatio
|
|||||||
}
|
}
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
|
|
||||||
// let totalApps = sortedAllApps.count
|
|
||||||
// var processedApps = 0
|
|
||||||
//
|
|
||||||
// DispatchQueue.global(qos: .userInitiated).async {
|
|
||||||
// for (index, app) in sortedAllApps.enumerated() {
|
|
||||||
// autoreleasepool {
|
|
||||||
// if appState.shouldCancelOperations {
|
|
||||||
// printOS("Operations cancelled.") // Debug print
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// printOS("Processing app \(index + 1) of \(totalApps): \(app.appName)")
|
|
||||||
//
|
|
||||||
// let semaphore = DispatchSemaphore(value: 0)
|
|
||||||
// appState.operationQueueLeftover.addOperation {
|
|
||||||
// if appState.shouldCancelOperations {
|
|
||||||
// printOS("Operations cancelled.") // Debug print
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// let pathFinder = AppPathFinder(
|
|
||||||
// appInfo: app,
|
|
||||||
// appState: appState,
|
|
||||||
// locations: locations,
|
|
||||||
// backgroundRun: true,
|
|
||||||
// reverseAddon: reverseAddon,
|
|
||||||
// completion: {
|
|
||||||
// semaphore.signal()
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// pathFinder.findPaths()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// semaphore.wait()
|
|
||||||
//
|
|
||||||
// DispatchQueue.main.async {
|
|
||||||
// processedApps += 1
|
|
||||||
// let progress = Double(processedApps) / Double(totalApps)
|
|
||||||
// withAnimation {
|
|
||||||
// appState.leftoverProgress.1 = progress
|
|
||||||
// }
|
|
||||||
// appState.leftoverProgress.0 = "Excluding application files for \(app.appName)"
|
|
||||||
// printOS("Progress: \(Int(progress * 100))%") // Debug print
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// appState.operationQueueLeftover.waitUntilAllOperationsAreFinished()
|
|
||||||
//
|
|
||||||
// DispatchQueue.main.async {
|
|
||||||
// if appState.shouldCancelOperations {
|
|
||||||
// completion()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if appState.appInfoStore.count == sortedAllApps.count {
|
|
||||||
// printOS("All apps processed successfully")
|
|
||||||
// appState.leftoverProgress.0 = "Finding leftover files, please wait..."
|
|
||||||
// ReversePathsSearcher(appState: appState, locations: locations, fsm: fsm, sortedApps: sortedAllApps).reversePathsSearch {
|
|
||||||
// updateOnMain {
|
|
||||||
// printOS("Reverse search processed successfully")
|
|
||||||
// appState.showProgress = false
|
|
||||||
// withAnimation {
|
|
||||||
// appState.leftoverProgress.1 = 0.0
|
|
||||||
// }
|
|
||||||
// appState.leftoverProgress.0 = "Reverse search completed successfully"
|
|
||||||
// }
|
|
||||||
// completion()
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// printOS("reversePreloader - Not all paths were loaded. Expected: \(sortedAllApps.count), Actual: \(appState.appInfoStore.count)")
|
|
||||||
// updateOnMain {
|
|
||||||
// appState.showProgress = false
|
|
||||||
// withAnimation {
|
|
||||||
// appState.leftoverProgress.1 = 0.0
|
|
||||||
// }
|
|
||||||
// appState.leftoverProgress.0 = "Reverse search failed to process existing application files (\(sortedAllApps.count)/\(appState.appInfoStore.count))"
|
|
||||||
// }
|
|
||||||
// completion()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -245,38 +159,6 @@ func showAppInFiles(appInfo: AppInfo, appState: AppState, locations: Locations,
|
|||||||
appState.currentView = .files
|
appState.currentView = .files
|
||||||
showPopover.wrappedValue.toggle()
|
showPopover.wrappedValue.toggle()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the appInfo exists in the appState.appInfoStore
|
|
||||||
// if let storedAppInfo = appState.appInfoStore.first(where: { $0.path == appInfo.path }) {
|
|
||||||
// // Update appState with the stored app info and selected items.
|
|
||||||
// appState.appInfo = storedAppInfo
|
|
||||||
// appState.selectedItems = Set(storedAppInfo.files)
|
|
||||||
//
|
|
||||||
// // Trigger the animation for changing views and showing the popover.
|
|
||||||
// withAnimation(Animation.easeIn(duration: 0.4)) {
|
|
||||||
// appState.currentView = .files
|
|
||||||
// showPopover.wrappedValue.toggle()
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // When the appInfo is not found, show progress, and search for paths.
|
|
||||||
// appState.showProgress = true
|
|
||||||
//
|
|
||||||
// // Initialize the path finder and execute its search.
|
|
||||||
// AppPathFinder(appInfo: appInfo, appState: appState, locations: locations) {
|
|
||||||
// updateOnMain {
|
|
||||||
// // Update the progress indicator on the main thread once the search completes.
|
|
||||||
// appState.showProgress = false
|
|
||||||
// }
|
|
||||||
// }.findPaths()
|
|
||||||
//
|
|
||||||
// appState.appInfo = appInfo
|
|
||||||
//
|
|
||||||
// // Animate the view change and popover display.
|
|
||||||
// withAnimation(Animation.easeIn(duration: 0.4)) {
|
|
||||||
// appState.currentView = .files
|
|
||||||
// showPopover.wrappedValue.toggle()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,23 +179,28 @@ func moveFilesToTrash(appState: AppState, at fileURLs: [URL], completion: @escap
|
|||||||
var error: NSDictionary?
|
var error: NSDictionary?
|
||||||
if let scriptObject = NSAppleScript(source: scriptSource) {
|
if let scriptObject = NSAppleScript(source: scriptSource) {
|
||||||
let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(&error)
|
let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(&error)
|
||||||
|
|
||||||
|
// Handle any AppleScript errors
|
||||||
if let error = error {
|
if let error = error {
|
||||||
// checkAllPermissions(appState: appState) { results in
|
|
||||||
// appState.permissionResults = results
|
|
||||||
// if !results.allPermissionsGranted {
|
|
||||||
// updateOnMain {
|
|
||||||
// appState.permissionsOkay = false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
printOS("Trash Error: \(error)")
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
printOS("Trash Error: \(error)")
|
||||||
completion(false) // Indicate failure
|
completion(false) // Indicate failure
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if output is null, indicating the user canceled the operation
|
||||||
|
if output.descriptorType == typeNull {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
printOS("Trash Error: operation canceled by the user")
|
||||||
|
completion(false) // Indicate failure due to cancellation
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process output if it exists
|
||||||
if let outputString = output.stringValue {
|
if let outputString = output.stringValue {
|
||||||
printOS(outputString)
|
printOS("Trash: \(outputString)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@@ -347,14 +234,6 @@ func undoTrash(appState: AppState, completion: @escaping () -> Void = {}) {
|
|||||||
if let scriptObject = NSAppleScript(source: scriptSource) {
|
if let scriptObject = NSAppleScript(source: scriptSource) {
|
||||||
let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(&error)
|
let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(&error)
|
||||||
if let error = error {
|
if let error = error {
|
||||||
// checkAllPermissions(appState: appState) { results in
|
|
||||||
// appState.permissionResults = results
|
|
||||||
// if !results.allPermissionsGranted {
|
|
||||||
// updateOnMain {
|
|
||||||
// appState.permissionsOkay = false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
printOS("Undo Trash Error: \(error)")
|
printOS("Undo Trash Error: \(error)")
|
||||||
} else if let outputString = output.stringValue {
|
} else if let outputString = output.stringValue {
|
||||||
printOS(outputString)
|
printOS(outputString)
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ struct Sponsor: Identifiable {
|
|||||||
let url: URL
|
let url: URL
|
||||||
|
|
||||||
static let sponsors: [Sponsor] = [
|
static let sponsors: [Sponsor] = [
|
||||||
|
Sponsor(name: "fpuhan", url: URL(string: "https://github.com/fpuhan")!),
|
||||||
|
Sponsor(name: "HungThinhIT", url: URL(string: "https://github.com/HungThinhIT")!),
|
||||||
Sponsor(name: "DharsanB", url: URL(string: "https://github.com/dharsanb")!),
|
Sponsor(name: "DharsanB", url: URL(string: "https://github.com/dharsanb")!),
|
||||||
Sponsor(name: "MadMacMad", url: URL(string: "https://github.com/MadMacMad")!),
|
Sponsor(name: "MadMacMad", url: URL(string: "https://github.com/MadMacMad")!),
|
||||||
Sponsor(name: "Butterdawgs", url: URL(string: "https://github.com/butterdawgs")!),
|
Sponsor(name: "Butterdawgs", url: URL(string: "https://github.com/butterdawgs")!),
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ struct ZombieView: View {
|
|||||||
ForEach(memoizedFiles, id: \.self) { file in
|
ForEach(memoizedFiles, id: \.self) { file in
|
||||||
if let fileSize = appState.zombieFile.fileSize[file], let fileSizeL = appState.zombieFile.fileSizeLogical[file], let fileIcon = appState.zombieFile.fileIcon[file], let iconImage = fileIcon.map(Image.init(nsImage:)) {
|
if let fileSize = appState.zombieFile.fileSize[file], let fileSizeL = appState.zombieFile.fileSizeLogical[file], let fileIcon = appState.zombieFile.fileIcon[file], let iconImage = fileIcon.map(Image.init(nsImage:)) {
|
||||||
VStack {
|
VStack {
|
||||||
ZombieFileDetailsItem(size: fileSize, sizeL: fileSizeL, icon: iconImage, path: file, isSelected: self.binding(for: file))
|
ZombieFileDetailsItem(size: fileSize, sizeL: fileSizeL, icon: iconImage, path: file, memoizedFiles: $memoizedFiles, isSelected: self.binding(for: file))
|
||||||
.padding(.vertical, 5)
|
.padding(.vertical, 5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,6 +462,7 @@ struct ZombieView: View {
|
|||||||
|
|
||||||
struct ZombieFileDetailsItem: View {
|
struct ZombieFileDetailsItem: View {
|
||||||
@EnvironmentObject var appState: AppState
|
@EnvironmentObject var appState: AppState
|
||||||
|
@EnvironmentObject var fsm: FolderSettingsManager
|
||||||
@State private var isHovered = false
|
@State private var isHovered = false
|
||||||
@AppStorage("settings.general.sizeType") var sizeType: String = "Real"
|
@AppStorage("settings.general.sizeType") var sizeType: String = "Real"
|
||||||
@AppStorage("settings.interface.animationEnabled") private var animationEnabled: Bool = true
|
@AppStorage("settings.interface.animationEnabled") private var animationEnabled: Bool = true
|
||||||
@@ -469,6 +470,8 @@ struct ZombieFileDetailsItem: View {
|
|||||||
let sizeL: Int64?
|
let sizeL: Int64?
|
||||||
let icon: Image?
|
let icon: Image?
|
||||||
let path: URL
|
let path: URL
|
||||||
|
@Binding var memoizedFiles: [URL]
|
||||||
|
|
||||||
@Binding var isSelected: Bool
|
@Binding var isSelected: Bool
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -550,6 +553,12 @@ struct ZombieFileDetailsItem: View {
|
|||||||
Button("View in Finder") {
|
Button("View in Finder") {
|
||||||
NSWorkspace.shared.selectFile(path.path, inFileViewerRootedAtPath: path.deletingLastPathComponent().path)
|
NSWorkspace.shared.selectFile(path.path, inFileViewerRootedAtPath: path.deletingLastPathComponent().path)
|
||||||
}
|
}
|
||||||
|
Divider()
|
||||||
|
Button("Exclude") {
|
||||||
|
fsm.addPathZ(path.path)
|
||||||
|
memoizedFiles.removeAll { $0 == path }
|
||||||
|
}
|
||||||
|
.help("This adds the file/folder to the Exclusions list. Edit the exclusions list from Settings > Folders tab")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user