This commit is contained in:
Alin
2024-03-19 16:21:01 -06:00
parent 2318949caf
commit a55396cdaa
15 changed files with 227 additions and 152 deletions
+4 -4
View File
@@ -559,7 +559,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 25;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BK8443AXLU;
@@ -577,7 +577,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 3.2.0;
MARKETING_VERSION = 3.2.1;
PRODUCT_BUNDLE_IDENTIFIER = com.alienator88.Pearcleaner;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -594,7 +594,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 24;
CURRENT_PROJECT_VERSION = 25;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BK8443AXLU;
@@ -612,7 +612,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 3.2.0;
MARKETING_VERSION = 3.2.1;
PRODUCT_BUNDLE_IDENTIFIER = com.alienator88.Pearcleaner;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
+2 -2
View File
@@ -34,7 +34,7 @@ class DeeplinkManager {
if let path = queryItems.first(where: { $0.name == DeepLinkConstants.query })?.value {
let pathURL = URL(fileURLWithPath: path)
let appInfo = getAppInfo(atPath: pathURL)
showAppInFiles(appInfo: appInfo!, mini: mini, appState: appState, locations: locations, showPopover: $showPopover)
showAppInFiles(appInfo: appInfo!, appState: appState, locations: locations, showPopover: $showPopover)
} else {
printOS("No path query parameter found in the URL")
}
@@ -46,7 +46,7 @@ class DeeplinkManager {
func handleAppBundle(url: URL, appState: AppState, locations: Locations) {
let appInfo = getAppInfo(atPath: url)
showAppInFiles(appInfo: appInfo!, mini: mini, appState: appState, locations: locations, showPopover: $showPopover)
showAppInFiles(appInfo: appInfo!, appState: appState, locations: locations, showPopover: $showPopover)
}
}
+9 -14
View File
@@ -471,7 +471,7 @@ func loadAllPaths(allApps: [AppInfo], appState: AppState, locations: Locations,
// Load item in Files view
func showAppInFiles(appInfo: AppInfo, mini: Bool, appState: AppState, locations: Locations, showPopover: Binding<Bool>) {
func showAppInFiles(appInfo: AppInfo, appState: AppState, locations: Locations, showPopover: Binding<Bool>) {
showPopover.wrappedValue = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
updateOnMain {
@@ -481,23 +481,15 @@ func showAppInFiles(appInfo: AppInfo, mini: Bool, appState: AppState, locations:
appState.appInfo = storedAppInfo
appState.selectedItems = Set(storedAppInfo.files)
withAnimation(Animation.easeIn(duration: 0.4)) {
if mini {
appState.currentView = .files
showPopover.wrappedValue.toggle()
} else {
appState.currentView = .files
}
appState.currentView = .files
showPopover.wrappedValue.toggle()
}
} else {
// Handle the case where the appInfo is not found in the store
withAnimation(Animation.easeIn(duration: 0.4)) {
appState.showProgress = true
if mini {
appState.currentView = .files
showPopover.wrappedValue.toggle()
} else {
appState.currentView = .files
}
appState.currentView = .files
showPopover.wrappedValue.toggle()
}
appState.appInfo = appInfo
findPathsForApp(appInfo: appInfo, appState: appState, locations: locations) {
@@ -640,7 +632,9 @@ func reversePathsSearch(appState: AppState, locations: Locations, completion: @e
// Move files to trash using applescript/Finder so it asks for user password if needed
func moveFilesToTrash(at fileURLs: [URL], completion: @escaping () -> Void = {}) {
@AppStorage("settings.sentinel.enable") var sentinel: Bool = false
if sentinel {
launchctl(load: false)
}
updateOnBackground {
let posixFiles = fileURLs.map { "POSIX file \"\($0.path)\", " }.joined().dropLast(3)
let scriptSource = """
@@ -660,6 +654,7 @@ func moveFilesToTrash(at fileURLs: [URL], completion: @escaping () -> Void = {})
completion()
}
}
}
+7 -4
View File
@@ -11,15 +11,15 @@ import SwiftUI
struct SimpleButtonStyle: ButtonStyle {
@State private var hovered = false
let icon: String
let label: String?
let help: String
let color: Color
let shield: Bool?
init(icon: String, help: String, color: Color, shield: Bool? = nil) {
init(icon: String, label: String? = "", help: String, color: Color) {
self.icon = icon
self.label = label
self.help = help
self.color = color
self.shield = shield
}
func makeBody(configuration: Self.Configuration) -> some View {
@@ -28,8 +28,11 @@ struct SimpleButtonStyle: ButtonStyle {
.resizable()
.scaledToFit()
.frame(width: 20)
.foregroundColor(hovered ? color : color.opacity(0.5))
if label != "" {
Text(label!)
}
}
.foregroundColor(hovered ? color : color.opacity(0.5))
.padding(5)
.onHover { hovering in
withAnimation() {
+10 -9
View File
@@ -34,15 +34,15 @@ func updateOnBackground(_ updates: @escaping () -> Void) {
// Resize window
func resizeWindow(width: CGFloat, height: CGFloat) {
if let window = NSApplication.shared.windows.first {
let newSize = NSSize(width: width, height: height)
window.setContentSize(newSize)
}
}
//func resizeWindow(width: CGFloat, height: CGFloat) {
// if let window = NSApplication.shared.windows.first {
// let newSize = NSSize(width: width, height: height)
// window.setContentSize(newSize)
// }
//}
func resizeWindowAuto(windowSettings: WindowSettings) {
if let window = NSApplication.shared.windows.first {
func resizeWindowAuto(windowSettings: WindowSettings, title: String) {
if let window = NSApplication.shared.windows.first(where: { $0.title == title }) {
let newSize = NSSize(width: windowSettings.loadWindowSettings().width, height: windowSettings.loadWindowSettings().height)
window.setContentSize(newSize)
}
@@ -168,7 +168,8 @@ func hasWindowOpen() -> Bool {
func findAndHideWindows(named titles: [String]) {
for title in titles {
if let window = NSApp.windows.first(where: { $0.title == title }) {
window.orderOut(nil)
// window.orderOut(nil)
window.close()
}
}
}
+11 -32
View File
@@ -110,6 +110,7 @@ struct PearcleanerApp: App {
MenuBarMiniAppView(search: $search, showPopover: $showPopover)
.environmentObject(locations)
.environmentObject(appState)
.preferredColorScheme(displayMode.colorScheme)
}, icon: selectedMenubarIcon)
}
@@ -181,49 +182,27 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
}
#if !DEBUG
func windowShouldClose(_ sender: NSWindow) -> Bool {
let menubarEnabled = UserDefaults.standard.bool(forKey: "settings.menubar.enabled")
// let alert = NSAlert.init()
// alert.addButton(withTitle: "Return")
// alert.addButton(withTitle: "Quit")
// alert.informativeText = "Quit or return to application?"
// let response = alert.runModal()
// if response == NSApplication.ModalResponse.alertFirstButtonReturn {
//#if !DEBUG
// func windowShouldClose(_ sender: NSWindow) -> Bool {
// let menubarEnabled = UserDefaults.standard.bool(forKey: "settings.menubar.enabled")
// if menubarEnabled {
// findAndHideWindows(named: ["Pearcleaner"])
// return false
// } else {
// NSApplication.shared.terminate(self)
// return true
// }
if menubarEnabled {
findAndHideWindows(named: ["Pearcleaner"])
return false
} else {
return true
}
}
#endif
// }
//#endif
func applicationDidFinishLaunching(_ notification: Notification) {
let menubarEnabled = UserDefaults.standard.bool(forKey: "settings.menubar.enabled")
// let dockEnabled = UserDefaults.standard.bool(forKey: "settings.dock.enabled")
if menubarEnabled {
#if !DEBUG
findAndHideWindows(named: ["Pearcleaner"])
// NSApp.windows.first?.close()
NSApplication.shared.setActivationPolicy(.accessory)
#endif
// if dockEnabled {
// NSApplication.shared.setActivationPolicy(.regular)
// } else {
// NSApplication.shared.setActivationPolicy(.accessory)
// }
}
// Link window to delegate
let mainWindow = NSApp.windows[0]
mainWindow.delegate = self
// Link window to delegate
// let mainWindow = NSApp.windows[0]
// mainWindow.delegate = self
}
+41 -14
View File
@@ -15,7 +15,6 @@ struct InterfaceSettingsTab: View {
@EnvironmentObject var locations: Locations
@State private var windowSettings = WindowSettings()
@AppStorage("settings.menubar.enabled") private var menubarEnabled: Bool = false
// @AppStorage("settings.dock.enabled") private var dockEnabled: Bool = false
@AppStorage("settings.general.mini") private var mini: Bool = false
@AppStorage("displayMode") var displayMode: DisplayMode = .system
@AppStorage("settings.general.glass") private var glass: Bool = true
@@ -57,6 +56,9 @@ struct InterfaceSettingsTab: View {
Toggle(isOn: $glass, label: {
})
.toggleStyle(.switch)
.onChange(of: glass) { newVal in
MenuBarExtraManager.shared.restartMenuBarExtra()
}
}
.padding(5)
.padding(.leading)
@@ -89,13 +91,17 @@ struct InterfaceSettingsTab: View {
displayMode.colorScheme = nil
if isDarkModeEnabled() {
displayMode.colorScheme = .dark
MenuBarExtraManager.shared.restartMenuBarExtra()
} else {
displayMode.colorScheme = .light
MenuBarExtraManager.shared.restartMenuBarExtra()
}
case "Dark":
displayMode.colorScheme = .dark
MenuBarExtraManager.shared.restartMenuBarExtra()
case "Light":
displayMode.colorScheme = .light
MenuBarExtraManager.shared.restartMenuBarExtra()
default:
break
}
@@ -135,19 +141,35 @@ struct InterfaceSettingsTab: View {
Toggle(isOn: $mini, label: {
})
.toggleStyle(.switch)
.disabled(menubarEnabled)
.help(menubarEnabled ? "Disabled when menubar icon is enabled" : "")
.onChange(of: mini) { newVal in
if mini {
appState.currentView = miniView ? .apps : .empty
showPopover = false
resizeWindowAuto(windowSettings: windowSettings)
} else {
resizeWindowAuto(windowSettings: windowSettings)
if appState.appInfo.appName.isEmpty {
appState.currentView = .empty
if mini {
appState.currentView = miniView ? .apps : .empty
showPopover = false
windowSettings.newWindow {
MiniMode(search: $search, showPopover: $showPopover)
.environmentObject(locations)
.environmentObject(appState)
.preferredColorScheme(displayMode.colorScheme)
}
resizeWindowAuto(windowSettings: windowSettings, title: "Pearcleaner")
} else {
appState.currentView = .files
if appState.appInfo.appName.isEmpty {
appState.currentView = .empty
} else {
appState.currentView = .files
}
windowSettings.newWindow {
RegularMode(search: $search, showPopover: $showPopover)
.environmentObject(locations)
.environmentObject(appState)
.preferredColorScheme(displayMode.colorScheme)
}
resizeWindowAuto(windowSettings: windowSettings, title: "Pearcleaner")
}
}
}
}
.padding(5)
@@ -229,7 +251,7 @@ struct InterfaceSettingsTab: View {
.font(.callout)
.foregroundStyle(.gray)
}
InfoButton(text: "When menubar icon is enabled, the main app window and dock icon will be hidden. You can still pop-out the main app window from the menubar icon temporarily if you'd like.", color: nil, label: "")
InfoButton(text: "When menubar icon is enabled, the main app window and dock icon will be disabled since the app will be put in accessory mode.", color: nil, label: "")
Spacer()
Toggle(isOn: $menubarEnabled, label: {
})
@@ -240,12 +262,13 @@ struct InterfaceSettingsTab: View {
MenuBarMiniAppView(search: $search, showPopover: $showPopover)
.environmentObject(locations)
.environmentObject(appState)
.preferredColorScheme(displayMode.colorScheme)
}, icon: selectedMenubarIcon)
NSApplication.shared.setActivationPolicy(.accessory)
findAndShowWindows(named: ["Pearcleaner", "Interface"])
findAndHideWindows(named: ["Pearcleaner"])
// findAndShowWindows(named: ["Pearcleaner", "Interface"])
} else {
MenuBarExtraManager.shared.removeMenuBarExtra()
// dockEnabled = true
NSApplication.shared.setActivationPolicy(.regular)
if !hasWindowOpen() {
if mini {
@@ -253,13 +276,17 @@ struct InterfaceSettingsTab: View {
MiniMode(search: $search, showPopover: $showPopover)
.environmentObject(locations)
.environmentObject(appState)
.preferredColorScheme(displayMode.colorScheme)
}
resizeWindowAuto(windowSettings: windowSettings, title: "Pearcleaner")
} else {
windowSettings.newWindow {
RegularMode(search: $search, showPopover: $showPopover)
.environmentObject(locations)
.environmentObject(appState)
.preferredColorScheme(displayMode.colorScheme)
}
resizeWindowAuto(windowSettings: windowSettings, title: "Pearcleaner")
}
}
+3 -3
View File
@@ -14,8 +14,8 @@ struct AppListItems: View {
@State private var isHovered = false
@State private var windowSettings = WindowSettings()
@Environment(\.colorScheme) var colorScheme
@AppStorage("settings.general.mini") private var mini: Bool = false
@AppStorage("settings.general.popover") private var popoverStay: Bool = true
// @AppStorage("settings.general.mini") private var mini: Bool = false
// @AppStorage("settings.general.popover") private var popoverStay: Bool = true
@AppStorage("displayMode") var displayMode: DisplayMode = .system
@Binding var showPopover: Bool
@EnvironmentObject var locations: Locations
@@ -110,7 +110,7 @@ struct AppListItems: View {
}
.onTapGesture {
withAnimation(Animation.easeInOut(duration: 0.4)) {
showAppInFiles(appInfo: appInfo, mini: mini, appState: appState, locations: locations, showPopover: $showPopover)
showAppInFiles(appInfo: appInfo, appState: appState, locations: locations, showPopover: $showPopover)
}
}
+7 -3
View File
@@ -16,9 +16,11 @@ struct FilesView: View {
@AppStorage("settings.sentinel.enable") private var sentinel: Bool = false
@AppStorage("settings.general.instant") var instantSearch: Bool = true
@AppStorage("settings.general.brew") private var brew: Bool = false
@AppStorage("settings.menubar.enabled") private var menubarEnabled: Bool = false
@Environment(\.colorScheme) var colorScheme
@Binding var showPopover: Bool
@Binding var search: String
var regularWin: Bool
@State private var selectedOption = "Default"
var body: some View {
@@ -38,7 +40,7 @@ struct FilesView: View {
.transition(.opacity)
} else {
// Titlebar
if mini {
if !regularWin {
HStack() {
Spacer()
@@ -192,7 +194,7 @@ struct FilesView: View {
updateOnMain {
// appState.appInfo = AppInfo.empty
search = ""
if mini {
if !regularWin {
appState.currentView = .apps
showPopover = false
} else {
@@ -200,7 +202,6 @@ struct FilesView: View {
}
}
var selectedItemsArray = Array(appState.selectedItems)
if let url = URL(string: appState.appInfo.path.absoluteString) {
let appFolderURL = appState.appInfo.path.absoluteString.contains("Wrapper") ? url.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent() : url.deletingLastPathComponent() // Get the immediate parent directory of regular and wrapped apps
@@ -220,6 +221,9 @@ struct FilesView: View {
appState.currentView = mini ? .apps : .empty
appState.isReminderVisible.toggle()
}
if sentinel {
launchctl(load: true)
}
}
// Remove app from app list
removeApp(appState: appState, withId: appState.appInfo.id)
+98 -41
View File
@@ -22,6 +22,7 @@ struct MenuBarMiniAppView: View {
@AppStorage("settings.general.glass") private var glass: Bool = true
@AppStorage("settings.general.popover") private var popoverStay: Bool = true
@Binding var showPopover: Bool
@State private var showMenu = false
var body: some View {
@@ -57,20 +58,11 @@ struct MenuBarMiniAppView: View {
AppsListView(search: $search, showPopover: $showPopover, filteredApps: filteredApps).padding(0)
HStack(spacing: 10) {
if #available(macOS 14.0, *) {
SettingsLink()
.buttonStyle(SimpleButtonStyle(icon: "gear", help: "Settings", color: Color("mode")))
} else {
Button("Settings") {
NSApp.sendAction(Selector(("showPreferencesWindow:")), to: NSApp.delegate, from: nil)
}
.buttonStyle(SimpleButtonStyle(icon: "gear", help: "Settings", color: Color("mode")))
}
Button("") {
Button("Leftover Files") {
showMenu = false
withAnimation(.easeInOut(duration: 0.5)) {
showPopover = false
updateOnMain {
updateOnMain() {
appState.appInfo = .empty
appState.selectedZombieItems = []
if appState.zombieFile.fileSize.keys.count == 0 {
@@ -91,34 +83,89 @@ struct MenuBarMiniAppView: View {
}
}
.buttonStyle(SimpleButtonStyle(icon: "clock.arrow.circlepath", help: "Leftover Files", color: Color("mode")))
.padding(.leading, 10)
SearchBarMiniBottom(search: $search)
// .padding(.leading, 20)
Button("Main") {
findAndShowWindows(named: ["Pearcleaner"])
// if mini {
// windowSettings.newWindow {
// MiniMode(search: $search, showPopover: $showPopover)
// .environmentObject(locations)
// .environmentObject(appState)
// }
// } else {
// windowSettings.newWindow {
// RegularMode(search: $search, showPopover: $showPopover)
// .environmentObject(locations)
// .environmentObject(appState)
// }
// }
Button("More") {
self.showMenu.toggle()
}
.buttonStyle(SimpleButtonStyle(icon: "macwindow.on.rectangle", help: "Pop Out Window", color: Color("mode")))
.padding(.trailing, 10)
.buttonStyle(SimpleButtonStyle(icon: "ellipsis.circle", help: "More", color: Color("mode")))
.popover(isPresented: $showMenu) {
VStack(alignment: .leading) {
Button("Kill") {
NSApp.terminate(nil)
if #available(macOS 14.0, *) {
SettingsLink{
Label("Settings", systemImage: "gear")
}
.buttonStyle(SimpleButtonStyle(icon: "gear", label: "Settings", help: "Settings", color: Color("mode")))
} else {
Button("Settings") {
NSApp.sendAction(Selector(("showPreferencesWindow:")), to: NSApp.delegate, from: nil)
showMenu = false
}
.buttonStyle(SimpleButtonStyle(icon: "gear", label: "Settings", help: "Settings", color: Color("mode")))
}
// Button("Leftover Files") {
// showMenu = false
// withAnimation(.easeInOut(duration: 0.5)) {
// showPopover = false
// updateOnMain() {
// appState.appInfo = .empty
// appState.selectedZombieItems = []
// if appState.zombieFile.fileSize.keys.count == 0 {
// appState.currentView = .zombie
// appState.showProgress.toggle()
// showPopover.toggle()
// if instantSearch {
// reversePathsSearch(appState: appState, locations: locations)
// } else {
// loadAllPaths(allApps: appState.sortedApps, appState: appState, locations: locations, reverseAddon: true)
// }
// } else {
// appState.currentView = .zombie
// showPopover.toggle()
// }
// }
//
// }
// }
// .buttonStyle(SimpleButtonStyle(icon: "clock.arrow.circlepath", label: "Leftover Files", help: "Leftover Files", color: Color("mode")))
Button("Quit") {
NSApp.terminate(nil)
}
.buttonStyle(SimpleButtonStyle(icon: "x.circle.fill", label: "Quit Pearcleaner", help: "Quit Pearcleaner", color: Color("mode")))
}
.padding()
.background(
Group {
if glass {
GlassEffect(material: .sidebar, blendingMode: .behindWindow)
.edgesIgnoringSafeArea(.all)
} else {
Rectangle()
.fill(Color("pop"))
.padding(-80)
}
}
)
}
.buttonStyle(SimpleButtonStyle(icon: "x.circle.fill", help: "Quit", color: Color("mode")))
}
.padding(.horizontal)
// .padding(.horizontal)
}
.padding(.vertical, 5)
@@ -136,30 +183,40 @@ struct MenuBarMiniAppView: View {
GlassEffect(material: .sidebar, blendingMode: .behindWindow)
.edgesIgnoringSafeArea(.all)
} else {
Color("pop")
Rectangle()
.fill(Color("pop"))
.padding(-80)
}
}
)
.transition(.opacity)
.popover(isPresented: $showPopover, arrowEdge: .trailing) {
.popover(isPresented: $showPopover, arrowEdge: .leading) {
VStack {
if appState.currentView == .files {
FilesView(showPopover: $showPopover, search: $search)
FilesView(showPopover: $showPopover, search: $search, regularWin: false)
.id(appState.appInfo.id)
} else if appState.currentView == .zombie {
ZombieView(showPopover: $showPopover, search: $search)
ZombieView(showPopover: $showPopover, search: $search, regularWin: false)
.id(appState.appInfo.id)
}
}
.interactiveDismissDisabled(popoverStay)
.background(
Rectangle()
.fill(Color("pop"))
.padding(-80)
Group {
if glass {
GlassEffect(material: .sidebar, blendingMode: .behindWindow)
.edgesIgnoringSafeArea(.all)
} else {
Rectangle()
.fill(Color("pop"))
.padding(-80)
}
}
)
.frame(width: 650, height: 550)
.frame(width: 650, height: 500)
}
}
+2 -2
View File
@@ -39,10 +39,10 @@ struct MiniMode: View {
.popover(isPresented: $showPopover, arrowEdge: .trailing) {
VStack {
if appState.currentView == .files {
FilesView(showPopover: $showPopover, search: $search)
FilesView(showPopover: $showPopover, search: $search, regularWin: false)
.id(appState.appInfo.id)
} else if appState.currentView == .zombie {
ZombieView(showPopover: $showPopover, search: $search)
ZombieView(showPopover: $showPopover, search: $search, regularWin: false)
.id(appState.appInfo.id)
}
+2 -2
View File
@@ -93,11 +93,11 @@ struct RegularMode: View {
AppDetailsEmptyView(showPopover: $showPopover)
} else if appState.currentView == .files {
TopBar(showPopover: $showPopover)
FilesView(showPopover: $showPopover, search: $search)
FilesView(showPopover: $showPopover, search: $search, regularWin: true)
.id(appState.appInfo.id)
} else if appState.currentView == .zombie {
TopBar(showPopover: $showPopover)
ZombieView(showPopover: $showPopover, search: $search)
ZombieView(showPopover: $showPopover, search: $search, regularWin: true)
.id(appState.appInfo.id)
}
}
+4 -11
View File
@@ -15,23 +15,16 @@ struct ZombieView: View {
@AppStorage("settings.general.mini") private var mini: Bool = false
@AppStorage("settings.sentinel.enable") private var sentinel: Bool = false
@AppStorage("settings.general.instant") private var instantSearch: Bool = true
@AppStorage("settings.menubar.enabled") private var menubarEnabled: Bool = false
@Environment(\.colorScheme) var colorScheme
@Binding var showPopover: Bool
@Binding var search: String
@State private var searchZ: String = ""
@State private var selectedOption = "Default"
var regularWin: Bool
var body: some View {
// let filteredAndSortedFiles: [URL] = {
// let files = appState.zombieFile.fileSize.keys.filter { url in
// searchZ.isEmpty || url.lastPathComponent.localizedCaseInsensitiveContains(searchZ)
// }
//
// return selectedOption == "Default" ?
// files.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) :
// files.sorted(by: { appState.zombieFile.fileSize[$0, default: 0] > appState.zombieFile.fileSize[$1, default: 0] })
// }()
let filteredAndSortedFiles: ([URL], Int64) = {
let filteredFiles = appState.zombieFile.fileSize.filter { (url, _) in
searchZ.isEmpty || url.lastPathComponent.localizedCaseInsensitiveContains(searchZ)
@@ -68,7 +61,7 @@ struct ZombieView: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
// Titlebar
if mini {
if !regularWin {
HStack(spacing: 0) {
Spacer()
@@ -188,7 +181,7 @@ struct ZombieView: View {
updateOnMain {
appState.zombieFile = .empty
search = ""
if mini {
if !regularWin {
appState.currentView = .apps
showPopover = false
} else {
+21 -8
View File
@@ -12,15 +12,22 @@ class MenuBarExtraManager {
static let shared = MenuBarExtraManager()
private var statusItem: NSStatusItem?
private var popover = NSPopover()
// Store the last view and icon for restart
private var lastView: (() -> AnyView)?
private var lastIcon: String?
func addMenuBarExtra<V: View>(withView view: @escaping () -> V, icon: String) {
guard statusItem == nil else { return }
// Remember the last view and icon
lastView = { AnyView(view()) }
lastIcon = icon
// Initialize the status item
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
// Set up the status item's button
if let button = statusItem?.button {
if let button = statusItem?.button{
if NSImage(systemSymbolName: icon, accessibilityDescription: nil) != nil {
button.image = NSImage(systemSymbolName: icon, accessibilityDescription: "Pearcleaner")
} else {
@@ -29,6 +36,7 @@ class MenuBarExtraManager {
}
button.action = #selector(togglePopover(_:))
button.target = self
button.sendAction(on: [.leftMouseDown, .rightMouseDown])
}
// Set up the popover
@@ -54,13 +62,16 @@ class MenuBarExtraManager {
}
}
// func getStatus() -> Bool {
// if let item = statusItem {
// return true
// } else {
// return false
// }
// }
func restartMenuBarExtra() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.removeMenuBarExtra()
// Ensure the last view and icon are available before re-adding
if let lastView = self.lastView, let lastIcon = self.lastIcon {
self.addMenuBarExtra(withView: lastView, icon: lastIcon)
}
}
}
@objc func togglePopover(_ sender: AnyObject?) {
if let button = statusItem?.button {
@@ -71,4 +82,6 @@ class MenuBarExtraManager {
}
}
}
}
+4 -1
View File
@@ -35,6 +35,7 @@ class WindowSettings {
}
func newWindow<V: View>(withView view: @escaping () -> V) {
findAndHideWindows(named: ["Pearcleaner"])
let contentView = view
let frame = self.loadWindowSettings()
let newWindow = NSWindow(
@@ -44,7 +45,9 @@ class WindowSettings {
newWindow.titlebarAppearsTransparent = true
newWindow.isMovableByWindowBackground = true
newWindow.center()
newWindow.setFrameAutosaveName("Main Window")
newWindow.title = "Pearcleaner"
newWindow.titleVisibility = .hidden
newWindow.setFrameAutosaveName("Pearcleaner")
newWindow.contentView = NSHostingView(rootView: contentView())
// self.window = newWindow
self.windows.append(newWindow)