mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
feat(ui): make ngrok URL clickable with copy button in Dashboard (#422)
Co-authored-by: Gopi Kori <gopi@bruviti.com>
This commit is contained in:
parent
12e6c6d61c
commit
4bc2cdd653
1 changed files with 51 additions and 4 deletions
|
|
@ -441,10 +441,20 @@ private struct RemoteAccessStatusSection: View {
|
||||||
.font(.system(size: 10))
|
.font(.system(size: 10))
|
||||||
Text("ngrok")
|
Text("ngrok")
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
Text("(\(status.publicUrl.replacingOccurrences(of: "https://", with: "")))")
|
|
||||||
.font(.caption)
|
if let url = URL(string: status.publicUrl) {
|
||||||
.foregroundColor(.secondary)
|
Link(status.publicUrl, destination: url)
|
||||||
.lineLimit(1)
|
.font(.caption)
|
||||||
|
.foregroundStyle(.blue)
|
||||||
|
.lineLimit(1)
|
||||||
|
} else {
|
||||||
|
Text(status.publicUrl)
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
NgrokURLCopyButton(url: status.publicUrl)
|
||||||
} else {
|
} else {
|
||||||
Image(systemName: "circle")
|
Image(systemName: "circle")
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
@ -495,6 +505,43 @@ private struct RemoteAccessStatusSection: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Ngrok URL Copy Button
|
||||||
|
|
||||||
|
private struct NgrokURLCopyButton: View {
|
||||||
|
let url: String
|
||||||
|
@State private var showCopiedFeedback = false
|
||||||
|
@State private var feedbackTask: DispatchWorkItem?
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Button(action: {
|
||||||
|
NSPasteboard.general.clearContents()
|
||||||
|
NSPasteboard.general.setString(url, forType: .string)
|
||||||
|
|
||||||
|
// Cancel previous timer if exists
|
||||||
|
feedbackTask?.cancel()
|
||||||
|
|
||||||
|
withAnimation {
|
||||||
|
showCopiedFeedback = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new timer
|
||||||
|
let task = DispatchWorkItem {
|
||||||
|
withAnimation {
|
||||||
|
showCopiedFeedback = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
feedbackTask = task
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: task)
|
||||||
|
}, label: {
|
||||||
|
Image(systemName: showCopiedFeedback ? "checkmark" : "doc.on.doc")
|
||||||
|
.foregroundColor(showCopiedFeedback ? .green : .accentColor)
|
||||||
|
})
|
||||||
|
.buttonStyle(.borderless)
|
||||||
|
.help("Copy URL")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
#Preview("Dashboard Settings") {
|
#Preview("Dashboard Settings") {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue