This commit is contained in:
Alin
2023-11-17 19:49:42 -07:00
parent 27b309a535
commit ee395b57aa
11 changed files with 129 additions and 118 deletions
+4 -4
View File
@@ -535,7 +535,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BK8443AXLU;
ENABLE_HARDENED_RUNTIME = YES;
@@ -552,7 +552,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.4;
MARKETING_VERSION = 1.5;
PRODUCT_BUNDLE_IDENTIFIER = com.alienator88.Pearcleaner;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -569,7 +569,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BK8443AXLU;
ENABLE_HARDENED_RUNTIME = YES;
@@ -586,7 +586,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.4;
MARKETING_VERSION = 1.5;
PRODUCT_BUNDLE_IDENTIFIER = com.alienator88.Pearcleaner;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
+2 -2
View File
@@ -12,7 +12,7 @@ let home = FileManager.default.homeDirectoryForCurrentUser.path
class AppState: ObservableObject
{
@Published var showFiles: Bool = false
// @Published var showFiles: Bool = false
@Published var appInfo: AppInfo
@Published var paths: [URL] = []
@Published var sortedApps: (userApps: [AppInfo], systemApps: [AppInfo]) = ([], [])
@@ -22,7 +22,7 @@ class AppState: ObservableObject
// @Published var currentMode = CurrentMode.regular
@Published var showAlert: Bool = false
@Published var sidebar: Bool = true
@Published var showPopover: Bool = false
// @Published var showPopover: Bool = false
@Published var isReminderVisible: Bool = false
@Published var releases = [Release]()
@Published var progressBar: (String, Double) = ("Ready", 0.0)
+7 -11
View File
@@ -186,8 +186,6 @@ func findPathsForApp(appState: AppState, appInfo: AppInfo) {
collection.insert(url, at: 0)
}
// Only search for extra files if not a webapp
// if !appInfo.webApp {
let fileManager = FileManager.default
let dispatchGroup = DispatchGroup()
let bundleComponents = appInfo.bundleIdentifier.components(separatedBy: ".")
@@ -200,6 +198,11 @@ func findPathsForApp(appState: AppState, appInfo: AppInfo) {
let locations = Locations()
for location in locations.apps.paths {
if !fileManager.fileExists(atPath: location) {
// print("Directory does not exist: \(location)")
continue
}
dispatchGroup.enter() // Enter the dispatch group
do {
@@ -217,7 +220,7 @@ func findPathsForApp(appState: AppState, appInfo: AppInfo) {
if appInfo.webApp {
if itemL.contains(bundleIdentifierL) {
if collection.contains(itemURL) {
return
continue
}
collection.append(itemURL)
}
@@ -265,20 +268,13 @@ func findPathsForApp(appState: AppState, appInfo: AppInfo) {
}
}
// }
// if appInfo.webApp {
// updateOnMain {
// appState.paths = collection
// appState.selectedItems = Set(collection)
// }
// }
}
}
// Move files to trash using applescript/Finder so it asks for user password if needed
func moveFilesToTrash(at fileURLs: [URL], completion: @escaping () -> Void = {}) {
updateOnBackground {
+12 -31
View File
@@ -78,8 +78,6 @@ struct LabeledDivider: View {
struct AnimatedSearchStyle: TextFieldStyle {
@State private var isHovered = false
@State var icon: Image?
@State var trash: Bool = false
@Binding var text: String
func _body(configuration: TextField<Self._Label>) -> some View {
@@ -87,51 +85,32 @@ struct AnimatedSearchStyle: TextFieldStyle {
HStack(spacing: 5) {
if isHovered || !text.isEmpty {
HStack(spacing: 5) {
if icon != nil {
icon
.foregroundColor(Color("AccentColor").opacity(0.5))
Image(systemName: "chevron.right")
.foregroundColor(Color("AccentColor").opacity(0.3))
.controlSize(.small)
}
configuration
.frame(maxWidth: 300)
.frame(width: 160)
.frame(height: 15)
.font(.title3)
.textFieldStyle(PlainTextFieldStyle())
if trash {
Image(systemName: "xmark")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 10, height: 10)
.padding(.trailing, 5)
.foregroundStyle(text.isEmpty ? Color.clear : (isHovered ? Color("AccentColor").opacity(0.8) : Color("AccentColor").opacity(0.5)))
.onTapGesture {
text = ""
}
}
}
} else {
Image(systemName: "magnifyingglass")
.foregroundColor(Color("AccentColor").opacity(0.5))
.padding(.trailing, 150)
.resizable()
.scaledToFit()
.frame(width: 18, height: 18)
.foregroundColor(isHovered ? Color("mode") : Color("mode").opacity(0.5))
}
}
.padding(6)
.padding(8)
.overlay(
Group {
if isHovered || !text.isEmpty {
RoundedRectangle(cornerRadius: 6)
.strokeBorder(Color("AccentColor").opacity(0.4), lineWidth: 1)
.strokeBorder(Color("mode").opacity(0.4), lineWidth: 1)
.allowsHitTesting(false)
}
}
)
.onHover { hovering in
withAnimation(Animation.easeIn(duration: 0.15)) {
withAnimation(Animation.easeInOut(duration: 0.4)) {
self.isHovered = hovering
}
}
@@ -139,6 +118,8 @@ struct AnimatedSearchStyle: TextFieldStyle {
}
struct SimpleSearchStyle: TextFieldStyle {
@State private var isHovered = false
@State var icon: Image?
+3 -3
View File
@@ -18,6 +18,7 @@ struct PearcleanerApp: App {
@AppStorage("displayMode") var displayMode: DisplayMode = .system
@AppStorage("settings.general.mini") private var mini: Bool = false
@State private var search = ""
@State private var showPopover: Bool = false
var body: some Scene {
@@ -25,10 +26,10 @@ struct PearcleanerApp: App {
Group {
if !mini {
AppListView(search: $search)
AppListView(search: $search, showPopover: $showPopover)
.frame(minWidth: 800, minHeight: 500)
} else {
MiniMode(search: $search)
MiniMode(search: $search, showPopover: $showPopover)
.frame(minWidth: 300, minHeight: 300)
}
@@ -78,7 +79,6 @@ struct PearcleanerApp: App {
}
.windowStyle(.hiddenTitleBar)
.windowToolbarStyle(.unified)
.windowResizability(.contentMinSize)
.commands {
AppCommands(appState: appState)
+4 -2
View File
@@ -11,10 +11,11 @@ import SwiftUI
struct AppListItems: View {
@EnvironmentObject var appState: AppState
// @Binding var reload: Bool
// @Binding var search: String
@Binding var search: String
@State private var isHovered = false
@Environment(\.colorScheme) var colorScheme
@AppStorage("settings.general.mini") private var mini: Bool = false
@Binding var showPopover: Bool
let appInfo: AppInfo
var isSelected: Bool {
@@ -93,11 +94,12 @@ struct AppListItems: View {
}
.onTapGesture {
updateOnMain {
appState.appInfo = .empty
appState.appInfo = appInfo
findPathsForApp(appState: appState, appInfo: appState.appInfo)
withAnimation(Animation.easeIn(duration: 0.4)) {
if mini {
appState.showPopover.toggle()
showPopover.toggle()
} else {
appState.currentView = .files
}
+18 -17
View File
@@ -16,6 +16,7 @@ struct AppListView: View {
@State private var showUsr: Bool = true
// @State private var sidebar: Bool = true
@State private var reload: Bool = false
@Binding var showPopover: Bool
var filteredUserApps: [AppInfo] {
if search.isEmpty {
@@ -56,20 +57,20 @@ struct AppListView: View {
HStack {
SearchBar(search: $search, reload: $reload)
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
// Refresh Apps list
reload.toggle()
let sortedApps = getSortedApps()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
appState.sortedApps.userApps = sortedApps.userApps
appState.sortedApps.systemApps = sortedApps.systemApps
reload.toggle()
}
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.triangle.2.circlepath", help: "Refresh app list", color: Color("mode")))
// Button("") {
// withAnimation(.easeInOut(duration: 0.5)) {
// // Refresh Apps list
// reload.toggle()
// let sortedApps = getSortedApps()
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
// appState.sortedApps.userApps = sortedApps.userApps
// appState.sortedApps.systemApps = sortedApps.systemApps
// reload.toggle()
// }
//
// }
// }
// .buttonStyle(SimpleButtonStyle(icon: "arrow.triangle.2.circlepath", help: "Refresh app list", color: Color("mode")))
}
}
.padding(.horizontal)
@@ -84,7 +85,7 @@ struct AppListView: View {
VStack {
Header(title: "User", count: filteredUserApps.count)
ForEach(filteredUserApps, id: \.self) { appInfo in
AppListItems(appInfo: appInfo)
AppListItems(search: $search, showPopover: $showPopover, appInfo: appInfo)
if appInfo != filteredUserApps.last {
Divider().padding(.horizontal, 5)
}
@@ -98,7 +99,7 @@ struct AppListView: View {
VStack {
Header(title: "System", count: filteredSystemApps.count)
ForEach(filteredSystemApps, id: \.self) { appInfo in
AppListItems(appInfo: appInfo)
AppListItems(search: $search, showPopover: $showPopover, appInfo: appInfo)
if appInfo != filteredSystemApps.last {
Divider().padding(.horizontal, 5)
}
@@ -135,7 +136,7 @@ struct AppListView: View {
AppDetailsEmptyView()
} else if appState.currentView == .files {
TopBar(reload: $reload)
FilesView()
FilesView(showPopover: $showPopover)
.id(appState.appInfo.id)
}
}
+14
View File
@@ -16,6 +16,7 @@ struct FilesView: View {
@State private var itemDetails: [(size: String, icon: Image?)] = []
@AppStorage("settings.general.mini") private var mini: Bool = false
@Environment(\.colorScheme) var colorScheme
@Binding var showPopover: Bool
var body: some View {
VStack(alignment: .center) {
@@ -161,18 +162,28 @@ struct FilesView: View {
Task {
updateOnMain {
appState.appInfo = AppInfo.empty
if mini {
appState.currentView = .apps
showPopover = false
} else {
appState.currentView = .empty
}
}
let selectedItemsArray = Array(appState.selectedItems).filter { !$0.path.contains(".Trash") }
killApp(appId: appState.appInfo.bundleIdentifier) {
moveFilesToTrash(at: selectedItemsArray) {
withAnimation {
updateOnMain {
appState.isReminderVisible.toggle()
}
}
refreshAppList(appState.appInfo)
}
}
}
}
.disabled(appState.selectedItems.isEmpty)
.buttonStyle(WindowActionButton(action: .accept))
@@ -230,11 +241,14 @@ struct FilesView: View {
func refreshAppList(_ appInfo: AppInfo) {
let sortedApps = getSortedApps()
updateOnMain {
appState.sortedApps.userApps = []
appState.sortedApps.systemApps = []
appState.sortedApps.userApps = sortedApps.userApps
appState.sortedApps.systemApps = sortedApps.systemApps
}
}
}
+11 -8
View File
@@ -16,7 +16,7 @@ struct MiniMode: View {
@State private var showUsr: Bool = true
@State private var reload: Bool = false
@AppStorage("settings.general.glass") private var glass: Bool = false
@Binding var showPopover: Bool
var body: some View {
@@ -30,11 +30,11 @@ struct MiniMode: View {
MiniEmptyView()
} else if appState.currentView == .files {
TopBarMini(reload: $reload, search: $search)
FilesView()
FilesView(showPopover: $showPopover)
.id(appState.appInfo.id)
} else if appState.currentView == .apps {
TopBarMini(reload: $reload, search: $search)
MiniAppView(search: $search, reload: $reload)
MiniAppView(search: $search, reload: $reload, showPopover: $showPopover)
}
}
// .padding(.leading, appState.sidebar ? 0 : 10)
@@ -84,15 +84,17 @@ struct MiniEmptyView: View {
if appState.isReminderVisible {
Text("CMD + Z to undo")
.font(.title2)
.foregroundStyle(Color("AccentColor").opacity(0.5))
.foregroundStyle(Color("mode").opacity(0.5))
.fontWeight(.medium)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
withAnimation {
updateOnMain {
appState.isReminderVisible = false
}
}
}
}
Spacer()
}
@@ -115,6 +117,7 @@ struct MiniAppView: View {
@State private var showUsr: Bool = true
@Binding var reload: Bool
@AppStorage("settings.general.mini") private var mini: Bool = false
@Binding var showPopover: Bool
var body: some View {
@@ -155,7 +158,7 @@ struct MiniAppView: View {
VStack {
Header(title: "User", count: filteredUserApps.count)
ForEach(filteredUserApps, id: \.self) { appInfo in
AppListItems(appInfo: appInfo)
AppListItems(search: $search, showPopover: $showPopover, appInfo: appInfo)
if appInfo != filteredUserApps.last {
Divider().padding(.horizontal, 5)
}
@@ -168,7 +171,7 @@ struct MiniAppView: View {
VStack {
Header(title: "System", count: filteredSystemApps.count)
ForEach(filteredSystemApps, id: \.self) { appInfo in
AppListItems(appInfo: appInfo)
AppListItems(search: $search, showPopover: $showPopover, appInfo: appInfo)
if appInfo != filteredSystemApps.last {
Divider().padding(.horizontal, 5)
}
@@ -190,9 +193,9 @@ struct MiniAppView: View {
}
}
.transition(.move(edge: .leading))
.popover(isPresented: $appState.showPopover, arrowEdge: .trailing) {
.popover(isPresented: $showPopover, arrowEdge: .trailing) {
VStack {
FilesView()
FilesView(showPopover: $showPopover)
.id(appState.appInfo.id)
}
.background(
+17 -13
View File
@@ -22,20 +22,10 @@ struct TopBar: View {
Spacer()
if appState.currentView != .empty {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.app", help: "Drop", color: Color("mode")))
}
if appState.isReminderVisible {
Text("CMD + Z to undo")
.font(.title2)
.foregroundStyle(Color("AccentColor").opacity(0.5))
.foregroundStyle(Color("mode").opacity(0.5))
.fontWeight(.medium)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
@@ -48,6 +38,20 @@ struct TopBar: View {
Spacer()
if appState.currentView != .empty {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.app", help: "Drop", color: Color("mode")))
}
// Spacer()
// if sentinel {
@@ -60,7 +64,7 @@ struct TopBar: View {
}
.padding(.horizontal, 20)
.padding(.top, 20)
.padding(.horizontal, 5)
.padding(.top, 10)
}
}
+18 -8
View File
@@ -27,11 +27,11 @@ struct TopBarMini: View {
SearchBarMini(search: $search, reload: $reload)
// .frame(width: 150)
.offset(x: 20)
.padding(.horizontal, 30)
// .offset(x: 20)
// .padding(.horizontal, 30)
// .padding(.top, 5)
Spacer()
// Spacer() //////////////
// Button("") {
// withAnimation(.easeInOut(duration: 0.5)) {
@@ -54,39 +54,48 @@ struct TopBarMini: View {
if appState.currentView == .apps {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
updateOnMain {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
}
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.app", help: "Drop", color: Color("mode")))
} else if appState.currentView == .empty {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
updateOnMain {
appState.currentView = .apps
}
}
}
.buttonStyle(SimpleButtonStyle(icon: "list.triangle", help: "Apps", color: Color("mode")))
} else if appState.currentView == .files {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
updateOnMain {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
}
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.app", help: "Drop", color: Color("mode")))
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
updateOnMain {
appState.currentView = .apps
}
}
}
.buttonStyle(SimpleButtonStyle(icon: "list.triangle", help: "Apps", color: Color("mode")))
}
}
.padding(.horizontal, 10)
.padding(.top, 10)
.padding(.bottom, 15)
.padding(.horizontal, 5)
.padding(.top, 5)
.padding(.bottom, 10)
}
}
@@ -98,8 +107,9 @@ struct SearchBarMini: View {
var body: some View {
HStack {
TextField("Search", text: $search)
.textFieldStyle(SimpleSearchStyle(trash: true, reload: $reload, text: $search))
.textFieldStyle(AnimatedSearchStyle(text: $search))
// .textFieldStyle(SimpleSearchStyle(trash: true, reload: $reload, text: $search))
}
.frame(height: 20)
// .frame(height: 20)
}
}