Skip to content

Commit

Permalink
v4.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
alienator88 committed Feb 3, 2025
1 parent 53ad8ff commit 0f0475f
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 140 deletions.
8 changes: 4 additions & 4 deletions Pearcleaner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUILD = 72;
APP_VERSION = 4.0.6;
APP_BUILD = 73;
APP_VERSION = 4.1.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
Expand Down Expand Up @@ -629,8 +629,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUILD = 72;
APP_VERSION = 4.0.6;
APP_BUILD = 73;
APP_VERSION = 4.1.0;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
Expand Down
1 change: 1 addition & 0 deletions Pearcleaner/Logic/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AppState: ObservableObject {
@Published var finderExtensionEnabled: Bool = false
@Published var showUninstallAlert: Bool = false
@Published var externalMode: Bool = false
@Published var multiMode: Bool = false
@Published var externalPaths: [URL] = [] // for handling multiple app from drops or deeplinks
@Published var selectedEnvironment: PathEnv? // for handling dev environments

Expand Down
10 changes: 7 additions & 3 deletions Pearcleaner/Logic/Styles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ struct SimpleCheckboxToggleStyle: ToggleStyle {
.scaleEffect(isHovered ? 0.8 : 1.0)
}
}
.overlay {
RoundedRectangle(cornerRadius: 4)
.strokeBorder(themeManager.pickerColor.adjustBrightness(-5.0), lineWidth: 1)
}
.onTapGesture {
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
configuration.isOn.toggle()
Expand Down Expand Up @@ -378,7 +382,7 @@ public struct SlideableDivider: View {
}
.contextMenu {
Button("Reset Size") {
dimension = 280
dimension = 300
}
}
.gesture(drag)
Expand All @@ -395,8 +399,8 @@ public struct SlideableDivider: View {
let newDimension = dimensionStart! + Double(delta)

// Set minimum and maximum width
let minWidth: Double = 220
let maxWidth: Double = 330
let minWidth: Double = 240
let maxWidth: Double = 350
dimension = max(minWidth, min(maxWidth, newDimension))
NSCursor.closedHand.set()
handleWidth = 6
Expand Down
1 change: 0 additions & 1 deletion Pearcleaner/PearcleanerApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ struct PearcleanerApp: App {

return true
}

.onOpenURL(perform: { url in
let deeplinkManager = DeeplinkManager(showPopover: $showPopover, updater: updater, fsm: fsm)
deeplinkManager.manage(url: url, appState: appState, locations: locations)
Expand Down
230 changes: 122 additions & 108 deletions Pearcleaner/Views/AppListItems.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,135 +31,149 @@ struct AppListItems: View {

var body: some View {

Button(action: {
if !isSelected {
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
showAppInFiles(appInfo: appInfo, appState: appState, locations: locations, showPopover: $showPopover)
HStack {

Toggle(isOn: Binding(
get: { self.appState.externalPaths.contains(self.appInfo.path) },
set: { isChecked in
if isChecked {
if !self.appState.externalPaths.contains(self.appInfo.path) {
let wasEmpty = self.appState.externalPaths.isEmpty
self.appState.externalPaths.append(self.appInfo.path)

if wasEmpty && appState.currentView != .files {
appState.multiMode = true
showAppInFiles(appInfo: appInfo, appState: appState, locations: locations, showPopover: $showPopover)
}
}
} else {
self.appState.externalPaths.removeAll { $0 == self.appInfo.path }

if self.appState.externalPaths.isEmpty {
appState.multiMode = false
}
}
}
} else {
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
updateOnMain {
appState.appInfo = .empty
appState.selectedItems = []
appState.currentView = miniView ? .apps : .empty
showPopover = false
)) { EmptyView() }
.toggleStyle(SimpleCheckboxToggleStyle())
.padding(.leading)

Button(action: {
if !isSelected {
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
showAppInFiles(appInfo: appInfo, appState: appState, locations: locations, showPopover: $showPopover)
}
} else {
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
updateOnMain {
appState.appInfo = .empty
appState.selectedItems = []
appState.currentView = miniView ? .apps : .empty
showPopover = false
}
}
}
}

}) {
VStack() {
}) {
VStack() {

HStack(alignment: .center) {
HStack(alignment: .center) {

if let appIcon = appInfo.appIcon {
ZStack {
Image(nsImage: appIcon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30)
.clipShape(RoundedRectangle(cornerRadius: 8))
}

}

if minimalEnabled {
Text(appInfo.appName)
.font(.system(size: (isSelected) ? 14 : 12))
.lineLimit(1)
.truncationMode(.tail)
} else {
VStack(alignment: .center, spacing: 2) {
HStack {
Text(appInfo.appName)
.font(.system(size: (isSelected) ? 14 : 12))
.lineLimit(1)
.truncationMode(.tail)
Spacer()
}

HStack(spacing: 5) {
Text(verbatim: "v\(appInfo.appVersion)")
.font(.footnote)
.lineLimit(1)
.truncationMode(.tail)
.opacity(0.5)
Text(verbatim: "").font(.footnote).opacity(0.5)

Text(appInfo.bundleSize == 0 ? String(localized: "calculating") : "\(formatByte(size: appInfo.bundleSize).human)")
.font(.footnote)
.lineLimit(1)
.truncationMode(.tail)
.opacity(0.5)
Spacer()
if let appIcon = appInfo.appIcon {
ZStack {
Image(nsImage: appIcon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30)
.clipShape(RoundedRectangle(cornerRadius: 8))
}

}
}

if minimalEnabled {
Text(appInfo.appName)
.font(.system(size: (isSelected) ? 14 : 12))
.lineLimit(1)
.truncationMode(.tail)
} else {
VStack(alignment: .center, spacing: 2) {
HStack {
Text(appInfo.appName)
.font(.system(size: (isSelected) ? 14 : 12))
.lineLimit(1)
.truncationMode(.tail)
Spacer()
}

HStack(spacing: 5) {
Text(verbatim: "v\(appInfo.appVersion)")
.font(.footnote)
.lineLimit(1)
.truncationMode(.tail)
.opacity(0.5)
Text(verbatim: "").font(.footnote).opacity(0.5)

Text(appInfo.bundleSize == 0 ? String(localized: "calculating") : "\(formatByte(size: appInfo.bundleSize).human)")
.font(.footnote)
.lineLimit(1)
.truncationMode(.tail)
.opacity(0.5)
Spacer()
}

if appInfo.webApp {
Image(systemName: "safari")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundStyle(.primary.opacity(0.3))
.symbolRenderingMode(.monochrome)
.help("Web app")
.padding(.trailing, 5)
}
if appInfo.wrapped {
Image(systemName: "iphone")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundStyle(.primary.opacity(0.3))
.symbolRenderingMode(.monochrome)
.help("iOS app")
.padding(.trailing, 5)
}
}
}

if minimalEnabled {
Spacer()
}

if minimalEnabled && !isSelected {
// Text(appInfo.bundleSize == 0 ? "v\(appInfo.appVersion)" : (isHovered ? "v\(appInfo.appVersion)" : formatByte(size: appInfo.bundleSize).human))
Text(appInfo.bundleSize == 0 ? "v\(appInfo.appVersion)" : formatByte(size: appInfo.bundleSize).human)
.font(.system(size: 10))
.foregroundStyle(.primary.opacity(0.5))
}
if appInfo.webApp {
Image(systemName: "safari")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundStyle(.primary.opacity(0.3))
.symbolRenderingMode(.monochrome)
.help("Web app")
.padding(.trailing, 5)
}
if appInfo.wrapped {
Image(systemName: "iphone")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundStyle(.primary.opacity(0.3))
.symbolRenderingMode(.monochrome)
.help("iOS app")
.padding(.trailing, 5)
}

// if isSelected && !(mini || menubarEnabled) {
// Button("Close") {
// withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
// updateOnMain {
// appState.appInfo = .empty
// appState.selectedItems = []
// appState.currentView = miniView ? .apps : .empty
// showPopover = false
// }
// }
//
// }
// .buttonStyle(SimpleButtonStyle(icon: "x.circle", iconFlip: "x.circle.fill", help: String(localized: "Close"), size: 16))
// }
if minimalEnabled {
Spacer()
}

if minimalEnabled && !isSelected {
Text(appInfo.bundleSize == 0 ? "v\(appInfo.appVersion)" : formatByte(size: appInfo.bundleSize).human)
.font(.system(size: 10))
.foregroundStyle(.primary.opacity(0.5))
}
}

}

.frame(height: 35)
.padding(.trailing)
.padding(.vertical, 5)
}
.frame(height: 35)
.padding(.horizontal)
.padding(.vertical, 5)
}
.buttonStyle(.borderless)
.foregroundStyle(.primary)
.onHover { hovering in
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.20 : 0)) {
self.isHovered = hovering
self.hoveredItemPath = isHovered ? appInfo.path : nil
.buttonStyle(.borderless)
.foregroundStyle(.primary)
.onHover { hovering in
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.20 : 0)) {
self.isHovered = hovering
self.hoveredItemPath = isHovered ? appInfo.path : nil
}
}


}
.background{
Rectangle()
Expand Down
44 changes: 23 additions & 21 deletions Pearcleaner/Views/FilesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -468,25 +468,26 @@ struct FilesView: View {
}

// Process the next app if in external mode
if appState.externalMode {
processNextExternalApp(appWasRemoved: appWasRemoved)
} else {
// Not in external mode
if appWasRemoved {
// Now update the UI to reflect that the app has been removed
updateOnMain {
search = ""
withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
if mini || menubarEnabled {
appState.currentView = .apps
showPopover = false
} else {
appState.currentView = .empty
}
}
}
}
}
processNextExternalApp(appWasRemoved: appWasRemoved)
// if appState.externalMode || appState.multiMode {
// processNextExternalApp(appWasRemoved: appWasRemoved)
// } else {
// // Not in external mode
// if appWasRemoved {
// // Now update the UI to reflect that the app has been removed
// updateOnMain {
// search = ""
// withAnimation(Animation.easeInOut(duration: animationEnabled ? 0.35 : 0)) {
// if mini || menubarEnabled {
// appState.currentView = .apps
// showPopover = false
// } else {
// appState.currentView = .empty
// }
// }
// }
// }
// }
}
}
}
Expand Down Expand Up @@ -518,13 +519,14 @@ struct FilesView: View {
}

// Terminate if oneShotMode is enabled
if oneShotMode {
if oneShotMode && !appState.multiMode {
updateOnMain(after: 2) {
NSApp.terminate(nil)
}
} else {
// Reset external mode
// Reset external/multi mode
appState.externalMode = false
appState.multiMode = false
}
} else if let nextPath = appState.externalPaths.first {
// More paths exist; continue processing
Expand Down
2 changes: 1 addition & 1 deletion Pearcleaner/Views/RegularMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct RegularMode: View {
@EnvironmentObject var locations: Locations
@EnvironmentObject var fsm: FolderSettingsManager
@AppStorage("settings.general.glass") private var glass: Bool = false
@AppStorage("settings.general.sidebarWidth") private var sidebarWidth: Double = 280
@AppStorage("settings.general.sidebarWidth") private var sidebarWidth: Double = 300
@AppStorage("settings.menubar.enabled") private var menubarEnabled: Bool = false
@AppStorage("settings.general.mini") private var mini: Bool = false
@AppStorage("settings.interface.animationEnabled") private var animationEnabled: Bool = true
Expand Down
Loading

0 comments on commit 0f0475f

Please sign in to comment.