import SwiftUI struct TTLControlPanel: View { let currentTTL: Int let currentIPv6HopLimit: Int let targetTTL: Int let defaultTTL: Int let isProtected: Bool let isProcessing: Bool let onActivate: () -> Void let onDeactivate: () -> Void @AppStorage("startMinimized") private var startMinimized = false @Environment(\.colorScheme) private var colorScheme @Namespace private var controlNamespace @State private var isHovering = false private var accentColor: Color { if colorScheme == .light { return isProtected ? Color(hue: 0.38, saturation: 0.85, brightness: 0.40) : Color(hue: 0.05, saturation: 0.90, brightness: 0.45) } else { return isProtected ? Color(hue: 0.38, saturation: 0.70, brightness: 0.80) : Color(hue: 0.06, saturation: 0.70, brightness: 0.85) } } private var buttonTint: Color { if colorScheme == .light { return isProtected ? Color(hue: 0.05, saturation: 0.85, brightness: isHovering ? 0.60 : 0.50) : Color(hue: 0.38, saturation: 0.85, brightness: isHovering ? 0.50 : 0.42) } else { return isProtected ? Color(hue: 0.06, saturation: 0.65, brightness: isHovering ? 0.90 : 0.80) : Color(hue: 0.38, saturation: 0.65, brightness: isHovering ? 0.90 : 0.80) } } var body: some View { VStack(spacing: 12) { ttlInfoCard protocolBadges actionButton settingsCard } } private var ttlInfoCard: some View { HStack(spacing: 20) { ttlValueDisplay( label: "CURRENT", value: currentTTL, highlight: isProtected ) Image(systemName: "arrow.right") .font(.system(size: 14, weight: .medium)) .foregroundStyle(.tertiary) ttlValueDisplay( label: "TARGET", value: targetTTL, highlight: true ) } .padding(.horizontal, 24) .padding(.vertical, 12) .frame(maxWidth: .infinity) .background { RoundedRectangle(cornerRadius: 16) .fill(.ultraThinMaterial) .overlay { RoundedRectangle(cornerRadius: 16) .stroke(accentColor.opacity(0.15), lineWidth: 0.5) } } .modifier(GlassCardModifier(tintColor: accentColor)) } private func ttlValueDisplay(label: String, value: Int, highlight: Bool) -> some View { VStack(spacing: 4) { Text(label) .font(.system(size: 10, weight: .semibold, design: .rounded)) .tracking(2) .foregroundStyle(.secondary) Text("\(value)") .font(.system(size: 30, weight: .bold, design: .monospaced)) .foregroundStyle(highlight ? accentColor : .primary) .contentTransition(.numericText()) .animation(.spring(duration: 0.5), value: value) } } // Protocol Badges private var protocolBadges: some View { HStack(spacing: 8) { badgeView(title: "IPv4 TTL", value: "\(currentTTL)", active: currentTTL == targetTTL) badgeView(title: "IPv6 HLIM", value: "\(currentIPv6HopLimit)", active: currentIPv6HopLimit == targetTTL) badgeView(title: "DNS FLUSH", value: "AUTO", active: isProtected) } } private func badgeView(title: String, value: String, active: Bool) -> some View { HStack(spacing: 4) { Circle() .fill(active ? Color.green : Color.orange) .frame(width: 5, height: 5) Text("\(title): \(value)") .font(.system(size: 9, weight: .medium, design: .monospaced)) .foregroundStyle(.secondary) } .padding(.horizontal, 8) .padding(.vertical, 4) .background( Capsule() .fill(.ultraThinMaterial) .overlay( Capsule().stroke(active ? Color.green.opacity(0.3) : Color.orange.opacity(0.2), lineWidth: 0.5) ) ) } // Action Button private var actionButton: some View { Button { if isProtected { onDeactivate() } else { onActivate() } } label: { HStack(spacing: 10) { if isProcessing { ProgressView() .controlSize(.small) .tint(.white) } else { Image(systemName: isProtected ? "antenna.radiowaves.left.and.right.slash" : "antenna.radiowaves.left.and.right") .font(.system(size: 16, weight: .semibold)) .symbolEffect(.bounce, value: isHovering) .contentTransition(.symbolEffect(.replace.magic(fallback: .replace))) } Text(isProtected ? "Deactivate Hider" : "Activate Hider") .font(.system(size: 15, weight: .semibold, design: .rounded)) .contentTransition(.numericText()) } .frame(maxWidth: .infinity) .padding(.vertical, 12) } .modifier(GlassButtonModifier()) .tint(buttonTint) .scaleEffect(isHovering ? 1.025 : 1.0) .shadow( color: (isProtected ? Color(hue: 0.06, saturation: 0.8, brightness: colorScheme == .light ? 0.5 : 0.9) : Color(hue: 0.38, saturation: 0.8, brightness: colorScheme == .light ? 0.4 : 0.9) ).opacity(isHovering ? (colorScheme == .light ? 0.35 : 0.45) : 0.0), radius: isHovering ? 12 : 0, x: 0, y: isHovering ? 4 : 0 ) .onHover { hovering in withAnimation(.spring(response: 0.35, dampingFraction: 0.7)) { isHovering = hovering } } .disabled(isProcessing) .animation(.easeInOut(duration: 0.3), value: isProtected) .animation(.easeInOut(duration: 0.3), value: isProcessing) } // Settings Card private var settingsCard: some View { HStack { Label("Start minimized in menu bar", systemImage: "macwindow.on.rectangle") .font(.system(size: 11, weight: .medium)) .foregroundStyle(.secondary) Spacer() Toggle("", isOn: $startMinimized) .toggleStyle(.switch) .controlSize(.small) .tint(accentColor) } .padding(.horizontal, 12) .padding(.vertical, 7) .background( RoundedRectangle(cornerRadius: 10) .fill(.ultraThinMaterial) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(accentColor.opacity(0.12), lineWidth: 0.5) ) ) } }