diff --git a/Pearcleaner.xcodeproj/project.pbxproj b/Pearcleaner.xcodeproj/project.pbxproj index 4eb000c..9ad3464 100644 --- a/Pearcleaner.xcodeproj/project.pbxproj +++ b/Pearcleaner.xcodeproj/project.pbxproj @@ -568,8 +568,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - APP_BUILD = 46; - APP_VERSION = 3.7.1; + APP_BUILD = 47; + APP_VERSION = 3.7.2; 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 = 46; - APP_VERSION = 3.7.1; + APP_BUILD = 47; + APP_VERSION = 3.7.2; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; diff --git a/Pearcleaner/Logic/Styles.swift b/Pearcleaner/Logic/Styles.swift index 8faa37e..32a83ba 100644 --- a/Pearcleaner/Logic/Styles.swift +++ b/Pearcleaner/Logic/Styles.swift @@ -928,7 +928,7 @@ extension View { } } - +// Background color/glass setter @ViewBuilder func backgroundView(themeSettings: ThemeSettings, darker: Bool = false, glass: Bool = false) -> some View { if glass { @@ -940,6 +940,32 @@ func backgroundView(themeSettings: ThemeSettings, darker: Bool = false, glass: B } +struct PickerModifier: ViewModifier { + @State private var isHovered: Bool = false + let themeSettings: ThemeSettings + + func body(content: Content) -> some View { + content + .buttonStyle(.borderless) + .padding(4) + .background { + backgroundView(themeSettings: themeSettings, darker: isHovered) + .clipShape(RoundedRectangle(cornerRadius: 10)) + } + .onHover { hovering in + isHovered = hovering + } + } +} + +extension View { + func pickerStyle(themeSettings: ThemeSettings) -> some View { + self.modifier(PickerModifier(themeSettings: themeSettings)) + } +} + + +// Preset view elements struct PresetColor: ButtonStyle { var fillColor: Color var label: String diff --git a/Pearcleaner/Logic/Updater.swift b/Pearcleaner/Logic/Updater.swift index 56b8a08..1099d6a 100644 --- a/Pearcleaner/Logic/Updater.swift +++ b/Pearcleaner/Logic/Updater.swift @@ -170,35 +170,62 @@ func UnzipAndReplace(DownloadedFileURL fileURL: String, appState: AppState) { // --- Updater check frequency -func updateNextUpdateDate() { - @AppStorage("settings.updater.updateTimeframe") var updateTimeframe: Int = 1 - @AppStorage("settings.updater.nextUpdateDate") var nextUpdateDate = Date.now.timeIntervalSinceReferenceDate - let updateSeconds = updateTimeframe.daysToSeconds - let newUpdateDate = Calendar.current.startOfDay(for: Date().addingTimeInterval(updateSeconds)) - nextUpdateDate = newUpdateDate.timeIntervalSinceReferenceDate +enum UpdateFrequency: String, CaseIterable, Identifiable { + case none = "Never" + case daily = "Daily" + case weekly = "Weekly" + case monthly = "Monthly" + + var id: String { self.rawValue } + + var interval: TimeInterval? { + switch self { + case .none: + return nil + case .daily: + return 86400 // 1 day in seconds + case .weekly: + return 604800 // 7 days in seconds + case .monthly: + return 2592000 // 30 days in seconds + } + } + + func updateNextUpdateDate() { + guard let updateInterval = self.interval else { return } + let newUpdateDate = Calendar.current.startOfDay(for: Date().addingTimeInterval(updateInterval)) + UserDefaults.standard.set(newUpdateDate.timeIntervalSinceReferenceDate, forKey: "settings.updater.nextUpdateDate") + } } +//func updateNextUpdateDate() { +// @AppStorage("settings.updater.updateFrequency") var updateFrequency: UpdateFrequency = .daily +// @AppStorage("settings.updater.nextUpdateDate") var nextUpdateDate = Date.now.timeIntervalSinceReferenceDate +// +// guard let updateInterval = updateFrequency.interval else { return } +// let newUpdateDate = Calendar.current.startOfDay(for: Date().addingTimeInterval(updateInterval)) +// nextUpdateDate = newUpdateDate.timeIntervalSinceReferenceDate +//} + func checkAndUpdateIfNeeded(appState: AppState) { - @AppStorage("settings.updater.updateTimeframe") var updateTimeframe: Int = 1 + @AppStorage("settings.updater.updateFrequency") var updateFrequency: UpdateFrequency = .daily @AppStorage("settings.updater.nextUpdateDate") var nextUpdateDate = Date.now.timeIntervalSinceReferenceDate - let updateSeconds = updateTimeframe.daysToSeconds - let now = Date() + guard let updateInterval = updateFrequency.interval else { + printOS("Updater: no update frequency set, skipping check") + return + } - // Retrieve the next update date from UserDefaults + let now = Date() let nextUpdateDateLocal = Date(timeIntervalSinceReferenceDate: nextUpdateDate) -// let nextUpdateDate = UserDefaults.standard.object(forKey: "settings.updater.nextUpdateDate") as? Date - // If there's no stored next update date or it's in the past, update immediately if !isSameDay(date1: nextUpdateDateLocal, date2: now) { - // Next update date is in the future, no need to update - printOS("Updater: next update date is in the future, skipping") + printOS("Updater: next update date is in the future, skipping (\(nextUpdateDateLocal))") return } - // Update immediately and set next update date updateApp(appState: appState) - setNextUpdateDate(interval: updateSeconds) + setNextUpdateDate(interval: updateInterval) } func updateApp(appState: AppState) { @@ -210,13 +237,59 @@ func updateApp(appState: AppState) { func setNextUpdateDate(interval: TimeInterval) { let newUpdateDate = Calendar.current.startOfDay(for: Date().addingTimeInterval(interval)) UserDefaults.standard.set(newUpdateDate.timeIntervalSinceReferenceDate, forKey: "settings.updater.nextUpdateDate") -// UserDefaults.standard.set(newUpdateDate, forKey: "settings.updater.nextUpdateDate") } func isSameDay(date1: Date, date2: Date) -> Bool { return Calendar.current.isDate(date1, inSameDayAs: date2) } +//func updateNextUpdateDate() { +// @AppStorage("settings.updater.updateTimeframe") var updateTimeframe: Int = 1 +// @AppStorage("settings.updater.nextUpdateDate") var nextUpdateDate = Date.now.timeIntervalSinceReferenceDate +// let updateSeconds = updateTimeframe.daysToSeconds +// let newUpdateDate = Calendar.current.startOfDay(for: Date().addingTimeInterval(updateSeconds)) +// nextUpdateDate = newUpdateDate.timeIntervalSinceReferenceDate +//} +// +//func checkAndUpdateIfNeeded(appState: AppState) { +// @AppStorage("settings.updater.updateTimeframe") var updateTimeframe: Int = 1 +// @AppStorage("settings.updater.nextUpdateDate") var nextUpdateDate = Date.now.timeIntervalSinceReferenceDate +// +// let updateSeconds = updateTimeframe.daysToSeconds +// let now = Date() +// +// // Retrieve the next update date from UserDefaults +// let nextUpdateDateLocal = Date(timeIntervalSinceReferenceDate: nextUpdateDate) +//// let nextUpdateDate = UserDefaults.standard.object(forKey: "settings.updater.nextUpdateDate") as? Date +// +// // If there's no stored next update date or it's in the past, update immediately +// if !isSameDay(date1: nextUpdateDateLocal, date2: now) { +// // Next update date is in the future, no need to update +// printOS("Updater: next update date is in the future, skipping") +// return +// } +// +// // Update immediately and set next update date +// updateApp(appState: appState) +// setNextUpdateDate(interval: updateSeconds) +//} +// +//func updateApp(appState: AppState) { +// // Perform your update logic here +// printOS("Updater: performing update") +// loadGithubReleases(appState: appState) +//} +// +//func setNextUpdateDate(interval: TimeInterval) { +// let newUpdateDate = Calendar.current.startOfDay(for: Date().addingTimeInterval(interval)) +// UserDefaults.standard.set(newUpdateDate.timeIntervalSinceReferenceDate, forKey: "settings.updater.nextUpdateDate") +//// UserDefaults.standard.set(newUpdateDate, forKey: "settings.updater.nextUpdateDate") +//} +// +//func isSameDay(date1: Date, date2: Date) -> Bool { +// return Calendar.current.isDate(date1, inSameDayAs: date2) +//} + // --- Updater Badge View diff --git a/Pearcleaner/PearcleanerApp.swift b/Pearcleaner/PearcleanerApp.swift index 1e780fb..a95ff55 100644 --- a/Pearcleaner/PearcleanerApp.swift +++ b/Pearcleaner/PearcleanerApp.swift @@ -15,8 +15,7 @@ struct PearcleanerApp: App { @StateObject var locations = Locations() @StateObject var fsm = FolderSettingsManager() @State private var windowSettings = WindowSettings() -// @AppStorage("settings.updater.updateTimeframe") private var updateTimeframe: Int = 1 - @AppStorage("settings.updater.enableUpdates") private var enableUpdates: Bool = true + @AppStorage("settings.updater.updateFrequency") private var updateFrequency: UpdateFrequency = .daily @AppStorage("settings.permissions.hasLaunched") private var hasLaunched: Bool = false @AppStorage("displayMode") var displayMode: DisplayMode = .system @AppStorage("settings.general.mini") private var mini: Bool = false @@ -121,7 +120,7 @@ struct PearcleanerApp: App { // Get GH releases loadGithubReleases(appState: appState, releaseOnly: true) - if enableUpdates { + if updateFrequency != .none { // Update checker checkAndUpdateIfNeeded(appState: appState) } @@ -181,10 +180,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { findAndSetWindowFrame(named: ["Pearcleaner"], windowSettings: windowSettings) - if UserDefaults.standard.object(forKey: "themeColor") == nil { - self.appearanceChanged() - } +// if UserDefaults.standard.object(forKey: "themeColor") == nil { +// self.appearanceChanged() +// } + self.appearanceCheck() + if menubarEnabled { findAndHideWindows(named: ["Pearcleaner"]) NSApplication.shared.setActivationPolicy(.accessory) @@ -194,14 +195,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { observer = DistributedNotificationCenter.default().addObserver(forName: NSNotification.Name(rawValue: "AppleInterfaceThemeChangedNotification"), object: nil, queue: OperationQueue.main) { [weak self] _ in let themeMode = UserDefaults.standard.string(forKey: "settings.general.selectedTheme") if themeMode == "Auto" { - self?.appearanceChanged() + self?.appearanceCheck() } } } - func appearanceChanged() { + func appearanceCheck() { let dm = UserDefaults.standard.integer(forKey: "displayMode") var displayMode = DisplayMode(rawValue: dm) let dark = isDarkMode() diff --git a/Pearcleaner/Settings/Folders.swift b/Pearcleaner/Settings/Folders.swift index e686f02..5d3e346 100644 --- a/Pearcleaner/Settings/Folders.swift +++ b/Pearcleaner/Settings/Folders.swift @@ -20,6 +20,7 @@ struct FolderSettingsTab: View { @EnvironmentObject var appState: AppState @EnvironmentObject var locations: Locations @EnvironmentObject var fsm: FolderSettingsManager + @EnvironmentObject var themeSettings: ThemeSettings @State private var isHovered = false var body: some View { @@ -81,7 +82,8 @@ struct FolderSettingsTab: View { } .scrollIndicators(.automatic) .padding() - .background(Color("mode").opacity(0.05)) +// .background(Color("mode").opacity(0.05)) + .background(backgroundView(themeSettings: themeSettings, darker: true)) .clipShape(RoundedRectangle(cornerRadius: 10)) .onDrop(of: ["public.file-url"], isTargeted: nil) { providers -> Bool in providers.forEach { provider in @@ -173,7 +175,8 @@ struct FolderSettingsTab: View { } .scrollIndicators(.automatic) .padding() - .background(Color("mode").opacity(0.05)) + .background(backgroundView(themeSettings: themeSettings, darker: true)) +// .background(Color("mode").opacity(0.05)) .clipShape(RoundedRectangle(cornerRadius: 10)) .onDrop(of: ["public.file-url"], isTargeted: nil) { providers -> Bool in providers.forEach { provider in diff --git a/Pearcleaner/Settings/General.swift b/Pearcleaner/Settings/General.swift index b3e8cf3..01e8949 100644 --- a/Pearcleaner/Settings/General.swift +++ b/Pearcleaner/Settings/General.swift @@ -13,6 +13,7 @@ import FinderSync struct GeneralSettingsTab: View { @EnvironmentObject var appState: AppState @EnvironmentObject var locations: Locations + @EnvironmentObject var themeSettings: ThemeSettings @State private var windowSettings = WindowSettings() @AppStorage("settings.general.glass") private var glass: Bool = true @AppStorage("settings.general.mini") private var mini: Bool = false @@ -107,31 +108,13 @@ struct GeneralSettingsTab: View { } InfoButton(text: "When searching for app files or leftover files, the list will be sorted either alphabetically or by size(large to small)") Spacer() - SegmentedPicker( - ["Alpha", "Size"], - selectedIndex: Binding( - get: { selectedSortAlpha ? 0 : 1 }, - set: { newIndex in - withAnimation(.easeInOut(duration: 0.3)) { - selectedSortAlpha = (newIndex == 0) - } - }), - selectionAlignment: .bottom, - content: { item, isSelected in - Text(item) - .font(.callout) - .foregroundColor(isSelected ? Color("mode") : Color("mode").opacity(0.5)) - .padding(.horizontal) - .padding(.bottom, 5) - .frame(width: 75) - - }, - selection: { - VStack(spacing: 0) { - Spacer() - Color("pear").frame(height: 1) - } - }) + Picker("", selection: $selectedSortAlpha) { + Text("Alpha") + .tag(true) + Text("Size") + .tag(false) + } + .pickerStyle(themeSettings: themeSettings) } .padding(5) .padding(.leading) @@ -145,48 +128,23 @@ struct GeneralSettingsTab: View { .padding(.trailing) .foregroundStyle(Color("mode").opacity(0.5)) VStack(alignment: .leading, spacing: 5) { - Text("File size display") + Text("File size display mode") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) } InfoButton(text: "Real size type will show how much actual allocated space the file has on disk. Logical type shows the binary size. The filesystem can compress and deduplicate sectors on disk, so real size is sometimes smaller(or bigger) than logical size. Finder size is similar to if you right click > Get Info on a file in Finder, which will show both the logical and real sizes together.") Spacer() - SegmentedPicker( - ["Real", "Logical", "Finder"], - selectedIndex: Binding( - get: { - switch sizeType { - case "Real": return 0 - case "Logical": return 1 - case "Finder": return 2 - default: return 0 - } - }, - set: { newIndex in - withAnimation(.easeInOut(duration: 0.3)) { - switch newIndex { - case 0: sizeType = "Real" - case 1: sizeType = "Logical" - case 2: sizeType = "Finder" - default: sizeType = "Real" - } - } - }), - selectionAlignment: .bottom, - content: { item, isSelected in - Text(item) - .font(.callout) - .foregroundColor(isSelected ? Color("mode") : Color("mode").opacity(0.5) ) - .padding(.horizontal) - .padding(.bottom, 5) - .frame(width: 75) - }, - selection: { - VStack(spacing: 0) { - Spacer() - Color("pear").frame(height: 1) - } - }) + Picker("", selection: $sizeType) { + Text("Real") + .tag("Real") + Text("Logical") + .tag("Logical") + Text("Finder") + .tag("Finder") + } + .pickerStyle(themeSettings: themeSettings) + + } .padding(5) .padding(.leading) @@ -237,7 +195,7 @@ struct GeneralSettingsTab: View { .frame(width: 20, height: 20) .padding(.trailing) .foregroundStyle(diskStatus ? .green : .red) - .saturation(displayMode.colorScheme == .dark ? 0.5 : 1) + .saturation(displayMode.colorScheme == .dark ? 0.8 : 1) Text(diskStatus ? "Full Disk permission granted" : "Full Disk permission not granted") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) @@ -265,7 +223,7 @@ struct GeneralSettingsTab: View { .frame(width: 20, height: 20) .padding(.trailing) .foregroundStyle(accessStatus ? .green : .red) - .saturation(displayMode.colorScheme == .dark ? 0.5 : 1) + .saturation(displayMode.colorScheme == .dark ? 0.8 : 1) Text(accessStatus ? "Accessibility permission granted" : "Accessibility permission not granted") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) @@ -292,7 +250,7 @@ struct GeneralSettingsTab: View { .frame(width: 20, height: 20) .padding(.trailing) .foregroundStyle(autoStatus ? .green : .red) - .saturation(displayMode.colorScheme == .dark ? 0.5 : 1) + .saturation(displayMode.colorScheme == .dark ? 0.8 : 1) Text(autoStatus ? "Automation permission granted" : "Automation permission not granted") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) @@ -330,7 +288,7 @@ struct GeneralSettingsTab: View { .frame(width: 20, height: 20) .padding(.trailing) .foregroundStyle(sentinel ? .green : .red) - .saturation(displayMode.colorScheme == .dark ? 0.5 : 1) + .saturation(displayMode.colorScheme == .dark ? 0.8 : 1) Text(sentinel ? "Detecting when apps are moved to Trash" : "**NOT** detecting when apps are moved to Trash") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) @@ -371,7 +329,7 @@ struct GeneralSettingsTab: View { .frame(width: 20, height: 20) .padding(.trailing) .foregroundStyle(appState.finderExtensionEnabled ? .green : .red) - .saturation(displayMode.colorScheme == .dark ? 0.5 : 1) + .saturation(displayMode.colorScheme == .dark ? 0.8 : 1) Text(appState.finderExtensionEnabled ? "Context menu extension for Finder is enabled" : "Context menu extension for Finder is disabled") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) diff --git a/Pearcleaner/Settings/Interface.swift b/Pearcleaner/Settings/Interface.swift index 4a3fb6b..c033d2c 100644 --- a/Pearcleaner/Settings/Interface.swift +++ b/Pearcleaner/Settings/Interface.swift @@ -193,40 +193,15 @@ struct InterfaceSettingsTab: View { } InfoButton(text: "Changing the color mode will reset the base color to defaults") Spacer() - SegmentedPicker( - ["Auto", "Dark", "Light"], - selectedIndex: Binding( - get: { - switch selectedTheme { - case "Dark": return 1 - case "Light": return 2 - default: return 0 - } - }, - set: { newIndex in - withAnimation(.easeInOut(duration: 0.3)) { - switch newIndex { - case 1: selectedTheme = "Dark" - case 2: selectedTheme = "Light" - default: selectedTheme = "Auto" - } - } - }), - selectionAlignment: .bottom, - content: { item, isSelected in - Text(item) - .font(.callout) - .foregroundColor(isSelected ? Color("mode") : Color("mode").opacity(0.5) ) - .padding(.horizontal) - .padding(.bottom, 5) - .frame(width: 65) - }, - selection: { - VStack(spacing: 0) { - Spacer() - Color("pear").frame(height: 1) - } - }) + Picker("", selection: $selectedTheme) { + Text("Auto") + .tag("Auto") + Text("Dark") + .tag("Dark") + Text("Light") + .tag("Light") + } + .pickerStyle(themeSettings: themeSettings) .onChange(of: selectedTheme) { newTheme in switch newTheme { case "Auto": diff --git a/Pearcleaner/Settings/Update.swift b/Pearcleaner/Settings/Update.swift index 739c6e0..3378166 100644 --- a/Pearcleaner/Settings/Update.swift +++ b/Pearcleaner/Settings/Update.swift @@ -11,44 +11,36 @@ import Foundation struct UpdateSettingsTab: View { @EnvironmentObject var appState: AppState + @EnvironmentObject var themeSettings: ThemeSettings @State private var showAlert = false @State private var showDone = false @AppStorage("settings.updater.nextUpdateDate") private var nextUpdateDate = Date.now.timeIntervalSinceReferenceDate - @AppStorage("settings.updater.updateTimeframe") private var updateTimeframe: Int = 1 - @AppStorage("settings.updater.enableUpdates") private var enableUpdates: Bool = true + @AppStorage("settings.updater.updateFrequency") private var updateFrequency: UpdateFrequency = .daily var body: some View { VStack { - HStack(spacing: 0) { - Image(systemName: "arrow.down.square") - .resizable() - .scaledToFit() - .frame(width: 20, height: 20) - .padding(.trailing) - .foregroundStyle(Color("mode").opacity(0.5)) - VStack { HStack(spacing: 0) { - Text("\(enableUpdates ? "Pearcleaner will check for updates every " : "Automatic updates are disabled")") + + Text("Pearcleaner will check for updates") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) - if enableUpdates { - Text("**\(updateTimeframe)**").font(.system(.callout, design: .monospaced)).monospacedDigit() - Text(updateTimeframe == 1 ? " day" : " days") - .font(.callout) - .foregroundStyle(Color("mode").opacity(0.5)) + Spacer() - Stepper("", value: $updateTimeframe, in: 0...30) - .onChange(of: updateTimeframe, perform: { _ in - updateNextUpdateDate() - }) + Picker("", selection: $updateFrequency) { + ForEach(UpdateFrequency.allCases, id: \.self) { frequency in + Text(frequency.rawValue).tag(frequency) + } } - Spacer() + .onChange(of: updateFrequency) { frequency in + updateFrequency.updateNextUpdateDate() + } + .pickerStyle(themeSettings: themeSettings) } - if enableUpdates { + if updateFrequency != .none { HStack { Text("Next update check: \(formattedDate(Date(timeIntervalSinceReferenceDate: nextUpdateDate)))") .font(.footnote) @@ -56,18 +48,9 @@ struct UpdateSettingsTab: View { Spacer() } } - - - } - - Spacer() - Toggle(isOn: $enableUpdates, label: { - }) - .toggleStyle(.switch) - } - .padding(5) - .padding(.leading) + .padding(5) + .padding(.horizontal) ScrollView { VStack() { @@ -83,8 +66,11 @@ struct UpdateSettingsTab: View { } .frame(minHeight: 0, maxHeight: .infinity) .frame(minWidth: 0, maxWidth: .infinity) - .padding() - +// .background(Color("mode").opacity(0.05)) + .background(backgroundView(themeSettings: themeSettings, darker: true)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .padding(.bottom) + Text("Showing last 3 releases") .font(.callout) .foregroundStyle(Color("mode").opacity(0.5)) @@ -129,10 +115,6 @@ struct UpdateSettingsTab: View { } .padding(20) .frame(width: 500, height: 520) -// .onAppear { -// // Convert TimeInterval to Date on appearance -// let _ = Date(timeIntervalSinceReferenceDate: nextUpdateDate) -// } } } diff --git a/Pearcleaner/Views/AppListItems.swift b/Pearcleaner/Views/AppListItems.swift index deed71a..1f9746d 100644 --- a/Pearcleaner/Views/AppListItems.swift +++ b/Pearcleaner/Views/AppListItems.swift @@ -79,7 +79,7 @@ struct AppListItems: View { } if bundleSize == 0 { - ProgressView().controlSize(.mini) + ProgressView().controlSize(.mini).padding(.leading, 5) } else { Text("\(isHovered ? "v\(appInfo.appVersion)" : formatByte(size: bundleSize).human)") .font(.system(size: (isHovered || isSelected) ? 12 : 10)) diff --git a/Pearcleaner/Views/Picker/SegmentedPicker.swift b/Pearcleaner/Views/Picker/SegmentedPicker.swift index 4bd6dd4..6be2518 100644 --- a/Pearcleaner/Views/Picker/SegmentedPicker.swift +++ b/Pearcleaner/Views/Picker/SegmentedPicker.swift @@ -107,3 +107,105 @@ extension View { } } } + + +// SegmentedPicker( +// ["Alpha", "Size"], +// selectedIndex: Binding( +// get: { selectedSortAlpha ? 0 : 1 }, +// set: { newIndex in +// withAnimation(.easeInOut(duration: 0.3)) { +// selectedSortAlpha = (newIndex == 0) +// } +// }), +// selectionAlignment: .bottom, +// content: { item, isSelected in +// Text(item) +// .font(.callout) +// .foregroundColor(isSelected ? Color("mode") : Color("mode").opacity(0.5)) +// .padding(.horizontal) +// .padding(.bottom, 5) +// .frame(width: 75) +// +// }, +// selection: { +// VStack(spacing: 0) { +// Spacer() +// Color("pear").frame(height: 1) +// } +// }) + + +// SegmentedPicker( +// ["Real", "Logical", "Finder"], +// selectedIndex: Binding( +// get: { +// switch sizeType { +// case "Real": return 0 +// case "Logical": return 1 +// case "Finder": return 2 +// default: return 0 +// } +// }, +// set: { newIndex in +// withAnimation(.easeInOut(duration: 0.3)) { +// switch newIndex { +// case 0: sizeType = "Real" +// case 1: sizeType = "Logical" +// case 2: sizeType = "Finder" +// default: sizeType = "Real" +// } +// } +// }), +// selectionAlignment: .bottom, +// content: { item, isSelected in +// Text(item) +// .font(.callout) +// .foregroundColor(isSelected ? Color("mode") : Color("mode").opacity(0.5) ) +// .padding(.horizontal) +// .padding(.bottom, 5) +// .frame(width: 75) +// }, +// selection: { +// VStack(spacing: 0) { +// Spacer() +// Color("pear").frame(height: 1) +// } +// }) + + + +// SegmentedPicker( +// ["Auto", "Dark", "Light"], +// selectedIndex: Binding( +// get: { +// switch selectedTheme { +// case "Dark": return 1 +// case "Light": return 2 +// default: return 0 +// } +// }, +// set: { newIndex in +// withAnimation(.easeInOut(duration: 0.3)) { +// switch newIndex { +// case 1: selectedTheme = "Dark" +// case 2: selectedTheme = "Light" +// default: selectedTheme = "Auto" +// } +// } +// }), +// selectionAlignment: .bottom, +// content: { item, isSelected in +// Text(item) +// .font(.callout) +// .foregroundColor(isSelected ? Color("mode") : Color("mode").opacity(0.5) ) +// .padding(.horizontal) +// .padding(.bottom, 5) +// .frame(width: 65) +// }, +// selection: { +// VStack(spacing: 0) { +// Spacer() +// Color("pear").frame(height: 1) +// } +// })