Files
ProxyIOS/UI/Pin/PinView.swift
Trey t 148bc3887c Add iPad support, auto-pinning, and comprehensive logging
- Adaptive iPhone/iPad layout with NavigationSplitView sidebar
- Auto-detect SSL-pinned domains, fall back to passthrough
- Certificate install via local HTTP server (Safari profile flow)
- App Group-backed CA, per-domain leaf cert LRU cache
- DB-backed config repository, Darwin notification throttling
- Rules engine, breakpoint rules, pinned domain tracking
- os.Logger instrumentation across tunnel/proxy/mitm/capture/cert/rules/db/ipc/ui
- Fix dyld framework embed, race conditions, thread safety
2026-04-11 12:52:18 -05:00

83 lines
2.8 KiB
Swift

import SwiftUI
import ProxyCore
import GRDB
struct PinView: View {
@State private var pinnedRequests: [CapturedTraffic] = []
@State private var observation: AnyDatabaseCancellable?
@State private var showClearAllConfirmation = false
private let trafficRepo = TrafficRepository()
var body: some View {
Group {
if pinnedRequests.isEmpty {
EmptyStateView(
icon: "pin.slash",
title: "No Pinned Requests",
subtitle: "Pin requests from the Home tab to save them here for quick access."
)
} else {
List {
ForEach(pinnedRequests) { request in
if let id = request.id {
NavigationLink(value: id) {
TrafficRowView(traffic: request)
}
}
}
.onDelete { offsets in
for index in offsets {
let request = pinnedRequests[index]
if let id = request.id {
try? trafficRepo.togglePin(id: id, isPinned: false)
}
}
}
}
.navigationDestination(for: Int64.self) { id in
RequestDetailView(trafficId: id)
}
}
}
.navigationTitle("Pin")
.toolbar {
if !pinnedRequests.isEmpty {
ToolbarItem(placement: .topBarTrailing) {
Button(role: .destructive) {
showClearAllConfirmation = true
} label: {
Text("Clear All")
}
}
}
}
.confirmationDialog(
"Clear All Pins",
isPresented: $showClearAllConfirmation,
titleVisibility: .visible
) {
Button("Clear All Pins", role: .destructive) {
for request in pinnedRequests {
if let id = request.id {
try? trafficRepo.togglePin(id: id, isPinned: false)
}
}
}
Button("Cancel", role: .cancel) {}
} message: {
Text("This will unpin all \(pinnedRequests.count) pinned requests.")
}
.task {
observation = trafficRepo.observePinnedTraffic()
.start(in: DatabaseManager.shared.dbPool) { error in
print("Pin observation error: \(error)")
} onChange: { pinned in
withAnimation {
pinnedRequests = pinned
}
}
}
}
}