This commit is contained in:
Alin
2024-04-12 16:44:53 -06:00
parent 9124d85c5d
commit bf7771cf61
28 changed files with 1014 additions and 412 deletions
+5 -4
View File
@@ -41,15 +41,16 @@ struct AppCommands: Commands {
let sortedApps = getSortedApps(paths: fsm.folderPaths, appState: appState)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
appState.sortedApps = []
// appState.sortedApps.systemApps = []
appState.sortedApps = sortedApps
// appState.sortedApps.systemApps = sortedApps.systemApps
if instantSearch {
Task(priority: .high){
loadAllPaths(allApps: sortedApps, appState: appState, locations: locations)
loadAllPaths(allApps: sortedApps, appState: appState, locations: locations) {
appState.reload.toggle()
}
}
} else {
appState.reload.toggle()
}
appState.reload.toggle()
}
}
} label: {
+17
View File
@@ -7,6 +7,7 @@
import Foundation
import SwiftUI
import FinderSync
let home = FileManager.default.homeDirectoryForCurrentUser.path
@@ -31,6 +32,7 @@ class AppState: ObservableObject
@Published var popCount: Int = 0
@Published var instantProgress: Double = 0.0
@Published var instantTotal: Double = 0.0
@Published var finderExtensionEnabled: Bool = false
init() {
@@ -54,6 +56,21 @@ class AppState: ObservableObject
fileSize: [:],
fileIcon: [:]
)
updateExtensionStatus()
NotificationCenter.default.addObserver(
self,
selector: #selector(updateExtensionStatus),
name: NSApplication.didBecomeActiveNotification,
object: nil
)
}
@objc func updateExtensionStatus() {
let extentionStatus = FIFinderSyncController.isExtensionEnabled
DispatchQueue.main.async {
self.finderExtensionEnabled = extentionStatus
}
}
}
-1
View File
@@ -26,7 +26,6 @@ class DeeplinkManager {
// This handles dropping an app onto Pearcleaner
if url.pathExtension == "app" {
handleAppBundle(url: url, appState: appState, locations: locations)
// This handles sentinel monitor launch
} else if url.scheme == DeepLinkConstants.scheme,
url.host == DeepLinkConstants.host,
let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
+76 -65
View File
@@ -11,15 +11,17 @@ import SwiftUI
struct SimpleButtonStyle: ButtonStyle {
@State private var hovered = false
let icon: String
let label: String?
let label: String
let help: String
let color: Color
let size: CGFloat
init(icon: String, label: String? = "", help: String, color: Color) {
init(icon: String, label: String = "", help: String, color: Color = Color("mode"), size: CGFloat = 20) {
self.icon = icon
self.label = label
self.help = help
self.color = color
self.size = size
}
func makeBody(configuration: Self.Configuration) -> some View {
@@ -27,8 +29,8 @@ struct SimpleButtonStyle: ButtonStyle {
Image(systemName: icon)
.resizable()
.scaledToFit()
.frame(width: 20)
if let label = label, !label.isEmpty {
.frame(width: size, height: size)
if !label.isEmpty {
Text(label)
}
}
@@ -45,34 +47,6 @@ struct SimpleButtonStyle: ButtonStyle {
}
struct NavButtonBottomBarStyle: ButtonStyle {
@State private var isHovered = false
var image: String
var help: String
func makeBody(configuration: Configuration) -> some View {
ZStack {
Image(systemName: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20)
.foregroundStyle(isHovered ? Color("mode").opacity(0.8) : Color("mode").opacity(0.5))
Rectangle()
.foregroundColor(.clear)
.frame(width: 36, height: 36)
.cornerRadius(6)
.contentShape(Rectangle())
}
.scaleEffect(configuration.isPressed ? 0.95 : 1)
.buttonStyle(.plain)
.onHover { inside in
isHovered = inside
}
.help(help)
}
}
struct InfoButton: View {
@State private var isPopoverPresented: Bool = false
@@ -215,7 +189,7 @@ public struct NewFeatureView: View {
showFeature = false
}
}
.buttonStyle(SimpleButtonStyle(icon: "x.circle.fill", help: "Close", color: .gray))
.buttonStyle(SimpleButtonStyle(icon: "x.circle.fill", help: "Close", color: (Color("mode").opacity(0.5))))
.onHover { isHovered in
if isHovered {
NSCursor.pointingHand.push()
@@ -249,43 +223,36 @@ public struct NewFeatureView: View {
public struct SlideableDivider: View {
@EnvironmentObject private var themeSettings: ThemeSettings
@Binding var dimension: Double
@State private var dimensionStart: Double?
@State private var handleWidth: Double = 2
@State private var handleWidth: Double = 4
@State private var handleHeight: Double = 30
@State private var isHovered: Bool = false
public init(dimension: Binding<Double>) {
self._dimension = dimension
}
public var body: some View {
Rectangle()
.foregroundStyle(Color.gray.opacity(0.3))
.frame(width: 1)
.overlay(
VStack(spacing: 0) {
Spacer()
RoundedRectangle(cornerRadius: 50)
.fill(Color("mode").opacity(0.3))
.frame(width: handleWidth, height: handleHeight)
.onHover { inside in
if inside {
NSCursor.resizeLeftRight.push()
.foregroundStyle(Color("mode").opacity(0.0))
.frame(width: 10)
.onHover { inside in
if inside {
NSCursor.resizeLeftRight.push()
} else {
NSCursor.pop()
} else {
NSCursor.pop()
}
}
.contextMenu {
Button("Reset Size") {
dimension = 280
}
}
.gesture(drag)
Spacer()
}
.offset(x: 5)
)
}
.contextMenu {
Button("Reset Size") {
dimension = 280
}
}
.gesture(drag)
.help("Right click to reset size")
}
var drag: some Gesture {
@@ -302,13 +269,13 @@ public struct SlideableDivider: View {
let maxWidth: Double = 350
dimension = max(minWidth, min(maxWidth, newDimension))
NSCursor.closedHand.set()
handleWidth = 4
handleWidth = 6
handleHeight = 40
}
.onEnded { val in
dimensionStart = nil
NSCursor.arrow.set()
handleWidth = 2
handleWidth = 4
handleHeight = 30
}
}
@@ -323,18 +290,18 @@ struct LabeledDivider: View {
HStack(spacing: 0) {
Rectangle()
.frame(height: 1)
.foregroundColor(.gray.opacity(0.2))
.foregroundColor(Color("mode").opacity(0.2))
Text(label)
.textCase(.uppercase)
.font(.title2)
.foregroundColor(.gray.opacity(0.6))
.foregroundColor(Color("mode").opacity(0.6))
.padding(.horizontal, 10)
.frame(minWidth: 80)
Rectangle()
.frame(height: 1)
.foregroundColor(.gray.opacity(0.2))
.foregroundColor(Color("mode").opacity(0.2))
}
.frame(minHeight: 35)
}
@@ -497,7 +464,7 @@ struct SimpleSearchStyle: TextFieldStyle {
}
RoundedRectangle(cornerRadius: 6)
.strokeBorder(Color.gray.opacity(0.2), lineWidth: 1)
.strokeBorder(Color("mode").opacity(0.2), lineWidth: 1)
.allowsHitTesting(false)
}
}
@@ -767,7 +734,7 @@ struct PillPicker: View {
Text(i == 0 ? "Apps" : (i == 1 ? "Widgets" : "Plugins"))
.font(.system(size: 12))
.foregroundColor(index == i ? (colorScheme == .dark ? .black : Color("AccentColor")) : .gray)
.foregroundColor(index == i ? (colorScheme == .dark ? .black : Color("AccentColor")) : Color("mode"))
}
.padding(5)
.frame(height: 25)
@@ -826,3 +793,47 @@ struct PearDropView: View {
}
}
// Used for testing UI bounds
extension View {
func bounds() -> some View {
self.border(Color.red, width: 1)
}
}
@ViewBuilder
func backgroundView(themeSettings: ThemeSettings, darker: Bool = false, glass: Bool = false) -> some View {
if glass {
GlassEffect(material: .sidebar, blendingMode: .behindWindow)
.edgesIgnoringSafeArea(.all)
} else {
darker ? themeSettings.themeColor.darker(by: 5).edgesIgnoringSafeArea(.all) : themeSettings.themeColor.edgesIgnoringSafeArea(.all)
}
}
struct PresetColor: ButtonStyle {
var fillColor: Color
var label: String
func makeBody(configuration: Configuration) -> some View {
HStack(alignment: .center, spacing: 10) {
Circle()
.frame(width: 20, height: 20)
.fixedSize(horizontal: true, vertical: true)
.foregroundColor(fillColor)
.background(fillColor)
.clipShape(Circle())
.help(label)
.overlay(
RoundedRectangle(cornerRadius: 25)
.strokeBorder(Color("mode").opacity(0.8), lineWidth: 1.5))
// Text(label)
}
.onHover { inside in inside ? NSCursor.pointingHand.push() : NSCursor.pop() }
}
}
+59
View File
@@ -0,0 +1,59 @@
//
// ThemeManager.swift
// Pearcleaner
//
// Created by Alin Lupascu on 4/12/24.
//
import Foundation
import SwiftUI
import AppKit
class ThemeSettings: ObservableObject {
static let shared = ThemeSettings()
private let userDefaults = UserDefaults.standard
private let colorKey = "themeColor"
@Published var themeColor: Color {
didSet {
saveThemeColor()
}
}
// light - Color(.sRGB, red: 1.0, green: 1.0, blue: 1.0, opacity: 1)
// dark - Color(.sRGB, red: 0.149, green: 0.149, blue: 0.149, opacity: 1)
init() {
// Initialize color from UserDefaults or use a default value
if let components = UserDefaults.standard.object(forKey: colorKey) as? [CGFloat], components.count >= 4 {
themeColor = Color(.sRGB, red: components[0], green: components[1], blue: components[2], opacity: components[3])
} else {
themeColor = Color.clear
}
}
func saveThemeColor() {
let nsColor = NSColor(themeColor)
if let components = nsColor.cgColor.components {
UserDefaults.standard.set(components, forKey: colorKey)
}
}
func resetToDefault(dark: Bool = true) {
themeColor = dark ? Color(.sRGB, red: 0.149, green: 0.149, blue: 0.149, opacity: 1) : Color(.sRGB, red: 1.0, green: 1.0, blue: 1.0, opacity: 1)
saveThemeColor()
}
}
extension Color {
func darker(by percentage: CGFloat = 30.0) -> Color {
var hsb = (hue: CGFloat(0), saturation: CGFloat(0), brightness: CGFloat(0), alpha: CGFloat(0))
NSColor(self).getHue(&hsb.hue, saturation: &hsb.saturation, brightness: &hsb.brightness, alpha: &hsb.alpha)
return Color(hue: hsb.hue, saturation: hsb.saturation, brightness: max(hsb.brightness - percentage/100, 0), opacity: hsb.alpha)
}
func lighter(by percentage: CGFloat = 30.0) -> Color {
var hsb = (hue: CGFloat(0), saturation: CGFloat(0), brightness: CGFloat(0), alpha: CGFloat(0))
NSColor(self).getHue(&hsb.hue, saturation: &hsb.saturation, brightness: &hsb.brightness, alpha: &hsb.alpha)
return Color(hue: hsb.hue, saturation: hsb.saturation, brightness: min(hsb.brightness + percentage / 100, 1.0), opacity: hsb.alpha)
}
}