This commit is contained in:
Alin
2024-03-01 18:28:21 -07:00
parent e87bbe0c9f
commit c3ce997a88
37 changed files with 783 additions and 2211 deletions
+2 -1
View File
@@ -36,10 +36,11 @@ struct AboutSettingsTab: View {
VStack(alignment: .leading) {
HStack() {
Text("Credits and Inspiration").font(.title2)
Text("Credits").font(.title2)
Spacer()
}
.padding(.leading)
.padding(.bottom)
HStack{
Image(systemName: "paintbrush.pointed")
+28 -17
View File
@@ -19,9 +19,10 @@ struct GeneralSettingsTab: View {
@AppStorage("settings.general.sidebarWidth") private var sidebarWidth: Double = 280
@AppStorage("displayMode") var displayMode: DisplayMode = .system
@AppStorage("settings.sentinel.enable") private var sentinel: Bool = false
@AppStorage("settings.general.instant") private var instantSearch: Bool = true
@AppStorage("settings.general.selectedTheme") var selectedTheme: String = "Auto"
@State private var diskStatus: Bool = false
@State private var accessStatus: Bool = false
@State private var selectedTheme = "Auto"
private let themes = ["Auto", "Dark", "Light"]
@Binding var showPopover: Bool
@@ -57,25 +58,24 @@ struct GeneralSettingsTab: View {
HStack(spacing: 0) {
Image(systemName: "sidebar.left")
Image(systemName: instantSearch ? "bolt" : "bolt.slash")
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.padding(.trailing)
.foregroundStyle(.gray)
Text("Adjust sidebar width")
.font(.callout)
.foregroundStyle(.gray)
VStack(alignment: .leading, spacing: 5) {
Text("\(instantSearch ? "Instant search is enabled" : "Instant search is disabled")")
.font(.callout)
.foregroundStyle(.gray)
}
InfoButton(text: "When instant search is enabled, all application files are gathered and cached for later use on startup instead of on each app click. There might be a slight delay of a few seconds when launching Pearcleaner depending on the amount of apps you have installed.", color: nil)
Spacer()
Slider(value: $sidebarWidth, in: 200...360) {
// Text("\(Int(sidebarWidth))")
}
.padding(.horizontal)
.frame(width: 185)
Button("") {
sidebarWidth = 280
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.uturn.left.circle", help: "Reset to default size", color: Color("mode")))
Toggle(isOn: $instantSearch, label: {
})
.toggleStyle(.switch)
}
.padding(5)
.padding(.leading)
@@ -89,7 +89,7 @@ struct GeneralSettingsTab: View {
.padding(.trailing)
.foregroundStyle(.gray)
VStack(alignment: .leading, spacing: 5) {
Text("Set color mode")
Text("Set application color mode")
.font(.callout)
.foregroundStyle(.gray)
}
@@ -143,7 +143,7 @@ struct GeneralSettingsTab: View {
.padding(.trailing)
.foregroundStyle(.gray)
VStack(alignment: .leading, spacing: 5) {
Text("\(mini ? "Mini window mode" : "Full size window mode")")
Text("\(mini ? "Mini window mode selected" : "Full size window mode selected")")
.font(.callout)
.foregroundStyle(.gray)
}
@@ -182,6 +182,9 @@ struct GeneralSettingsTab: View {
.font(.callout)
.foregroundStyle(.gray)
}
InfoButton(text: "In mini window mode, you can have Pearcleaner startup to the Apps List view or the Drop Target view.", color: nil)
Spacer()
Toggle(isOn: $miniView, label: {
})
@@ -202,10 +205,13 @@ struct GeneralSettingsTab: View {
.padding(.trailing)
.foregroundStyle(.gray)
VStack(alignment: .leading, spacing: 5) {
Text("\(popoverStay ? "Popover window doesn't hide on outside click" : "Popover window hides on outside click")")
Text("\(popoverStay ? "Popover window will stay on top" : "Popover window will not stay on top")")
.font(.callout)
.foregroundStyle(.gray)
}
InfoButton(text: "In mini window mode, if you pin the Files popover on top, clicking away from the window will not dismiss it. Otherwise, it will dismiss by clicking anywhere outside the popover.", color: nil)
Spacer()
Toggle(isOn: $popoverStay, label: {
})
@@ -330,6 +336,11 @@ struct GeneralSettingsTab: View {
.onAppear {
diskStatus = checkAndRequestFullDiskAccess(appState: appState, skipAlert: true)
accessStatus = checkAndRequestAccessibilityAccess(appState: appState)
// if displayMode.colorScheme == .dark {
// selectedTheme = "Dark"
// } else if displayMode.colorScheme == .light {
// selectedTheme = "Light"
// }
}
}
-150
View File
@@ -1,150 +0,0 @@
//
// Permissions.swift
// Pearcleaner
//
// Created by Alin Lupascu on 11/5/23.
//
import Foundation
import SwiftUI
struct PermissionsSettingsTab: View {
@EnvironmentObject var appState: AppState
@State private var diskStatus: Bool = false
@State private var accessStatus: Bool = false
var body: some View {
Form {
VStack(alignment: .leading, spacing: 10) {
HStack(spacing: 0) {
Image(systemName: diskStatus ? "externaldrive" : "externaldrive")
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.padding(.trailing)
.foregroundStyle(diskStatus ? .green : .red)
Text(diskStatus ? "Full Disk permission granted" : "Full Disk permission not granted")
.font(.callout)
.foregroundStyle(.gray)
Spacer()
Button("") {
if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles") {
NSWorkspace.shared.open(url)
}
}
.buttonStyle(SimpleButtonStyle(icon: "gear", help: "View disk permissions pane", color: Color("mode")))
}
.padding(5)
HStack(spacing: 0) {
Image(systemName: accessStatus ? "accessibility" : "accessibility")
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.padding(.trailing)
.foregroundStyle(accessStatus ? .green : .red)
Text(accessStatus ? "Accessibility permission granted" : "Accessibility permission not granted")
.font(.callout)
.foregroundStyle(.gray)
Spacer()
Button("") {
if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility") {
NSWorkspace.shared.open(url)
}
}
.buttonStyle(SimpleButtonStyle(icon: "gear", help: "View accessibility permissions pane", color: Color("mode")))
}
.padding(5)
// HStack(spacing: 15) {
// Image(systemName: "internaldrive")
// .resizable()
// .scaledToFit()
// .frame(width: 20)
//
// VStack(alignment: .leading, spacing: 5) {
// Text("Full Disk")
// Text(diskStatus ? "Permission granted" : "Permission not granted")
// .font(.footnote)
// .foregroundStyle(diskStatus ? .green : .red)
// }
//
// Spacer()
//
// Button("") {
// if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles") {
// NSWorkspace.shared.open(url)
// }
// }
// .buttonStyle(SimpleButtonStyle(icon: "paperplane", help: "View disk permission pane", color: Color("AccentColor")))
// }
// .padding()
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(Color("mode").opacity(0.05))
// )
// HStack(spacing: 15) {
// Image(systemName: "accessibility")
// .resizable()
// .scaledToFit()
// .frame(width: 20)
//
// VStack(alignment: .leading, spacing: 5) {
// Text("Accessibility")
// Text(accessStatus ? "Permission granted" : "Permission not granted")
// .font(.footnote)
// .foregroundStyle(accessStatus ? .green : .red)
// }
//
// Spacer()
//
// Button("") {
// if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility") {
// NSWorkspace.shared.open(url)
// }
// }
// .buttonStyle(SimpleButtonStyle(icon: "paperplane", help: "View accessibility pane", color: Color("AccentColor")))
// }
// .padding()
// .background(
// RoundedRectangle(cornerRadius: 8)
// .fill(Color("mode").opacity(0.05))
// )
// HStack(alignment: .center) {
// Spacer()
// Button("") {
// relaunchApp()
// }
// .buttonStyle(SimpleButtonStyle(icon: "restart", help: "Restart application", color: Color("AccentColor")))
// Text("Restart")
// Spacer()
// }
// .padding()
}
}
.padding(20)
.frame(width: 400, height: 200)
.onAppear {
diskStatus = checkAndRequestFullDiskAccess(appState: appState, skipAlert: true)
accessStatus = checkAndRequestAccessibilityAccess(appState: appState)
}
}
}
-56
View File
@@ -1,56 +0,0 @@
//
// Sentinel.swift
// Pearcleaner
//
// Created by Alin Lupascu on 11/9/23.
//
import Foundation
import SwiftUI
struct SentinelSettingsTab: View {
@EnvironmentObject var appState: AppState
@AppStorage("settings.sentinel.enable") private var sentinel: Bool = false
var body: some View {
Form {
VStack {
HStack {
VStack(alignment: .leading, spacing: 5) {
Text("Sentinel Monitor").font(.title2)
Text("Detects when apps are moved to Trash for file removal")
.font(.footnote)
.foregroundStyle(.gray)
}
Spacer()
Toggle(isOn: $sentinel, label: {
})
.toggleStyle(SentinelToggleStyle())
.onChange(of: sentinel) { newValue in
if newValue {
launchctl(load: true)
} else {
launchctl(load: false)
}
}
}
.padding()
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color("mode").opacity(0.05))
)
Text("If you uninstall Pearcleaner, make sure to disable Sentinel first").font(.footnote)
.foregroundStyle(Color.red)
.padding()
}
}
.padding(20)
.frame(width: 450, height: 130)
}
}
+3 -13
View File
@@ -20,18 +20,6 @@ struct SettingsView: View {
}
.tag(CurrentTabView.general)
// PermissionsSettingsTab()
// .tabItem {
// Label(CurrentTabView.permissions.title, systemImage: "lock")
// }
// .tag(CurrentTabView.permissions)
// SentinelSettingsTab()
// .tabItem {
// Label(CurrentTabView.sentinel.title, systemImage: "eye.circle")
// }
// .tag(CurrentTabView.sentinel)
UpdateSettingsTab()
.tabItem {
Label(CurrentTabView.update.title, systemImage: "cloud")
@@ -45,7 +33,7 @@ struct SettingsView: View {
.tag(CurrentTabView.about)
}
}
}
@@ -56,3 +44,5 @@ struct SettingsView: View {
+4 -20
View File
@@ -71,23 +71,25 @@ struct UpdateSettingsTab: View {
HStack(alignment: .center, spacing: 20) {
Spacer()
Button("Update Notes"){
loadGithubReleases(appState: appState)
}
.buttonStyle(SimpleButtonStyle(icon: "list.bullet", help: "Check release notes", color: Color("mode")))
Spacer()
Button("Force Update"){
loadGithubReleases(appState: appState, manual: true)
}
.buttonStyle(SimpleButtonStyle(icon: "arrow.down.square", help: "Check for updates", color: Color("mode")))
Spacer()
Button("GitHub"){
NSWorkspace.shared.open(URL(string: "https://github.com/alienator88/Pearcleaner/releases")!)
}
.buttonStyle(SimpleButtonStyle(icon: "link", help: "View releases on GitHub", color: Color("mode")))
Spacer()
}
@@ -130,13 +132,9 @@ func checkForUpdate(appState: AppState, manual: Bool = false) {
let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
if latestRelease.tag_name > currentVersion ?? "" {
NewWin.show(appState: appState, width: 500, height: 440, newWin: .update)
// appState.alertType = .update
// appState.showAlert = true
} else {
if manual {
NewWin.show(appState: appState, width: 500, height: 300, newWin: .no_update)
// appState.alertType = .no_update
// appState.showAlert = true
}
}
}
@@ -215,22 +213,14 @@ func UnzipAndReplace(DownloadedFileURL fileURL: String, appState: AppState) {
// Unzip the downloaded update file to your app's bundle path
let process = Process()
// process.executableURL = URL(fileURLWithPath: "/usr/bin/unzip")
// process.arguments = [fileURL, "-d", appDirectory]
process.executableURL = URL(fileURLWithPath: "/usr/bin/ditto")
process.arguments = ["-xk", fileURL, appDirectory]
// let pipe = Pipe()
process.standardOutput = FileHandle.nullDevice
process.standardError = FileHandle.nullDevice
try process.run()
process.waitUntilExit()
// let outputData = pipe.fileHandleForReading.readDataToEndOfFile()
// let output = String(decoding: outputData, as: UTF8.self)
//
// writeLog(string: output)
updateOnMain {
appState.progressBar.0 = "Deleting update file"
appState.progressBar.1 = 0.8
@@ -239,12 +229,6 @@ func UnzipAndReplace(DownloadedFileURL fileURL: String, appState: AppState) {
// After unzipping, remove the update file
try fileManager.removeItem(atPath: fileURL)
// Show Restart dialog
// updateOnMain {
// appState.alertType = .restartApp
// appState.showAlert = true
// }
} catch {
printOS("Error updating the app: \(error)")