- 清理:应用缓存、日志、浏览器缓存、Xcode/模拟器/npm 缓存、下载残留、安装包、废纸篓; 白名单目录 + 安全守卫,运行中的应用自动跳过,执行前逐项复核,操作日志 - 系统维护:刷新 DNS 缓存、释放内存(辅助工具或管理员授权) - 面板:去掉打开后的二次调整高度与窗口高度动画,内容放得下时不回弹, 修复点击菜单栏图标关闭时被重新打开 - 更换应用图标,面板与关于页使用应用图标作为 Logo - 清理未使用的组件、格式化方法、设计 token 与辅助工具接口
95 lines
3.1 KiB
Swift
95 lines
3.1 KiB
Swift
import AppKit
|
|
import Metrics
|
|
import SwiftUI
|
|
|
|
public struct PanelRootView: View {
|
|
@Environment(AppModel.self) private var model
|
|
@Environment(\.isSnapshot) private var isSnapshot
|
|
|
|
public init() {}
|
|
|
|
public var body: some View {
|
|
VStack(spacing: 0) {
|
|
PanelHeader()
|
|
.padding(DS.Space.s3)
|
|
|
|
HairlineDivider()
|
|
|
|
Group {
|
|
switch model.settings.panelTab {
|
|
case .overview: OverviewPage()
|
|
case .processes: ProcessesPage()
|
|
case .thermal: ThermalPage()
|
|
case .keepAwake: KeepAwakePage()
|
|
case .cleaner: CleanerPage()
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: isSnapshot ? nil : .infinity, alignment: .top)
|
|
}
|
|
.frame(width: DS.Size.panelWidth)
|
|
.frame(maxHeight: isSnapshot ? nil : .infinity, alignment: .top)
|
|
.fixedSize(horizontal: false, vertical: isSnapshot)
|
|
.background {
|
|
// 实际面板由窗口的液态玻璃底板提供背景;平铺(测量 / 截图)模式使用实色
|
|
if isSnapshot {
|
|
RoundedRectangle(cornerRadius: DS.Radius.xl).fill(DS.Palette.background)
|
|
}
|
|
}
|
|
.overlay {
|
|
if isSnapshot {
|
|
RoundedRectangle(cornerRadius: DS.Radius.xl).strokeBorder(DS.Palette.border, lineWidth: DS.Size.stroke)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct PanelHeader: View {
|
|
@Environment(AppModel.self) private var model
|
|
|
|
var body: some View {
|
|
@Bindable var settings = model.settings
|
|
|
|
HStack(spacing: DS.Space.s3) {
|
|
AppGlyph()
|
|
VStack(alignment: .leading, spacing: 0) {
|
|
Text("OpenStats")
|
|
.dsFont(.base, weight: .semibold)
|
|
.foregroundStyle(DS.Palette.textPrimary)
|
|
Text("状态栏监控")
|
|
.dsFont(.xs)
|
|
.foregroundStyle(DS.Palette.textSecondary)
|
|
}
|
|
.fixedSize()
|
|
|
|
Spacer(minLength: DS.Space.s3)
|
|
|
|
SegmentedControl(selection: $settings.panelTab,
|
|
options: PanelTab.allCases.map { ($0, $0.title) })
|
|
.frame(width: DS.Size.tabsWidth)
|
|
|
|
Spacer(minLength: DS.Space.s3)
|
|
|
|
if model.keepAwake.isActive {
|
|
Image(systemName: "cup.and.saucer.fill")
|
|
.font(.system(size: DS.TextSize.sm.rawValue, weight: .semibold))
|
|
.foregroundStyle(DS.Palette.primary)
|
|
.help("防休眠已开启")
|
|
}
|
|
IconButton(systemName: "gearshape", help: "设置") { model.openSettings() }
|
|
IconButton(systemName: "power", help: "退出 OpenStats") { model.quit() }
|
|
}
|
|
}
|
|
}
|
|
|
|
struct AppGlyph: View {
|
|
var size: CGFloat = DS.Size.controlHeight
|
|
|
|
var body: some View {
|
|
Image(nsImage: NSApp.applicationIconImage)
|
|
.resizable()
|
|
.interpolation(.high)
|
|
.frame(width: size, height: size)
|
|
.accessibilityHidden(true)
|
|
}
|
|
}
|