Skip to content

Commit

Permalink
v4.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
alienator88 committed Nov 18, 2024
1 parent 0b03824 commit 251ce1a
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 47 deletions.
25 changes: 21 additions & 4 deletions Pearcleaner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
C7A27E812AFD7C4600166168 /* com.alienator88.PearcleanerSentinel.plist in Resources */ = {isa = PBXBuildFile; fileRef = C7A27E802AFD7C4600166168 /* com.alienator88.PearcleanerSentinel.plist */; };
C7A2AE5D2B9644F300161540 /* FileWatcher in Frameworks */ = {isa = PBXBuildFile; productRef = C7A2AE5C2B9644F300161540 /* FileWatcher */; };
C7A6DBF12C9DD27200CFA042 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C7A6DBF02C9DD27200CFA042 /* Assets.xcassets */; };
C7B0FE392CEBB14500083982 /* Fuse in Frameworks */ = {isa = PBXBuildFile; productRef = C7B0FE382CEBB14500083982 /* Fuse */; };
C7BE91A82C9E37AB009FA129 /* FinderOpen.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C78121632BC892A000BE06BD /* FinderOpen.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
C7CF47242B3B3F1700979C5F /* WindowSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7CF47232B3B3F1700979C5F /* WindowSettings.swift */; };
C7D31D4A2AFEB26700C7ED9E /* AppListItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7D31D492AFEB26700C7ED9E /* AppListItems.swift */; };
Expand Down Expand Up @@ -157,6 +158,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C7B0FE392CEBB14500083982 /* Fuse in Frameworks */,
C76EDCD62C45DC82000CF29D /* AlinFoundation in Frameworks */,
C7736E4F2C49A44200917293 /* AlinFoundation in Frameworks */,
);
Expand Down Expand Up @@ -338,6 +340,7 @@
packageProductDependencies = (
C76EDCD52C45DC82000CF29D /* AlinFoundation */,
C7736E4E2C49A44200917293 /* AlinFoundation */,
C7B0FE382CEBB14500083982 /* Fuse */,
);
productName = PeakPurge;
productReference = C77B90002AF18E2E009CC655 /* Pearcleaner.app */;
Expand Down Expand Up @@ -399,6 +402,7 @@
packageReferences = (
C7A2AE5B2B9644DA00161540 /* XCRemoteSwiftPackageReference "FileWatcher" */,
C7736E4D2C49A44200917293 /* XCRemoteSwiftPackageReference "AlinFoundation" */,
C7B0FE372CEBB14500083982 /* XCRemoteSwiftPackageReference "fuse-swift" */,
);
productRefGroup = C77B90012AF18E2E009CC655 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -549,8 +553,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUILD = 65;
APP_VERSION = 3.9.3;
APP_BUILD = 66;
APP_VERSION = 4.0.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
Expand Down Expand Up @@ -621,8 +625,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUILD = 65;
APP_VERSION = 3.9.3;
APP_BUILD = 66;
APP_VERSION = 4.0.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
Expand Down Expand Up @@ -893,6 +897,14 @@
minimumVersion = 0.2.3;
};
};
C7B0FE372CEBB14500083982 /* XCRemoteSwiftPackageReference "fuse-swift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/krisk/fuse-swift";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.4.0;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand All @@ -910,6 +922,11 @@
package = C7A2AE5B2B9644DA00161540 /* XCRemoteSwiftPackageReference "FileWatcher" */;
productName = FileWatcher;
};
C7B0FE382CEBB14500083982 /* Fuse */ = {
isa = XCSwiftPackageProductDependency;
package = C7B0FE372CEBB14500083982 /* XCRemoteSwiftPackageReference "fuse-swift" */;
productName = Fuse;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = C77B8FF82AF18E2E009CC655 /* Project object */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"originHash" : "bebe4a176f4f3b9e625a60cb3048363d2aeb03aa06dabf97821c3b73b1c5f149",
"originHash" : "86b6bd342d4a4f0d825ea3c6c6cba6a6c6f5e9c0bd3788dba02512e688f9fbc4",
"pins" : [
{
"identity" : "alinfoundation",
"kind" : "remoteSourceControl",
"location" : "https://github.com/alienator88/AlinFoundation",
"state" : {
"branch" : "main",
"revision" : "320a4ad2126e1ceb5d6073337063dcbd37c1242d"
"revision" : "3480d1d1d0a1f540b8c4668dd1fac1d1ffab2260"
}
},
{
Expand All @@ -18,6 +18,15 @@
"revision" : "e67c2a99502eade343fecabeca8c57e749a55b59",
"version" : "0.2.3"
}
},
{
"identity" : "fuse-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/krisk/fuse-swift",
"state" : {
"revision" : "26ba868691b2d8b7bf2b1322951eb591be70ccca",
"version" : "1.4.0"
}
}
],
"version" : 3
Expand Down
14 changes: 10 additions & 4 deletions Pearcleaner/Logic/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,19 @@ enum CurrentPage:Int, CaseIterable, Identifiable

