Working stuffgit add .

This commit is contained in:
Hariharan Mudaliar 2025-10-19 02:20:26 +05:30
commit 630431a008
15 changed files with 2577 additions and 308 deletions

View file

@ -56,15 +56,19 @@ struct NotchStatsView: View {
@State private var showingCPUPopover = false
@State private var showingMemoryPopover = false
@State private var showingGPUPopover = false
@State private var showingNetworkPopover = false
@State private var showingDiskPopover = false
@State private var isHoveringCPUPopover = false
@State private var isHoveringMemoryPopover = false
@State private var isHoveringGPUPopover = false
@State private var isHoveringNetworkPopover = false
@State private var isHoveringDiskPopover = false
@State private var isResizingForStats = false
@EnvironmentObject var vm: DynamicIslandViewModel
var availableGraphs: [GraphData] {
var graphs: [GraphData] = []
if showCpuGraph {
graphs.append(SingleGraphData(
title: "CPU",
@ -74,7 +78,7 @@ struct NotchStatsView: View {
icon: "cpu"
))
}
if showMemoryGraph {
graphs.append(SingleGraphData(
title: "Memory",
@ -84,7 +88,7 @@ struct NotchStatsView: View {
icon: "memorychip"
))
}
if showGpuGraph {
graphs.append(SingleGraphData(
title: "GPU",
@ -94,7 +98,7 @@ struct NotchStatsView: View {
icon: "display"
))
}
if showNetworkGraph {
graphs.append(DualGraphData(
title: "Network",
@ -108,7 +112,7 @@ struct NotchStatsView: View {
icon: "network"
))
}
if showDiskGraph {
graphs.append(DualGraphData(
title: "Disk",
@ -122,15 +126,15 @@ struct NotchStatsView: View {
icon: "internaldrive"
))
}
return graphs
}
// Smart grid layout system for different graph counts
@ViewBuilder
var statsGridLayout: some View {
let graphCount = availableGraphs.count
if graphCount <= 3 {
// 1-3 graphs: Single row with equal spacing
LazyVGrid(
@ -163,7 +167,7 @@ struct NotchStatsView: View {
graphViewForIndex(index)
}
}
// Second row: 2 graphs (half-width each)
LazyVGrid(
columns: Array(repeating: GridItem(.flexible(), spacing: 8), count: 2),
@ -176,13 +180,12 @@ struct NotchStatsView: View {
}
}
}
@ViewBuilder
private func graphViewForIndex(_ index: Int) -> some View {
let graphData = availableGraphs[index]
// Only make CPU, Memory, GPU clickable for process popovers
if graphData.title == "CPU" || graphData.title == "Memory" || graphData.title == "GPU" {
if let rankingType = rankingTypeForGraph(graphData) {
Button(action: {
handleGraphClick(for: graphData)
}) {
@ -191,7 +194,7 @@ struct NotchStatsView: View {
.buttonStyle(PlainButtonStyle())
.popover(isPresented: bindingForGraph(graphData)) {
RankedProcessPopover(
rankingType: rankingTypeForGraph(graphData),
rankingType: rankingType,
onHoverChange: { hovering in
switch graphData.title {
case "CPU":
@ -200,13 +203,16 @@ struct NotchStatsView: View {
isHoveringMemoryPopover = hovering
case "GPU":
isHoveringGPUPopover = hovering
case "Network":
isHoveringNetworkPopover = hovering
case "Disk":
isHoveringDiskPopover = hovering
default:
break
}
}
)
.onDisappear {
// Reset hover states when popover disappears
switch graphData.title {
case "CPU":
isHoveringCPUPopover = false
@ -214,10 +220,13 @@ struct NotchStatsView: View {
isHoveringMemoryPopover = false
case "GPU":
isHoveringGPUPopover = false
case "Network":
isHoveringNetworkPopover = false
case "Disk":
isHoveringDiskPopover = false
default:
break
}
// Ensure popover state is updated when popover disappears
DispatchQueue.main.async {
updateStatsPopoverState()
}
@ -228,7 +237,6 @@ struct NotchStatsView: View {
removal: .scale.combined(with: .opacity).animation(.easeInOut(duration: 0.4))
))
} else {
// Network and Disk graphs are not clickable
UnifiedStatsCard(graphData: graphData)
.transition(.asymmetric(
insertion: .scale.combined(with: .opacity).animation(.easeInOut(duration: 0.4)),
@ -236,7 +244,7 @@ struct NotchStatsView: View {
))
}
}
private func handleGraphClick(for graphData: GraphData) {
switch graphData.title {
case "CPU":
@ -245,11 +253,15 @@ struct NotchStatsView: View {
showingMemoryPopover = true
case "GPU":
showingGPUPopover = true
case "Network":
showingNetworkPopover = true
case "Disk":
showingDiskPopover = true
default:
break
}
}
private func bindingForGraph(_ graphData: GraphData) -> Binding<Bool> {
switch graphData.title {
case "CPU":
@ -258,12 +270,16 @@ struct NotchStatsView: View {
return $showingMemoryPopover
case "GPU":
return $showingGPUPopover
case "Network":
return $showingNetworkPopover
case "Disk":
return $showingDiskPopover
default:
return .constant(false)
}
}
private func rankingTypeForGraph(_ graphData: GraphData) -> ProcessRankingType {
private func rankingTypeForGraph(_ graphData: GraphData) -> ProcessRankingType? {
switch graphData.title {
case "CPU":
return .cpu
@ -271,8 +287,12 @@ struct NotchStatsView: View {
return .memory
case "GPU":
return .gpu
case "Network":
return .network
case "Disk":
return .disk
default:
return .cpu
return nil
}
}
@ -323,7 +343,6 @@ struct NotchStatsView: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding()
} else {
// Stats content with smart grid layout
VStack(spacing: 8) {
statsGridLayout
}
@ -349,7 +368,7 @@ struct NotchStatsView: View {
}
.animation(.easeInOut(duration: 0.4), value: enableStatsFeature)
.animation(.easeInOut(duration: 0.4), value: availableGraphs.count)
.onChange(of: availableGraphs.count) { _, newCount in
.onChange(of: availableGraphs.count) { _, _ in
// Protect against hover interference during dynamic sizing
isResizingForStats = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
@ -365,6 +384,12 @@ struct NotchStatsView: View {
.onChange(of: showingGPUPopover) { _, _ in
updateStatsPopoverState()
}
.onChange(of: showingNetworkPopover) { _, _ in
updateStatsPopoverState()
}
.onChange(of: showingDiskPopover) { _, _ in
updateStatsPopoverState()
}
.onChange(of: isHoveringCPUPopover) { _, _ in
updateStatsPopoverState()
}
@ -374,15 +399,23 @@ struct NotchStatsView: View {
.onChange(of: isHoveringGPUPopover) { _, _ in
updateStatsPopoverState()
}
.onChange(of: isHoveringNetworkPopover) { _, _ in
updateStatsPopoverState()
}
.onChange(of: isHoveringDiskPopover) { _, _ in
updateStatsPopoverState()
}
}
private func updateStatsPopoverState() {
// Use the same logic as battery popover: active only when shown AND hovered
// Also consider resize protection to prevent closing during layout changes
let newState = (showingCPUPopover && isHoveringCPUPopover) ||
(showingMemoryPopover && isHoveringMemoryPopover) ||
(showingGPUPopover && isHoveringGPUPopover) ||
isResizingForStats
let newState = (showingCPUPopover && isHoveringCPUPopover) ||
(showingMemoryPopover && isHoveringMemoryPopover) ||
(showingGPUPopover && isHoveringGPUPopover) ||
(showingNetworkPopover && isHoveringNetworkPopover) ||
(showingDiskPopover && isHoveringDiskPopover) ||
isResizingForStats
if vm.isStatsPopoverActive != newState {
vm.isStatsPopoverActive = newState
#if DEBUG
@ -390,6 +423,8 @@ struct NotchStatsView: View {
print(" CPU: shown=\(showingCPUPopover), hovering=\(isHoveringCPUPopover)")
print(" Memory: shown=\(showingMemoryPopover), hovering=\(isHoveringMemoryPopover)")
print(" GPU: shown=\(showingGPUPopover), hovering=\(isHoveringGPUPopover)")
print(" Network: shown=\(showingNetworkPopover), hovering=\(isHoveringNetworkPopover)")
print(" Disk: shown=\(showingDiskPopover), hovering=\(isHoveringDiskPopover)")
print(" Resizing: \(isResizingForStats)")
#endif
}
@ -460,8 +495,8 @@ struct UnifiedStatsCard: View {
}
.frame(height: 36) // Match boring.notch exactly - reduced from 50
// Click hint - only for CPU, Memory, GPU
if graphData.title == "CPU" || graphData.title == "Memory" || graphData.title == "GPU" {
// Click hint - shown for graphs that open popovers
if ["CPU", "Memory", "GPU", "Network", "Disk"].contains(graphData.title) {
Text("Click for details")
.font(.caption2)
.foregroundColor(.secondary)