This commit is contained in:
Alin
2024-02-14 18:09:43 -07:00
parent fd583b6676
commit 17a81343aa
15 changed files with 423 additions and 231 deletions
+4 -4
View File
@@ -543,7 +543,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 17;
CURRENT_PROJECT_VERSION = 18;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BK8443AXLU;
@@ -561,7 +561,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 2.6;
MARKETING_VERSION = 2.7;
PRODUCT_BUNDLE_IDENTIFIER = com.alienator88.Pearcleaner;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -578,7 +578,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 17;
CURRENT_PROJECT_VERSION = 18;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BK8443AXLU;
@@ -596,7 +596,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 2.6;
MARKETING_VERSION = 2.7;
PRODUCT_BUNDLE_IDENTIFIER = com.alienator88.Pearcleaner;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
+29 -29
View File
@@ -45,35 +45,35 @@ class AppState: ObservableObject
}
class ProgressManager: ObservableObject {
@Published var progress: Double = 0.0
@Published var total: Double = 0.0
@Published var status: String = "Ready"
func setTotal(_ total: Double) {
DispatchQueue.main.async {
self.total = total
}
}
func updateProgress() {
DispatchQueue.main.async {
self.progress = min(max(0.0, self.progress + 1.0), Double(self.total))
}
}
func updateStatus(status: String) {
DispatchQueue.main.async {
self.status = status
}
}
func resetProgress() {
DispatchQueue.main.async {
self.progress = 0.0
}
}
}
//class ProgressManager: ObservableObject {
// @Published var progress: Double = 0.0
// @Published var total: Double = 0.0
// @Published var status: String = "Ready"
//
// func setTotal(_ total: Double) {
// DispatchQueue.main.async {
// self.total = total
// }
// }
//
// func updateProgress() {
// DispatchQueue.main.async {
// self.progress = min(max(0.0, self.progress + 1.0), Double(self.total))
// }
// }
//
// func updateStatus(status: String) {
// DispatchQueue.main.async {
// self.status = status
// }
// }
//
// func resetProgress() {
// DispatchQueue.main.async {
// self.progress = 0.0
// }
// }
//}
+4 -7
View File
@@ -72,13 +72,10 @@ class Locations: ObservableObject {
])
// Append Application Support subfolders for deeper search
do {
let subfolders = try appSupSubfolders()
for folder in subfolders {
self.apps.paths.append("\(home)/Library/Application Support/\(folder)")
}
} catch {
print("Error getting subfolders: \(error)")
let subfolders = listAppSupportDirectories()
for folder in subfolders {
self.apps.paths.append("\(home)/Library/Application Support/\(folder)")
// writeLog(string: "Adding subfolder: \(home)/Library/Application Support/\(folder)")
}
// self.widgets = Category(name: "Widgets", paths: [
+50 -12
View File
@@ -269,24 +269,56 @@ func darwinCT() -> (String, String) {
// Add subfolders of ~/Library/Application Support/ to locations for deeper search
func appSupSubfolders() throws -> [String] {
let fileManager = FileManager.default
let appSup = "\(home)/Library/Application Support/"
let subfolders = try fileManager.contentsOfDirectory(atPath: appSup)
let exclusionRegex = try NSRegularExpression(pattern: "\\bcom\\.apple\\b", options: [])
//func appSupSubfolders2() throws -> [String] {
// let fileManager = FileManager.default
// let appSup = "\(home)/Library/Application Support/"
// let subfolders = try fileManager.contentsOfDirectory(atPath: appSup)
// let exclusionRegex = try NSRegularExpression(pattern: "\\bcom\\.apple\\b", options: [])
// let exclusions = ["MobileSync", ".DS_Store", "Xcode", "SyncServices", "networkserviceproxy", "DiskImages", "CallHistoryTransactions", "App Store", "CloudDocs", "icdd", "iCloud", "Instruments", "AddressBook", "FaceTime", "AskPermission", "CallHistoryDB"]
//
// let allowedFolders = subfolders.filter { folder in
// let range = NSRange(location: 0, length: folder.utf16.count)
// return exclusionRegex.firstMatch(in: folder, options: [], range: range) == nil && !exclusions.contains(folder)
// }
//
// return allowedFolders
//}
func listAppSupportDirectories() -> [String] {
let home = FileManager.default.homeDirectoryForCurrentUser
let appSupportLocation = home.appendingPathComponent("Library/Application Support/")
let exclusions = ["MobileSync", ".DS_Store", "Xcode", "SyncServices", "networkserviceproxy", "DiskImages", "CallHistoryTransactions", "App Store", "CloudDocs", "icdd", "iCloud", "Instruments", "AddressBook", "FaceTime", "AskPermission", "CallHistoryDB"]
let exclusionRegex = try! NSRegularExpression(pattern: "\\bcom\\.apple\\b", options: [])
let allowedFolders = subfolders.filter { folder in
let range = NSRange(location: 0, length: folder.utf16.count)
return exclusionRegex.firstMatch(in: folder, options: [], range: range) == nil && !exclusions.contains(folder)
do {
let fileManager = FileManager.default
let directoryContents = try fileManager.contentsOfDirectory(at: appSupportLocation, includingPropertiesForKeys: [.isDirectoryKey], options: .skipsHiddenFiles)
let filteredDirectories: [String] = directoryContents.compactMap { url in
var isDirectory: ObjCBool = false
guard fileManager.fileExists(atPath: url.path, isDirectory: &isDirectory) else {
return nil
}
let directoryName = url.lastPathComponent
// Check for exclusions using regex and provided list
let excludeByRegex = exclusionRegex.firstMatch(in: directoryName, options: [], range: NSRange(location: 0, length: directoryName.utf16.count)) != nil
let excludeByList = exclusions.contains(directoryName)
return isDirectory.boolValue && !excludeByRegex && !excludeByList ? directoryName : nil
}
return filteredDirectories
} catch {
print("Error listing AppSupport directories: \(error.localizedDescription)")
return []
}
return allowedFolders
}
// Check if app is running before deleting app files
func killApp(appId: String, completion: @escaping () -> Void = {}) {
let runningApps = NSWorkspace.shared.runningApplications
@@ -360,7 +392,7 @@ func findPathsForApp(appState: AppState, locations: Locations) {
if collection.contains(itemURL) {
break
continue
}
// Catch web app plist files
if appInfo.webApp {
@@ -391,6 +423,7 @@ func findPathsForApp(appState: AppState, locations: Locations) {
}
} catch {
// writeLog(string: "Error processing location: \(location)\n\(error)")
print("Error processing location:", location, error)
continue
}
@@ -406,11 +439,16 @@ func findPathsForApp(appState: AppState, locations: Locations) {
collection.append(contentsOf: groupContainers)
let sortedCollection = collection.sorted(by: { $0.absoluteString < $1.absoluteString })
// writeLog(string: "\n\nsortedCollection: \(sortedCollection)")
// Save to appState
dispatchGroup.notify(queue: .main) {
updateOnMain {
appState.paths = sortedCollection
appState.selectedItems = Set(sortedCollection)
// writeLog(string: "\n\nappStatePaths: \(appState.paths)")
// writeLog(string: "\n\nappStateSelected: \(appState.selectedItems)")
}
}
+24 -21
View File
@@ -30,7 +30,7 @@ struct SimpleButtonStyle: ButtonStyle {
.frame(width: 20)
.foregroundColor(hovered ? color : color.opacity(0.5))
}
.padding(8)
.padding(5)
// .background {
// if hovered && !(shield ?? false) {
//// Circle()
@@ -173,6 +173,7 @@ struct AnimatedSearchStyle: TextFieldStyle {
struct SimpleSearchStyle: TextFieldStyle {
@State private var isHovered = false
@FocusState private var isFocused: Bool
@State var icon: Image?
@State var trash: Bool = false
@Binding var text: String
@@ -195,25 +196,25 @@ struct SimpleSearchStyle: TextFieldStyle {
.font(.title3)
.textFieldStyle(PlainTextFieldStyle())
Image(systemName: "arrow.triangle.2.circlepath")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 15, height: 15)
.padding(.trailing, 5)
.foregroundStyle(isHovered ? Color("mode").opacity(0.8) : Color("mode").opacity(0.5))
.onTapGesture {
withAnimation {
// Refresh Apps list
appState.reload.toggle()
let sortedApps = getSortedApps()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
appState.sortedApps.userApps = sortedApps.userApps
appState.sortedApps.systemApps = sortedApps.systemApps
appState.reload.toggle()
}
}
}
// Image(systemName: "arrow.triangle.2.circlepath")
// .resizable()
// .aspectRatio(contentMode: .fit)
// .frame(width: 15, height: 15)
// .padding(.trailing, 5)
// .foregroundStyle(isHovered ? Color("mode").opacity(0.8) : Color("mode").opacity(0.5))
// .onTapGesture {
// withAnimation {
// // Refresh Apps list
// appState.reload.toggle()
// let sortedApps = getSortedApps()
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
// appState.sortedApps.userApps = sortedApps.userApps
// appState.sortedApps.systemApps = sortedApps.systemApps
// appState.reload.toggle()
// }
// }
//
// }
if trash && text != "" {
Image(systemName: "xmark")
@@ -240,10 +241,12 @@ struct SimpleSearchStyle: TextFieldStyle {
}
)
.onHover { hovering in
withAnimation(Animation.easeIn(duration: 0.15)) {
withAnimation(Animation.easeInOut(duration: 0.15)) {
self.isHovered = hovering
self.isFocused = hovering
}
}
.focused($isFocused)
}
}
+7
View File
@@ -32,6 +32,13 @@ func resizeWindow(width: CGFloat, height: CGFloat) {
}
}
func resizeWindowAuto(windowSettings: WindowSettings) {
if let window = NSApplication.shared.windows.first {
let newSize = NSSize(width: windowSettings.loadWindowSettings().width, height: windowSettings.loadWindowSettings().height)
window.setContentSize(newSize)
}
}
// Check FDA
func checkFullDiskAccessForApp() -> Bool {
+9 -5
View File
@@ -10,22 +10,26 @@ import SwiftUI
class WindowSettings {
private let windowWidthKey = "windowWidthKey"
private let windowHeightKey = "windowHeightKey"
private let windowWidthKeyMini = "windowWidthKeyMini"
private let windowHeightKeyMini = "windowHeightKeyMini"
private let windowXKey = "windowXKey"
private let windowYKey = "windowYKey"
@AppStorage("settings.general.mini") private var mini: Bool = false
func saveWindowSettings(frame: NSRect) {
UserDefaults.standard.set(Float(frame.size.width), forKey: windowWidthKey)
UserDefaults.standard.set(Float(frame.size.height), forKey: windowHeightKey)
UserDefaults.standard.set(Float(frame.size.width), forKey: mini ? windowWidthKeyMini : windowWidthKey)
UserDefaults.standard.set(Float(frame.size.height), forKey: mini ? windowHeightKeyMini : windowHeightKey)
UserDefaults.standard.set(Float(frame.origin.x), forKey: windowXKey)
UserDefaults.standard.set(Float(frame.origin.y), forKey: windowYKey)
}
func loadWindowSettings() -> NSRect {
let width = CGFloat(UserDefaults.standard.float(forKey: windowWidthKey))
let height = CGFloat(UserDefaults.standard.float(forKey: windowHeightKey))
let width = CGFloat(UserDefaults.standard.float(forKey: mini ? windowWidthKeyMini : windowWidthKey))
let height = CGFloat(UserDefaults.standard.float(forKey: mini ? windowHeightKeyMini : windowHeightKey))
let x = CGFloat(UserDefaults.standard.float(forKey: windowXKey))
let y = CGFloat(UserDefaults.standard.float(forKey: windowYKey))
return NSRect(x: x, y: y, width: width, height: height)
}
}
+16
View File
@@ -20,6 +20,7 @@ struct PearcleanerApp: App {
@AppStorage("settings.permissions.hasLaunched") private var hasLaunched: Bool = false
@AppStorage("displayMode") var displayMode: DisplayMode = .system
@AppStorage("settings.general.mini") private var mini: Bool = false
@AppStorage("settings.general.miniview") private var miniView: Bool = true
@State private var search = ""
@State private var showPopover: Bool = false
@@ -65,6 +66,13 @@ struct PearcleanerApp: App {
}
}
.onAppear {
if miniView {
appState.currentView = .apps
} else {
appState.currentView = .empty
}
// Disable tabbing
NSWindow.allowsAutomaticWindowTabbing = false
@@ -79,6 +87,8 @@ struct PearcleanerApp: App {
// Load progressbar total
// appState.progressManager.total = Double(locations.apps.paths.count)
Task {
@@ -140,5 +150,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
// func applicationDidFinishLaunching(_ notification: Notification, win: WindowSettings) {
// let frame = win.loadWindowSettings()
// NSApplication.shared.windows.first?.setFrame(frame, display: true)
// }
}
+52 -13
View File
@@ -10,10 +10,13 @@ import SwiftUI
struct GeneralSettingsTab: View {
@EnvironmentObject var appState: AppState
@State private var windowSettings = WindowSettings()
@AppStorage("settings.general.glass") private var glass: Bool = true
@AppStorage("settings.general.mini") private var mini: Bool = false
@AppStorage("settings.general.dark") var isDark: Bool = true
@AppStorage("settings.general.popover") private var popoverStay: Bool = true
@AppStorage("settings.general.miniview") private var miniView: Bool = true
@AppStorage("settings.general.sidebarWidth") private var sidebarWidth: Double = 280
@AppStorage("displayMode") var displayMode: DisplayMode = .system
@State private var selectedTheme = "Auto"
private let themes = ["Auto", "Dark", "Light"]
@@ -38,7 +41,26 @@ struct GeneralSettingsTab: View {
RoundedRectangle(cornerRadius: 8)
.fill(Color("mode").opacity(0.05))
)
HStack {
VStack(alignment: .leading, spacing: 5) {
Text("Sidebar").font(.title2)
Text("Adjust sidebar width")
.font(.footnote)
.foregroundStyle(.gray)
}
Spacer()
Slider(value: $sidebarWidth, in: 200...400) {
Text("\(Int(sidebarWidth))")
}
.padding(.horizontal)
}
.padding()
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color("mode").opacity(0.05))
)
HStack {
VStack(alignment: .leading, spacing: 5) {
Text("Appearance").font(.title2)
@@ -73,12 +95,7 @@ struct GeneralSettingsTab: View {
break
}
}
// Toggle(isOn: $isDark, label: {
// })
// .toggleStyle(.switch)
// .onChange(of: isDark) { newValue in
// displayMode.colorScheme = newValue ? .dark : .light
// }
}
.padding()
.background(
@@ -99,10 +116,12 @@ struct GeneralSettingsTab: View {
.toggleStyle(.switch)
.onChange(of: mini) { newVal in
if mini {
resizeWindow(width: 300, height: 300)
appState.currentView = .empty
resizeWindowAuto(windowSettings: windowSettings)
// resizeWindow(width: 300, height: 300)
appState.currentView = miniView ? .apps : .empty
} else {
resizeWindow(width: 700, height: 500)
resizeWindowAuto(windowSettings: windowSettings)
// resizeWindow(width: 700, height: 500)
if appState.appInfo.appName.isEmpty {
appState.currentView = .empty
} else {
@@ -118,11 +137,31 @@ struct GeneralSettingsTab: View {
)
HStack {
VStack(alignment: .leading, spacing: 5) {
Text("Mini - Default View").font(.title2)
Text("Toggles drop target or apps list view on launch")
.font(.footnote)
.foregroundStyle(.gray)
}
Spacer()
Toggle(isOn: $miniView, label: {
})
.toggleStyle(.switch)
.onChange(of: miniView) { newVal in
appState.currentView = newVal ? .apps : .empty
}
}
.padding()
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color("mode").opacity(0.05))
)
HStack {
VStack(alignment: .leading, spacing: 5) {
Text("Mini - Files View").font(.title2)
Text("Keeps file search view on top in mini mode")
Text("Mini - Popover").font(.title2)
Text("Keeps file search popover on top in mini mode")
.font(.footnote)
.foregroundStyle(.gray)
}
@@ -145,7 +184,7 @@ struct GeneralSettingsTab: View {
}
.padding(20)
.frame(width: 400, height: 350)
.frame(width: 400, height: 500)
}
+34 -25
View File
@@ -42,27 +42,36 @@ struct AppListItems: View {
.truncationMode(.tail)
.padding(.horizontal, 5)
}
Spacer()
if appInfo.webApp {
Text("web")
.font(.footnote)
.foregroundStyle(Color("mode").opacity(0.5))
.foregroundStyle(Color("mode").opacity(0.3))
.frame(minWidth: 30, minHeight: 15)
.padding(2)
.background(Color("mode").opacity(0.1))
.clipShape(.capsule)
.background(
Capsule().strokeBorder(Color("mode").opacity(0.3), lineWidth: 1)
)
// .background(Color("mode").opacity(0.1))
// .clipShape(.capsule)
}
if appInfo.wrapped {
Text("iOS")
.font(.footnote)
.foregroundStyle(Color("mode").opacity(0.5))
.foregroundStyle(Color("mode").opacity(0.3))
.frame(minWidth: 30, minHeight: 15)
.padding(2)
.background(Color("mode").opacity(0.1))
.clipShape(.capsule)
.background(
Capsule().strokeBorder(Color("mode").opacity(0.3), lineWidth: 1)
)
// .background(Color("mode").opacity(0.1))
// .clipShape(.capsule)
}
Spacer()
Text(appInfo.appVersion)
.font(.footnote)
.foregroundStyle(Color("mode").opacity(0.5))
@@ -105,24 +114,24 @@ struct AppListItems: View {
}
}
.popover(isPresented: Binding(
get: { showPopover && appState.appInfo.id == appInfo.id},
set: { _ in showPopover = false}
), attachmentAnchor: .rect(.rect(CGRect(x: windowSettings.loadWindowSettings().width - 17, y: 15, width: 0, height: 0))), arrowEdge: .trailing) {
// .popover(isPresented: Binding(
// get: { showPopover && appState.appInfo.id == appInfo.id},
// set: { _ in showPopover = false}
// ), attachmentAnchor: .rect(.rect(CGRect(x: windowSettings.loadWindowSettings().width - 17, y: 15, width: 0, height: 0))), arrowEdge: .trailing) {
// .popover(isPresented: $showPopover, arrowEdge: .trailing) {
VStack {
FilesView(showPopover: $showPopover, search: $search)
.id(appState.appInfo.id)
}
.interactiveDismissDisabled(popoverStay)
.background(
Rectangle()
.fill(Color("pop"))
.padding(-80)
)
.frame(minWidth: 650, minHeight: 500)
}
// VStack {
// FilesView(showPopover: $showPopover, search: $search)
// .id(appState.appInfo.id)
// }
// .interactiveDismissDisabled(popoverStay)
// .background(
// Rectangle()
// .fill(Color("pop"))
// .padding(-80)
// )
// .frame(minWidth: 650, minHeight: 500)
//
// }
}
}
+55 -16
View File
@@ -11,6 +11,7 @@ import SwiftUI
struct AppListView: View {
@EnvironmentObject var appState: AppState
@AppStorage("settings.general.glass") private var glass: Bool = false
@AppStorage("settings.general.sidebarWidth") private var sidebarWidth: Double = 280
@Binding var search: String
@State private var showSys: Bool = true
@State private var showUsr: Bool = true
@@ -47,14 +48,15 @@ struct AppListView: View {
ProgressView("Refreshing applications")
Spacer()
}
.frame(width: 250)
.frame(width: sidebarWidth)
.padding(.vertical)
} else {
VStack(alignment: .center) {
VStack(alignment: .center, spacing: 20) {
HStack {
SearchBar(search: $search)
SearchBarMiniBottom(search: $search)
// SearchBar(search: $search)
// Button("") {
// withAnimation(.easeInOut(duration: 0.5)) {
@@ -72,14 +74,14 @@ struct AppListView: View {
// .buttonStyle(SimpleButtonStyle(icon: "arrow.triangle.2.circlepath", help: "Refresh app list", color: Color("mode")))
}
}
.padding(.horizontal)
// .padding(.horizontal)
.padding(.top, 20)
.padding(.bottom)
ScrollView {
VStack(alignment: .leading) {
LazyVStack(alignment: .leading, pinnedViews: [.sectionHeaders]) {
if filteredUserApps.count > 0 {
VStack {
Header(title: "User", count: filteredUserApps.count)
@@ -91,7 +93,7 @@ struct AppListView: View {
}
// .padding(.bottom)
}
}
if filteredSystemApps.count > 0 {
@@ -113,7 +115,7 @@ struct AppListView: View {
.scrollIndicators(.never)
}
.frame(width: 250)
.frame(width: sidebarWidth)
.padding(.vertical)
}
@@ -130,7 +132,7 @@ struct AppListView: View {
// Details View
VStack(spacing: 0) {
if appState.currentView == .empty {
if appState.currentView == .empty || appState.currentView == .apps {
TopBar()
AppDetailsEmptyView(showPopover: $showPopover)
} else if appState.currentView == .files {
@@ -236,18 +238,55 @@ struct SearchBar: View {
struct Header: View {
let title: String
let count: Int
@State private var hovered = false
@EnvironmentObject var appState: AppState
var body: some View {
HStack {
Text(title).opacity(0.5)
// Spacer()
HStack {
if hovered {
withAnimation() {
Image(systemName: "arrow.circlepath")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 19, height: 19)
.onTapGesture {
withAnimation {
// Refresh Apps list
appState.reload.toggle()
let sortedApps = getSortedApps()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
appState.sortedApps.userApps = sortedApps.userApps
appState.sortedApps.systemApps = sortedApps.systemApps
appState.reload.toggle()
}
}
}
.help("Refresh apps")
}
} else {
Text("\(count)")
.font(.system(size: 10))
.frame(minWidth: count > 99 ? 30 : 20, minHeight: 15)
.padding(2)
.background(Color("mode").opacity(0.1))
.clipShape(.capsule)
// .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
}
}
.onHover { hovering in
withAnimation() {
hovered = hovering
}
}
Spacer()
Text("\(count)")
.font(.system(size: 10))
.frame(minWidth: count > 99 ? 30 : 20, minHeight: 15)
.padding(2)
.background(Color("mode").opacity(0.1))
.clipShape(.capsule)
// .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
}
.padding(4)
}
+2 -15
View File
@@ -34,20 +34,7 @@ struct FilesView: View {
ProgressView()
.progressViewStyle(.linear)
.frame(width: 400, height: 10)
// ProgressView("\(appState.progressManager.status)", value: appState.progressManager.progress, total: Double(appState.progressManager.total))
// .progressViewStyle(LinearProgressViewStyle(tint: .blue))
// .frame(width: 400, height: 10)
// .padding(.top)
// .onReceive(appState.progressManager.$progress) { newProgress in
// DispatchQueue.main.async {
// appState.objectWillChange.send()
// }
// }
// .onReceive(appState.progressManager.$status) { newStatus in
// DispatchQueue.main.async {
// appState.objectWillChange.send()
// }
// }
Spacer()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -272,10 +259,10 @@ struct FilesView: View {
}
if let appSize = totalSizeOnDisk(for: appState.paths) {
self.appSize = "\(appSize)"
self.showDetails = true
} else {
print("Error calculating the total size on disk.")
}
self.showDetails = true
}
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+48 -19
View File
@@ -39,24 +39,24 @@ struct MiniMode: View {
}
// .padding(.leading, appState.sidebar ? 0 : 10)
.transition(.move(edge: .leading))
// .popover(isPresented: $showPopover, arrowEdge: .trailing) {
// VStack {
// FilesView(showPopover: $showPopover, search: $search)
// .id(appState.appInfo.id)
// }
// .interactiveDismissDisabled(popoverStay)
// .background(
// Rectangle()
// .fill(Color("pop"))
// .padding(-80)
// )
// .frame(minWidth: 600, minHeight: 500)
//
// }
.popover(isPresented: $showPopover, arrowEdge: .trailing) {
VStack {
FilesView(showPopover: $showPopover, search: $search)
.id(appState.appInfo.id)
}
.interactiveDismissDisabled(popoverStay)
.background(
Rectangle()
.fill(Color("pop"))
.padding(-80)
)
.frame(minWidth: 650, minHeight: 500)
}
}
.frame(minWidth: 300, minHeight: 300)
.frame(minWidth: 300, minHeight: 335)
.edgesIgnoringSafeArea(.all)
.background(glass ? GlassEffect(material: .sidebar, blendingMode: .behindWindow).edgesIgnoringSafeArea(.all) : nil)
@@ -184,12 +184,37 @@ struct MiniAppView: View {
.padding(.vertical)
} else {
VStack(alignment: .center) {
// if appState.currentView == .apps {
// HStack(alignment: .center, spacing: 0) {
// Spacer()
//
// Button("") {
// withAnimation(.easeInOut(duration: 0.5)) {
// // updateOnMain {
// appState.currentView = .empty
// appState.appInfo = AppInfo.empty
// showPopover = false
// // }
// }
// }
// .buttonStyle(SimpleButtonStyle(icon: "arrow.backward.square", help: "Back to Drop Zone", color: Color("mode")))
// .padding(.leading, 10)
// .padding(.trailing, 0)
//
// SearchBarMiniBottom(search: $search)
//
// Spacer()
// }
// .padding(.top, 30)
// }
ScrollView {
VStack(alignment: .leading) {
LazyVStack(alignment: .leading, pinnedViews: [.sectionHeaders]) {
if filteredUserApps.count > 0 {
VStack {
Header(title: "User", count: filteredUserApps.count)
ForEach(filteredUserApps, id: \.self) { appInfo in
@@ -203,6 +228,7 @@ struct MiniAppView: View {
}
if filteredSystemApps.count > 0 {
VStack {
Header(title: "System", count: filteredSystemApps.count)
ForEach(filteredSystemApps, id: \.self) { appInfo in
@@ -219,7 +245,10 @@ struct MiniAppView: View {
}
.scrollIndicators(.never)
if appState.currentView == .apps {
SearchBarMiniBottom(search: $search)
}
}
.padding(.bottom)
}
+1 -1
View File
@@ -37,7 +37,7 @@ struct TopBar: View {
Spacer()
if appState.currentView != .empty {
if appState.currentView != .empty || appState.currentView != .apps {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
appState.currentView = .empty
+88 -64
View File
@@ -15,88 +15,99 @@ struct TopBarMini: View {
@Binding var search: String
@Binding var showPopover: Bool
@EnvironmentObject var appState: AppState
var body: some View {
HStack(alignment: .center, spacing: 5) {
Spacer()
if appState.currentView == .apps {
// HStack {
// Spacer()
SearchBarMini(search: $search)
// .frame(width: 150)
// .offset(x: 20)
// .padding(.horizontal, 30)
// .padding(.top, 5)
// Spacer() //////////////
// 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()
// }
//
// }
// if appState.currentView == .apps {
// Button("") {
// withAnimation(.easeInOut(duration: 0.5)) {
// // updateOnMain {
// appState.currentView = .empty
// appState.appInfo = AppInfo.empty
// showPopover = false
// // }
// }
// .buttonStyle(SimpleButtonStyle(icon: "arrow.triangle.2.circlepath", help: "Refresh app list", color: Color("mode")))
// .padding(.leading, 5)
// }
}
if appState.currentView == .apps {
// .buttonStyle(SimpleButtonStyle(icon: "arrow.backward.square", help: "Back to Drop Zone", color: Color("mode")))
// } else
if appState.currentView == .empty {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
// updateOnMain {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
showPopover = false
// }
// updateOnMain {
appState.currentView = .apps
// }
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.app", help: "Back to Drop Zone", 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 List", color: Color("mode")))
.buttonStyle(SimpleButtonStyle(icon: "list.dash", help: "Apps List", color: Color("mode")))
} else if appState.currentView == .files {
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
// updateOnMain {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
// }
// updateOnMain {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
// }
}
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.app", help: "Back to Drop Zone", color: Color("mode")))
.buttonStyle(SimpleButtonStyle(icon: "plus.square.dashed", help: "Drop Target", color: Color("mode")))
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
// updateOnMain {
appState.currentView = .apps
// }
// updateOnMain {
appState.currentView = .apps
// }
}
}
.buttonStyle(SimpleButtonStyle(icon: "list.triangle", help: "Apps List", color: Color("mode")))
.buttonStyle(SimpleButtonStyle(icon: "list.dash", help: "Apps List", color: Color("mode")))
}
if appState.currentView == .apps {
HStack {
Spacer()
// SearchBarMini(search: $search)
// .frame(width: 150)
// .offset(x: 20)
// .padding(.horizontal, 30)
// .padding(.top, 5)
Button("") {
withAnimation(.easeInOut(duration: 0.5)) {
// updateOnMain {
appState.currentView = .empty
appState.appInfo = AppInfo.empty
showPopover = false
// }
}
}
.buttonStyle(SimpleButtonStyle(icon: "plus.square.dashed", help: "Drop Target", color: Color("mode")))
// Spacer()
// Button("") {
// withAnimation {
// // Refresh Apps list
// appState.reload.toggle()
// let sortedApps = getSortedApps()
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// appState.sortedApps.userApps = sortedApps.userApps
// appState.sortedApps.systemApps = sortedApps.systemApps
// appState.reload.toggle()
// }
// }
// }
// .buttonStyle(SimpleButtonStyle(icon: "arrow.circlepath", help: "Refresh app list", color: Color("mode")))
// .padding(.leading, 5)
}
}
}
.padding(.horizontal, 5)
.padding(.top, 5)
.padding(.bottom, 10)
.padding(.horizontal, 10)
.padding(.top, 10)
.padding(.bottom, 5)
}
}
@@ -108,8 +119,21 @@ struct SearchBarMini: View {
HStack {
TextField("Search", text: $search)
.textFieldStyle(AnimatedSearchStyle(text: $search))
// .textFieldStyle(SimpleSearchStyle(trash: true, reload: $reload, text: $search))
// .textFieldStyle(SimpleSearchStyle(trash: true, reload: $reload, text: $search))
}
// .frame(height: 20)
.frame(height: 20)
}
}
struct SearchBarMiniBottom: View {
@Binding var search: String
var body: some View {
HStack {
TextField("Search", text: $search)
.textFieldStyle(SimpleSearchStyle(trash: true, text: $search))
}
.padding(.horizontal)
.padding(.bottom, 0)
}
}