var id: Int { rawValue }

var title: String {
var details: (title: String, icon: String) {
switch self {
case .applications: return String(localized: "Applications")
case .orphans: return String(localized: "Orphaned Files")
case .development: return String(localized: "Development")
case .applications:
return (String(localized: "Applications"), "square.grid.3x3.fill.square")
case .orphans:
return (String(localized: "Orphaned Files"), "doc.text.magnifyingglass")
case .development:
return (String(localized: "Development"), "hammer.circle")
}
}

var title: String { details.title }
var icon: String { details.icon }
}

enum SortOption:Int, CaseIterable, Identifiable {
Expand Down
13 changes: 2 additions & 11 deletions Pearcleaner/Logic/Logic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ func getSortedApps(paths: [String]) -> [AppInfo] {
let appURLs = try fileManager.contentsOfDirectory(at: URL(fileURLWithPath: directoryPath), includingPropertiesForKeys: nil, options: [])

for appURL in appURLs {
if appURL.pathExtension == "app" && !isRestricted(atPath: appURL) {
if appURL.pathExtension == "app" && !isRestricted(atPath: appURL) &&
!appURL.isSymlink() {
// Add the path to the array
apps.append(appURL)
} else if appURL.hasDirectoryPath {
Expand All @@ -37,8 +38,6 @@ func getSortedApps(paths: [String]) -> [AppInfo] {
// Collect system applications
paths.forEach { collectAppPaths(at: $0) }

// let startTime = Date()

// Convert collected paths to string format for metadata query
let combinedPaths = apps.map { $0.path }

Expand All @@ -64,14 +63,6 @@ func getSortedApps(paths: [String]) -> [AppInfo] {
// Sort apps by display name
let sortedApps = appInfos.sorted { $0.appName.lowercased() < $1.appName.lowercased() }

// Get app info and sort
// let sortedApps = apps
// .compactMap { AppInfoFetcher.getAppInfo(atPath: $0) }


// let elapsedTime = Date().timeIntervalSince(startTime)
// print("Time taken for mdls metadata extraction: \(elapsedTime) seconds")

return sortedApps
}

Expand Down
77 changes: 77 additions & 0 deletions Pearcleaner/Logic/Styles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,80 @@ struct GlowGradientButton: View {
)
}
}



struct CustomPickerButton: View {
// Selected option binding to allow external state management
@Binding var selectedOption: CurrentPage
@Binding var isExpanded: Bool
@AppStorage("settings.interface.animationEnabled") private var animationEnabled: Bool = true

// Options array with names and icons
let options: [CurrentPage]

// Action callback when an option is selected
var onSelect: ((String) -> Void)?

// @State private var isExpanded: Bool = false

var body: some View {
Button(action: {
withAnimation(Animation.spring(duration: animationEnabled ? 0.35 : 0)) {
isExpanded.toggle()
}
}) {
ZStack {
// Background and overlay styling
VStack {
if isExpanded {
// Expanded menu with selectable options
VStack(alignment: .leading, spacing: 10) {
ForEach(options, id: \.title) { option in
Button(action: {
selectedOption = option // Update selected option
onSelect?(option.title) // Call the selection handler
withAnimation {
isExpanded = false
}
}) {
HStack {
Image(systemName: option.icon)
Text(option.title)
}
}
.buttonStyle(.plain)
}
}
} else {
// Display the selected option when collapsed
HStack {
Image(systemName: selectedOption.icon)
Text(selectedOption.title)
}
}
}
.padding(isExpanded ? 10 : 8)
// .background(
// ZStack {
// LinearGradient(
// colors: [Color.green, Color.orange],
// startPoint: .topLeading,
// endPoint: .bottomTrailing
// ) // Gradient layer
// .clipShape(RoundedRectangle(cornerRadius: 8)) // Match shape to material
// .overlay(.ultraThinMaterial) // Translucent material over gradient
// }
// )
.background(.ultraThinMaterial)
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.strokeBorder(Color.secondary.opacity(0.5), lineWidth: 0.6)
)
.transition(.scale)
}
}
.buttonStyle(.plain)
}
}
10 changes: 10 additions & 0 deletions Pearcleaner/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@
}
}
}
},
"Add file/folder from clipboard" : {

},
"Add files or folders that will be ignored when searching for orphaned files. Click a path to remove it from the list." : {
"extractionState" : "manual",
Expand Down Expand Up @@ -469,6 +472,9 @@
}
}
}
},
"Add folder from clipboard" : {

},
"Add/Save" : {
"extractionState" : "manual",
Expand Down Expand Up @@ -1827,6 +1833,7 @@
}
},
"Development Environments" : {
"extractionState" : "stale",
"localizations" : {
"zh-Hant" : {
"stringUnit" : {
Expand All @@ -1835,6 +1842,9 @@
}
}
}
},
"Development Environments (Beta)" : {

},
"Disabled when menubar icon is enabled" : {
"extractionState" : "manual",
Expand Down
45 changes: 45 additions & 0 deletions Pearcleaner/Settings/Folders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,17 @@ struct FolderSettingsTab: View {
HStack {
Spacer()
Text("Drop folders above or click to add").opacity(0.5)

Button {
selectFolder()
} label: { EmptyView() }
.buttonStyle(SimpleButtonStyle(icon: "plus.circle", help: String(localized: "Add folder"), size: 16, rotate: true))

Button {
clipboardAdd()
} label: { EmptyView() }
.buttonStyle(SimpleButtonStyle(icon: "document.on.clipboard", help: String(localized: "Add folder from clipboard"), size: 16, rotate: false))

Spacer()
}
}
Expand Down Expand Up @@ -192,6 +199,12 @@ struct FolderSettingsTab: View {
selectFilesFoldersZ()
} label: { EmptyView() }
.buttonStyle(SimpleButtonStyle(icon: "plus.circle", help: String(localized: "Add file/folder"), size: 16, rotate: true))

Button {
clipboardAdd(zombie: true)
} label: { EmptyView() }
.buttonStyle(SimpleButtonStyle(icon: "document.on.clipboard", help: String(localized: "Add file/folder from clipboard"), size: 16, rotate: false))

Spacer()
}
}
Expand Down Expand Up @@ -240,6 +253,38 @@ struct FolderSettingsTab: View {
}
}

