100 lines
3.7 KiB
Swift
100 lines
3.7 KiB
Swift
import SwiftUI
|
|
import ProxyCore
|
|
import GRDB
|
|
|
|
struct BreakpointRulesView: View {
|
|
@State private var isEnabled = IPCManager.shared.isBreakpointEnabled
|
|
@State private var rules: [BreakpointRule] = []
|
|
@State private var showAddRule = false
|
|
@State private var observation: AnyDatabaseCancellable?
|
|
|
|
private let rulesRepo = RulesRepository()
|
|
|
|
var body: some View {
|
|
List {
|
|
Section {
|
|
ToggleHeaderView(
|
|
title: "Breakpoint",
|
|
description: "Pause and modify HTTP requests and responses in real-time before they reach the server or the app.",
|
|
isEnabled: $isEnabled
|
|
)
|
|
.onChange(of: isEnabled) { _, newValue in
|
|
IPCManager.shared.isBreakpointEnabled = newValue
|
|
IPCManager.shared.post(.configurationChanged)
|
|
}
|
|
}
|
|
.listRowInsets(EdgeInsets())
|
|
|
|
Section("Rules") {
|
|
if rules.isEmpty {
|
|
EmptyStateView(
|
|
icon: "pause.circle",
|
|
title: "No Breakpoint Rules",
|
|
subtitle: "Tap + to create a new breakpoint rule."
|
|
)
|
|
} else {
|
|
ForEach(rules) { rule in
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(rule.name ?? rule.urlPattern)
|
|
.font(.subheadline.weight(.medium))
|
|
Text(rule.urlPattern)
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
HStack(spacing: 8) {
|
|
if rule.interceptRequest {
|
|
Text("Request")
|
|
.font(.caption2)
|
|
.foregroundStyle(.blue)
|
|
}
|
|
if rule.interceptResponse {
|
|
Text("Response")
|
|
.font(.caption2)
|
|
.foregroundStyle(.green)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.onDelete { indexSet in
|
|
for index in indexSet {
|
|
if let id = rules[index].id {
|
|
try? rulesRepo.deleteBreakpointRule(id: id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle("Breakpoint")
|
|
.toolbar {
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
Button { showAddRule = true } label: {
|
|
Image(systemName: "plus")
|
|
}
|
|
}
|
|
}
|
|
.sheet(isPresented: $showAddRule) {
|
|
NavigationStack {
|
|
Form {
|
|
// TODO: Add breakpoint rule creation form
|
|
Text("Breakpoint rule creation")
|
|
}
|
|
.navigationTitle("New Breakpoint Rule")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Cancel") { showAddRule = false }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.task {
|
|
observation = rulesRepo.observeBreakpointRules()
|
|
.start(in: DatabaseManager.shared.dbPool) { error in
|
|
print("Breakpoint observation error: \(error)")
|
|
} onChange: { newRules in
|
|
rules = newRules
|
|
}
|
|
}
|
|
}
|
|
}
|