Files
proxy/internal/tui/confirmation_dialog.go

81 lines
1.8 KiB
Go

package tui
import (
"fmt"
"strings"
"proxyctl/internal/app"
)
type confirmationResult uint8
const (
confirmationPending confirmationResult = iota
confirmationAccepted
confirmationCancelled
)
// confirmationDialog is the reusable safe-default interaction used for
// destructive Profile deletion and Application-requested confirmations.
// confirmFocused is deliberately false in every new dialog.
type confirmationDialog struct {
request app.Confirmation
confirmFocused bool
offset int
}
func newConfirmationDialog(request app.Confirmation) confirmationDialog {
return confirmationDialog{request: request}
}
func (d *confirmationDialog) update(key string) confirmationResult {
switch key {
case "pgup":
d.offset = max(0, d.offset-5)
case "pgdown":
d.offset += 5
case "home":
d.offset = 0
case "end":
d.offset = 1 << 20
case "left", "right", "tab", "shift+tab":
d.confirmFocused = !d.confirmFocused
case "y":
return confirmationAccepted
case "n", "esc", "q":
return confirmationCancelled
case "enter":
if d.confirmFocused {
return confirmationAccepted
}
return confirmationCancelled
}
return confirmationPending
}
func (d confirmationDialog) view() string {
confirmLabel := d.request.ConfirmLabel
if confirmLabel == "" {
confirmLabel = "Confirm"
}
cancelLabel := d.request.CancelLabel
if cancelLabel == "" {
cancelLabel = "Cancel"
}
confirm, cancel := " "+confirmLabel, "> "+cancelLabel
if d.confirmFocused {
confirm, cancel = "> "+confirmLabel, " "+cancelLabel
}
var body strings.Builder
body.WriteString(d.request.Title)
if d.request.Summary != "" {
fmt.Fprintf(&body, "\n%s", d.request.Summary)
}
for _, detail := range d.request.Details {
fmt.Fprintf(&body, "\n• %s", detail)
}
fmt.Fprintf(&body, "\n\n%s %s", cancel, confirm)
return body.String()
}