private func clipboardAdd(zombie: Bool = false) {
let pasteboard = NSPasteboard.general

// Check for file URL first
if let fileURL = pasteboard.propertyList(forType: .fileURL) as? String,
let folderURL = URL(string: fileURL) {
processClipboardPath(folderURL.path, zombie: zombie)
}
// Fallback to string-based path
else if let clipboardString = pasteboard.string(forType: .string) {
processClipboardPath(clipboardString, zombie: zombie)
} else {
printOS("FSM: Clipboard does not contain a valid path or file URL")
}
}

// Helper function to process the extracted path
private func processClipboardPath(_ path: String, zombie: Bool) {
let fileManager = FileManager.default
var isDir: ObjCBool = false

if fileManager.fileExists(atPath: path, isDirectory: &isDir) {
if zombie || isDir.boolValue {
zombie ? fsm.addPathZ(path) : fsm.addPath(path)
} else {
printOS("FSM: Clipboard content is not a directory and zombie mode is disabled")
}
} else {
printOS("FSM: Clipboard content is not a valid path")
}
}

}


Expand Down
17 changes: 10 additions & 7 deletions Pearcleaner/Views/AppSearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import SwiftUI
import AlinFoundation
import Fuse

struct AppSearchView: View {
@EnvironmentObject var appState: AppState
Expand Down Expand Up @@ -222,7 +223,15 @@ struct AppSearchView: View {
if search.isEmpty {
apps = appState.sortedApps
} else {
apps = appState.sortedApps.filter { $0.appName.localizedCaseInsensitiveContains(search) }
let fuse = Fuse()
apps = appState.sortedApps.filter { app in
if app.appName.localizedCaseInsensitiveContains(search) {
return true
}
let result = fuse.search(search, in: app.appName)
return result?.score ?? 1.0 < 0.5 // Adjust threshold as needed (lower = stricter)
}
// apps = appState.sortedApps.filter { $0.appName.localizedCaseInsensitiveContains(search) }
}

// Sort based on the selected option
Expand All @@ -241,12 +250,6 @@ struct AppSearchView: View {
return apps.sorted { ($0.lastUsedDate ?? Date.distantPast) > ($1.lastUsedDate ?? Date.distantPast) }
}

// switch selectedSortAlpha {
// case true:
// return apps.sorted { $0.appName.replacingOccurrences(of: ".", with: "").lowercased() < $1.appName.replacingOccurrences(of: ".", with: "").lowercased() }
// case false:
// return apps.sorted { $0.bundleSize > $1.bundleSize }
// }
}

}
Expand Down
Loading

0 comments on commit 251ce1a

Please sign in to comment.