mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
Always show port kill button
This commit is contained in:
parent
8c8e267ea6
commit
e9ef227f8f
1 changed files with 54 additions and 32 deletions
|
|
@ -252,46 +252,68 @@ private struct ServerStatusSection: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Port conflict warning
|
// Port conflict warning
|
||||||
if let conflict = portConflict {
|
if let conflict = portConflict {
|
||||||
VStack(alignment: .leading, spacing: 6) {
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
HStack(spacing: 4) {
|
|
||||||
Image(systemName: "exclamationmark.triangle.fill")
|
|
||||||
.foregroundColor(.orange)
|
|
||||||
.font(.caption)
|
|
||||||
|
|
||||||
Text("Port \(conflict.port) is used by \(conflict.process.name)")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundColor(.orange)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !conflict.alternativePorts.isEmpty {
|
|
||||||
HStack(spacing: 4) {
|
HStack(spacing: 4) {
|
||||||
Text("Try port:")
|
Image(systemName: "exclamationmark.triangle.fill")
|
||||||
|
.foregroundColor(.orange)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
|
|
||||||
ForEach(conflict.alternativePorts.prefix(3), id: \.self) { port in
|
Text("Port \(conflict.port) is used by \(conflict.process.name)")
|
||||||
Button(String(port)) {
|
|
||||||
Task {
|
|
||||||
await ServerConfigurationHelpers.restartServerWithNewPort(
|
|
||||||
port,
|
|
||||||
serverManager: serverManager
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.buttonStyle(.link)
|
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
.foregroundColor(.orange)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !conflict.alternativePorts.isEmpty {
|
||||||
|
HStack(spacing: 4) {
|
||||||
|
Text("Try port:")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
|
||||||
|
ForEach(conflict.alternativePorts.prefix(3), id: \.self) { port in
|
||||||
|
Button(String(port)) {
|
||||||
|
Task {
|
||||||
|
await ServerConfigurationHelpers.restartServerWithNewPort(
|
||||||
|
port,
|
||||||
|
serverManager: serverManager
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttonStyle(.link)
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add kill button for conflicting processes
|
||||||
|
HStack {
|
||||||
|
Button("Kill Process") {
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
try await PortConflictResolver.shared.forceKillProcess(conflict)
|
||||||
|
// After killing, clear the conflict and restart the server
|
||||||
|
portConflict = nil
|
||||||
|
await serverManager.start()
|
||||||
|
} catch {
|
||||||
|
// Handle error - in a real implementation, you might show an alert
|
||||||
|
print("Failed to kill process: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
.controlSize(.small)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.top, 8)
|
||||||
}
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 12)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.background(Color.orange.opacity(0.1))
|
||||||
|
.cornerRadius(6)
|
||||||
}
|
}
|
||||||
.padding(.vertical, 8)
|
|
||||||
.padding(.horizontal, 12)
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
.background(Color.orange.opacity(0.1))
|
|
||||||
.cornerRadius(6)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.padding(.vertical, 4)
|
.padding(.vertical, 4)
|
||||||
.task {
|
.task {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue