Files
Pearcleaner/Pearcleaner/Logic/AppState.swift
T
2024-08-01 18:09:32 -06:00

209 lines
5.2 KiB
Swift

//
// AppState.swift
// Pearcleaner
//
// Created by Alin Lupascu on 10/31/23.
//
import Foundation
import SwiftUI
import FinderSync
let home = FileManager.default.homeDirectoryForCurrentUser.path
class AppState: ObservableObject {
@Published var appInfo: AppInfo
// @Published var appInfoStore: [AppInfo] = []
@Published var trashedFiles: [AppInfo] = []
@Published var zombieFile: ZombieFile
@Published var sortedApps: [AppInfo] = []
@Published var selectedItems = Set<URL>()
@Published var currentView = CurrentDetailsView.empty
@Published var showAlert: Bool = false
@Published var sidebar: Bool = true
@Published var reload: Bool = false
@Published var showProgress: Bool = false
@Published var leftoverProgress: (String, Double) = ("", 0.0)
@Published var finderExtensionEnabled: Bool = false
@Published var showUninstallAlert: Bool = false
@Published var oneShotMode: Bool = false
@Published var showConditionBuilder: Bool = false
var operationQueueLeftover = OperationQueue()
@Published var shouldCancelOperations = false
func cancelQueueOperations() {
operationQueueLeftover.cancelAllOperations()
shouldCancelOperations = true
DispatchQueue.main.async {
self.leftoverProgress = ("Search canceled", 0.0)
self.showProgress = false
self.currentView = .empty
}
}
init() {
self.appInfo = AppInfo(
id: UUID(),
path: URL(fileURLWithPath: ""),
bundleIdentifier: "",
appName: "",
appVersion: "",
appIcon: nil,
webApp: false,
wrapped: false,
system: false,
arch: .empty,
bundleSize: 0,
files: [],
fileSize: [:],
fileSizeLogical: [:],
fileIcon: [:]
)
self.zombieFile = ZombieFile(
id: UUID(),
fileSize: [:],
fileSizeLogical: [:],
fileIcon: [:],
isDirectory: [:]
)
updateExtensionStatus()
NotificationCenter.default.addObserver(
self,
selector: #selector(updateExtensionStatus),
name: NSApplication.didBecomeActiveNotification,
object: nil
)
}
@objc func updateExtensionStatus() {
let extensionStatus = FIFinderSyncController.isExtensionEnabled
DispatchQueue.main.async {
self.finderExtensionEnabled = extensionStatus
}
}
func triggerUninstallAlert() {
self.showUninstallAlert = true
}
}
struct AppInfo: Identifiable, Equatable, Hashable {
let id: UUID
let path: URL
let bundleIdentifier: String
let appName: String
let appVersion: String
let appIcon: NSImage?
let webApp: Bool
let wrapped: Bool
let system: Bool
var arch: Arch
var bundleSize: Int64
var files: [URL]
var fileSize: [URL:Int64]
var fileSizeLogical: [URL:Int64]
var fileIcon: [URL:NSImage?]
var totalSize: Int64
{
return fileSize.values.reduce(0, +)
}
var totalSizeLogical: Int64
{
return fileSizeLogical.values.reduce(0, +)
}
static let empty = AppInfo(id: UUID(), path: URL(fileURLWithPath: ""), bundleIdentifier: "", appName: "", appVersion: "", appIcon: nil, webApp: false, wrapped: false, system: false, arch: .empty, bundleSize: 0, files: [], fileSize: [:], fileSizeLogical: [:], fileIcon: [:])
}
struct ZombieFile: Identifiable, Equatable, Hashable {
let id: UUID
var fileSize: [URL:Int64]
var fileSizeLogical: [URL:Int64]
var fileIcon: [URL:NSImage?]
var isDirectory: [URL:Bool]
var totalSize: Int64
{
return fileSize.values.reduce(0, +)
}
var totalSizeLogical: Int64
{
return fileSizeLogical.values.reduce(0, +)
}
static let empty = ZombieFile(id: UUID(), fileSize: [:], fileSizeLogical: [:], fileIcon: [:], isDirectory: [:])
}
extension ZombieFile {
/// Converts the data in ZombieFile into a list of Item instances.
func toItems() -> [Item] {
var items = [Item]()
// Iterate over each URL in fileSize to get corresponding properties
for (url, size) in fileSize {
let name = url.lastPathComponent
let isDir = isDirectory[url] ?? false
let parent = url.deletingLastPathComponent()
// Create an Item instance for each URL
let item = Item(url: url, name: name, size: size, isDirectory: isDir, parentURL: parent)
items.append(item)
}
return items//.sorted { $0.size > $1.size }
}
}
enum Arch {
case arm
case intel
case universal
case empty
}
enum CurrentTabView:Int
{
case general
case interface
case folders
case update
case tips
case about
var title: String {
switch self {
case .general: return "General"
case .interface: return "Interface"
case .folders: return "Folders"
case .update: return "Update"
case .tips: return "Tips"
case .about: return "About"
}
}
}
enum CurrentDetailsView:Int
{
case empty
case files
case apps
case zombie
}