mirror of
https://github.com/exituser/Pearcleaner.git
synced 2026-09-17 04:58:56 +00:00
v3.6.5
This commit is contained in:
@@ -568,8 +568,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
APP_BUILD = 43;
|
||||
APP_VERSION = 3.6.4;
|
||||
APP_BUILD = 44;
|
||||
APP_VERSION = 3.6.5;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
@@ -638,8 +638,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
APP_BUILD = 43;
|
||||
APP_VERSION = 3.6.4;
|
||||
APP_BUILD = 44;
|
||||
APP_VERSION = 3.6.5;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
|
||||
@@ -32,6 +32,7 @@ class AppState: ObservableObject {
|
||||
@Published var permissionsOkay: Bool = true
|
||||
@Published var permissionResults: PermissionsCheckResults?
|
||||
@Published var showUninstallAlert: Bool = false
|
||||
@Published var oneShotMode: Bool = false
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import SwiftUI
|
||||
class DeeplinkManager {
|
||||
@Binding var showPopover: Bool
|
||||
@AppStorage("settings.general.mini") private var mini: Bool = false
|
||||
@AppStorage("settings.general.oneshot") private var oneShotMode: Bool = false
|
||||
|
||||
init(showPopover: Binding<Bool>) {
|
||||
_showPopover = showPopover
|
||||
@@ -27,7 +28,7 @@ class DeeplinkManager {
|
||||
if url.pathExtension == "app" {
|
||||
handleAppBundle(url: url, appState: appState, locations: locations)
|
||||
} else if url.scheme == DeepLinkConstants.scheme,
|
||||
// This handles SentinelMonitor FileWatcher
|
||||
// This handles SentinelMonitor FileWatcher and FinderOpen extension
|
||||
url.host == DeepLinkConstants.host,
|
||||
let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
|
||||
let queryItems = components.queryItems {
|
||||
@@ -35,6 +36,11 @@ class DeeplinkManager {
|
||||
let pathURL = URL(fileURLWithPath: path)
|
||||
let appInfo = AppInfoFetcher.getAppInfo(atPath: pathURL)
|
||||
showAppInFiles(appInfo: appInfo!, appState: appState, locations: locations, showPopover: $showPopover)
|
||||
if oneShotMode {
|
||||
updateOnMain {
|
||||
appState.oneShotMode = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printOS("No path query parameter found in the URL")
|
||||
}
|
||||
@@ -47,6 +53,12 @@ class DeeplinkManager {
|
||||
func handleAppBundle(url: URL, appState: AppState, locations: Locations) {
|
||||
let appInfo = AppInfoFetcher.getAppInfo(atPath: url)
|
||||
showAppInFiles(appInfo: appInfo!, appState: appState, locations: locations, showPopover: $showPopover)
|
||||
// Even if enabled, disable one-shot mode for app drops
|
||||
if oneShotMode {
|
||||
updateOnMain {
|
||||
appState.oneShotMode = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ struct GeneralSettingsTab: View {
|
||||
@AppStorage("displayMode") var displayMode: DisplayMode = .system
|
||||
@AppStorage("settings.sentinel.enable") private var sentinel: Bool = false
|
||||
@AppStorage("settings.general.brew") private var brew: Bool = false
|
||||
@AppStorage("settings.general.oneshot") private var oneShotMode: Bool = false
|
||||
@AppStorage("settings.general.selectedSort") var selectedSortAlpha: Bool = true
|
||||
@AppStorage("settings.general.sizeType") var sizeType: String = "Real"
|
||||
@State private var diskStatus: Bool = false
|
||||
@@ -68,6 +69,30 @@ struct GeneralSettingsTab: View {
|
||||
.padding(.leading)
|
||||
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Image(systemName: oneShotMode ? "scope" : "circlebadge")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
.padding(.trailing)
|
||||
.foregroundStyle(Color("mode").opacity(0.5))
|
||||
VStack(alignment: .leading, spacing: 5) {
|
||||
Text("\(oneShotMode ? "One-Shot Mode is enabled" : "One-Shot Mode is disabled")")
|
||||
.font(.callout)
|
||||
.foregroundStyle(Color("mode").opacity(0.5))
|
||||
}
|
||||
|
||||
InfoButton(text: "When one-shot mode is enabled, clicking the Uninstall button to remove an app will also close Pearcleaner right after. This only affects Pearcleaner when it is opened via external means, like Sentinel Trash Monitor or the Finder extension. This allows for single use of the app, AKA one-shot mode. When Pearcleaner is opened normally, this setting is ignored and will work as usual.")
|
||||
|
||||
Spacer()
|
||||
Toggle(isOn: $oneShotMode, label: {
|
||||
})
|
||||
.toggleStyle(.switch)
|
||||
}
|
||||
.padding(5)
|
||||
.padding(.leading)
|
||||
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Image(systemName: selectedSortAlpha ? "textformat.abc" : "textformat.123")
|
||||
.resizable()
|
||||
@@ -405,7 +430,7 @@ struct GeneralSettingsTab: View {
|
||||
|
||||
}
|
||||
.padding(20)
|
||||
.frame(width: 500, height: 670)
|
||||
.frame(width: 500, height: 710)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ struct InterfaceSettingsTab: View {
|
||||
@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.animateLogo") private var animateLogo: Bool = true
|
||||
// @AppStorage("settings.general.animateLogo") private var animateLogo: Bool = true
|
||||
@AppStorage("settings.general.selectedTheme") var selectedTheme: String = "Auto"
|
||||
@AppStorage("settings.interface.selectedMenubarIcon") var selectedMenubarIcon: String = "pear-4"
|
||||
@State private var isLaunchAtLoginEnabled: Bool = false
|
||||
@@ -76,34 +76,34 @@ struct InterfaceSettingsTab: View {
|
||||
.padding(.leading)
|
||||
|
||||
|
||||
HStack(spacing: 0) {
|
||||
Image(systemName: animateLogo ? "play.fill" : "pause")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
.padding(.trailing)
|
||||
.foregroundStyle(Color("mode").opacity(0.5))
|
||||
VStack(alignment: .leading, spacing: 5) {
|
||||
Text("\(animateLogo ? "Logo animation enabled" : "Logo animation disabled")")
|
||||
.font(.callout)
|
||||
.foregroundStyle(Color("mode").opacity(0.5))
|
||||
|
||||
}
|
||||
if !isMacOS14OrHigher {
|
||||
Text("(macOS 14+)")
|
||||
.font(.footnote)
|
||||
.foregroundStyle(Color("mode").opacity(0.3))
|
||||
.padding(.leading, 5)
|
||||
}
|
||||
// InfoButton(text: "The logo animation is only available in macOS 14 or higher")
|
||||
Spacer()
|
||||
Toggle(isOn: $animateLogo, label: {
|
||||
})
|
||||
.toggleStyle(.switch)
|
||||
.disabled(!isMacOS14OrHigher)
|
||||
}
|
||||
.padding(5)
|
||||
.padding(.leading)
|
||||
// HStack(spacing: 0) {
|
||||
// Image(systemName: animateLogo ? "play.fill" : "pause")
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .frame(width: 20, height: 20)
|
||||
// .padding(.trailing)
|
||||
// .foregroundStyle(Color("mode").opacity(0.5))
|
||||
// VStack(alignment: .leading, spacing: 5) {
|
||||
// Text("\(animateLogo ? "Logo animation enabled" : "Logo animation disabled")")
|
||||
// .font(.callout)
|
||||
// .foregroundStyle(Color("mode").opacity(0.5))
|
||||
//
|
||||
// }
|
||||
// if !isMacOS14OrHigher {
|
||||
// Text("(macOS 14+)")
|
||||
// .font(.footnote)
|
||||
// .foregroundStyle(Color("mode").opacity(0.3))
|
||||
// .padding(.leading, 5)
|
||||
// }
|
||||
//// InfoButton(text: "The logo animation is only available in macOS 14 or higher")
|
||||
// Spacer()
|
||||
// Toggle(isOn: $animateLogo, label: {
|
||||
// })
|
||||
// .toggleStyle(.switch)
|
||||
// .disabled(!isMacOS14OrHigher)
|
||||
// }
|
||||
// .padding(5)
|
||||
// .padding(.leading)
|
||||
|
||||
|
||||
|
||||
@@ -557,7 +557,7 @@ struct InterfaceSettingsTab: View {
|
||||
|
||||
}
|
||||
.padding(20)
|
||||
.frame(width: 500, height: 600)
|
||||
.frame(width: 500, height: 580)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -317,6 +317,11 @@ struct FilesView: View {
|
||||
}
|
||||
// Match found, remove the app
|
||||
removeApp(appState: appState, withPath: appState.appInfo.path)
|
||||
|
||||
if appState.oneShotMode {
|
||||
NSApp.terminate(nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
// Add deleted appInfo object to trashed array
|
||||
appState.trashedFiles.append(appState.appInfo)
|
||||
@@ -331,6 +336,9 @@ struct FilesView: View {
|
||||
appState.appInfo.fileSize = appState.appInfo.fileSize.filter { !appState.selectedItems.contains($0.key) }
|
||||
// Update the selectedFiles to remove references that are no longer present
|
||||
appState.selectedItems.removeAll()
|
||||
if appState.oneShotMode {
|
||||
NSApp.terminate(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,19 +52,17 @@ struct MiniEmptyView: View {
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@EnvironmentObject var appState: AppState
|
||||
@EnvironmentObject var locations: Locations
|
||||
@State private var animateGradient: Bool = false
|
||||
// @State private var animateGradient: Bool = false
|
||||
@AppStorage("settings.general.mini") private var mini: Bool = false
|
||||
@AppStorage("settings.general.animateLogo") private var animateLogo: Bool = true
|
||||
// @AppStorage("settings.general.animateLogo") private var animateLogo: Bool = true
|
||||
@Binding var showPopover: Bool
|
||||
@State private var animationStart = false
|
||||
// @State private var animationStart = false
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .center) {
|
||||
|
||||
Spacer()
|
||||
|
||||
if #available(macOS 14, *) {
|
||||
if animateLogo && animationStart {
|
||||
LinearGradient(gradient: Gradient(colors: [.green, .orange]), startPoint: .leading, endPoint: .trailing)
|
||||
.mask(
|
||||
Image(systemName: "plus.square.dashed")
|
||||
@@ -75,36 +73,49 @@ struct MiniEmptyView: View {
|
||||
.fontWeight(.ultraLight)
|
||||
.offset(x: 5, y: 5)
|
||||
)
|
||||
.phaseAnimator([false, true]) { wwdc24, chromaRotate in
|
||||
wwdc24
|
||||
.hueRotation(.degrees(chromaRotate ? 420 : 0))
|
||||
} animation: { chromaRotate in
|
||||
.easeInOut(duration: 6)
|
||||
}
|
||||
} else {
|
||||
LinearGradient(gradient: Gradient(colors: [.green, .orange]), startPoint: .leading, endPoint: .trailing)
|
||||
.mask(
|
||||
Image(systemName: "plus.square.dashed")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 120, height: 120, alignment: .center)
|
||||
.padding()
|
||||
.fontWeight(.ultraLight)
|
||||
.offset(x: 5, y: 5)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
LinearGradient(gradient: Gradient(colors: [.green, .orange]), startPoint: .leading, endPoint: .trailing)
|
||||
.mask(
|
||||
Image(systemName: "plus.square.dashed")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 120, height: 120, alignment: .center)
|
||||
.padding()
|
||||
.fontWeight(.ultraLight)
|
||||
.offset(x: 5, y: 5)
|
||||
)
|
||||
}
|
||||
|
||||
// if #available(macOS 14, *) {
|
||||
// if animateLogo && animationStart {
|
||||
// LinearGradient(gradient: Gradient(colors: [.green, .orange]), startPoint: .leading, endPoint: .trailing)
|
||||
// .mask(
|
||||
// Image(systemName: "plus.square.dashed")
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .frame(width: 120, height: 120, alignment: .center)
|
||||
// .padding()
|
||||
// .fontWeight(.ultraLight)
|
||||
// .offset(x: 5, y: 5)
|
||||
// )
|
||||
// .phaseAnimator([false, true]) { wwdc24, chromaRotate in
|
||||
// wwdc24
|
||||
// .hueRotation(.degrees(chromaRotate ? 420 : 0))
|
||||
// } animation: { chromaRotate in
|
||||
// .easeInOut(duration: 6)
|
||||
// }
|
||||
// } else {
|
||||
// LinearGradient(gradient: Gradient(colors: [.green, .orange]), startPoint: .leading, endPoint: .trailing)
|
||||
// .mask(
|
||||
// Image(systemName: "plus.square.dashed")
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .frame(width: 120, height: 120, alignment: .center)
|
||||
// .padding()
|
||||
// .fontWeight(.ultraLight)
|
||||
// .offset(x: 5, y: 5)
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// LinearGradient(gradient: Gradient(colors: [.green, .orange]), startPoint: .leading, endPoint: .trailing)
|
||||
// .mask(
|
||||
// Image(systemName: "plus.square.dashed")
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .frame(width: 120, height: 120, alignment: .center)
|
||||
// .padding()
|
||||
// .fontWeight(.ultraLight)
|
||||
// .offset(x: 5, y: 5)
|
||||
// )
|
||||
// }
|
||||
|
||||
Text("Drop an app here")
|
||||
.font(.title3)
|
||||
@@ -124,11 +135,11 @@ struct MiniEmptyView: View {
|
||||
appState.currentView = .apps
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
animationStart = true
|
||||
}
|
||||
}
|
||||
// .onAppear {
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
// animationStart = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +152,7 @@ struct MiniAppView: View {
|
||||
@EnvironmentObject var appState: AppState
|
||||
@EnvironmentObject var locations: Locations
|
||||
@EnvironmentObject var themeSettings: ThemeSettings
|
||||
@State private var animateGradient: Bool = false
|
||||
// @State private var animateGradient: Bool = false
|
||||
@Binding var search: String
|
||||
@State private var showSys: Bool = true
|
||||
@State private var showUsr: Bool = true
|
||||
|
||||
@@ -86,30 +86,31 @@ struct AppDetailsEmptyView: View {
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@EnvironmentObject var appState: AppState
|
||||
@EnvironmentObject var locations: Locations
|
||||
@AppStorage("settings.general.animateLogo") private var animateLogo: Bool = true
|
||||
// @AppStorage("settings.general.animateLogo") private var animateLogo: Bool = true
|
||||
@Binding var showPopover: Bool
|
||||
@State private var animationStart = false
|
||||
// @State private var animationStart = false
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .center) {
|
||||
|
||||
Spacer()
|
||||
if #available(macOS 14, *) {
|
||||
if animateLogo && animationStart {
|
||||
PearDropView()
|
||||
.phaseAnimator([false, true]) { wwdc24, chromaRotate in
|
||||
wwdc24
|
||||
.hueRotation(.degrees(chromaRotate ? 420 : 0))
|
||||
} animation: { chromaRotate in
|
||||
.easeInOut(duration: 6)
|
||||
}
|
||||
} else {
|
||||
PearDropView()
|
||||
}
|
||||
|
||||
} else {
|
||||
PearDropView()
|
||||
}
|
||||
// if #available(macOS 14, *) {
|
||||
// if animateLogo && animationStart {
|
||||
// PearDropView()
|
||||
// .phaseAnimator([false, true]) { wwdc24, chromaRotate in
|
||||
// wwdc24
|
||||
// .hueRotation(.degrees(chromaRotate ? 420 : 0))
|
||||
// } animation: { chromaRotate in
|
||||
// .easeInOut(duration: 6)
|
||||
// }
|
||||
// } else {
|
||||
// PearDropView()
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// PearDropView()
|
||||
// }
|
||||
|
||||
Spacer()
|
||||
|
||||
@@ -118,10 +119,10 @@ struct AppDetailsEmptyView: View {
|
||||
.padding(.bottom, 25)
|
||||
.opacity(0.5)
|
||||
}
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
animationStart = true
|
||||
}
|
||||
}
|
||||
// .onAppear {
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
// animationStart = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user