- 清理:应用缓存、日志、浏览器缓存、Xcode/模拟器/npm 缓存、下载残留、安装包、废纸篓; 白名单目录 + 安全守卫,运行中的应用自动跳过,执行前逐项复核,操作日志 - 系统维护:刷新 DNS 缓存、释放内存(辅助工具或管理员授权) - 面板:去掉打开后的二次调整高度与窗口高度动画,内容放得下时不回弹, 修复点击菜单栏图标关闭时被重新打开 - 更换应用图标,面板与关于页使用应用图标作为 Logo - 清理未使用的组件、格式化方法、设计 token 与辅助工具接口
108 lines
3.7 KiB
Swift
108 lines
3.7 KiB
Swift
import Foundation
|
|
import Metrics
|
|
import Observation
|
|
import ServiceManagement
|
|
import SMC
|
|
|
|
/// 应用状态总入口,注入到所有 SwiftUI 视图
|
|
@MainActor
|
|
@Observable
|
|
public final class AppModel {
|
|
public let settings: AppSettings
|
|
public let store: MetricsStore
|
|
public let helper: HelperClient
|
|
public let fans: FanController
|
|
public let keepAwake: KeepAwakeController
|
|
public let cleaner: CleanerController
|
|
public let maintenance: MaintenanceController
|
|
@ObservationIgnored public let hub = MetricsHub()
|
|
|
|
public var isPanelVisible = false
|
|
public private(set) var launchAtLoginEnabled = SMAppService.mainApp.status == .enabled
|
|
public private(set) var launchAtLoginError: String?
|
|
|
|
@ObservationIgnored var openSettings: () -> Void = {}
|
|
@ObservationIgnored var quit: () -> Void = {}
|
|
|
|
public init(settings: AppSettings = AppSettings()) {
|
|
let store = MetricsStore()
|
|
let helper = HelperClient()
|
|
self.settings = settings
|
|
self.store = store
|
|
self.helper = helper
|
|
fans = FanController(helper: helper, store: store, settings: settings)
|
|
keepAwake = KeepAwakeController(helper: helper, settings: settings)
|
|
cleaner = CleanerController(settings: settings)
|
|
maintenance = MaintenanceController(helper: helper)
|
|
}
|
|
|
|
/// 根据当前可见内容决定采集范围
|
|
var demand: MetricsDemand {
|
|
var demand = MetricsDemand()
|
|
let tab = settings.panelTab
|
|
let panel = isPanelVisible
|
|
let menu = settings.menuBarItems
|
|
|
|
demand.interval = panel ? .seconds(1) : .seconds(settings.refreshSeconds)
|
|
demand.memory = true
|
|
demand.network = true
|
|
demand.gpu = (panel && tab == .overview) || menu.contains(.gpu)
|
|
demand.disk = panel && (tab == .overview || tab == .cleaner)
|
|
demand.battery = (panel && (tab == .overview || tab == .keepAwake)) || keepAwake.lidClosedActive
|
|
demand.processes = panel && (tab == .processes || tab == .overview)
|
|
|
|
var groups = Set<TemperatureGroup>()
|
|
if panel && tab == .overview { groups.formUnion([.cpu, .gpu]) }
|
|
if panel && tab == .thermal { groups.formUnion(TemperatureGroup.allCases) }
|
|
if menu.contains(.temperature) || fans.mode != .automatic { groups.insert(.cpu) }
|
|
demand.temperatures = groups
|
|
demand.fans = (panel && (tab == .thermal || tab == .overview)) || menu.contains(.fan) || fans.mode != .automatic
|
|
return demand
|
|
}
|
|
|
|
func refreshLaunchAtLogin() {
|
|
launchAtLoginEnabled = SMAppService.mainApp.status == .enabled
|
|
}
|
|
|
|
func setLaunchAtLogin(_ enabled: Bool) {
|
|
launchAtLoginError = nil
|
|
do {
|
|
if enabled {
|
|
try SMAppService.mainApp.register()
|
|
} else {
|
|
try SMAppService.mainApp.unregister()
|
|
}
|
|
} catch {
|
|
launchAtLoginError = error.localizedDescription
|
|
}
|
|
refreshLaunchAtLogin()
|
|
}
|
|
|
|
/// 概览页快捷切换风扇:未安装辅助工具时跳到散热页引导安装
|
|
func requestFanMode(_ mode: FanController.Mode) {
|
|
guard helper.isReady else {
|
|
settings.panelTab = .thermal
|
|
return
|
|
}
|
|
Task { await fans.select(mode) }
|
|
}
|
|
|
|
/// 概览页快捷开关合盖运行:同时开启防休眠
|
|
func requestLidMode(_ enabled: Bool) {
|
|
guard helper.isReady else {
|
|
settings.panelTab = .keepAwake
|
|
return
|
|
}
|
|
Task {
|
|
await keepAwake.setLidClosed(enabled)
|
|
if enabled, !keepAwake.isActive { await keepAwake.start() }
|
|
}
|
|
}
|
|
|
|
func handle(_ snapshot: MetricsSnapshot) {
|
|
store.apply(snapshot)
|
|
fans.evaluateSafety()
|
|
keepAwake.evaluateBattery(store.battery)
|
|
}
|
|
}
|