Files
MujicaUI/file_change_card.go
T

86 lines
2.8 KiB
Go

package mujica
import (
"log/slog"
"github.com/egoist/mygo/ui"
"mujicaui/icons"
"mujicaui/theme"
)
// FileChangeCardOptions configure a FileChangeCard.
type FileChangeCardOptions struct {
// Preview is the diff lines shown; zero means 8.
Preview int
Disabled bool
}
// FileChangeResult reports this frame's events.
type FileChangeResult struct {
Element *ui.Element
// Decided reports that *decision changed.
Decided bool
// OpenDiff asks the caller to show the full diff.
OpenDiff bool
}
// FileChangeCard previews a file change to accept or reject.
func FileChangeCard(c *ui.Context, decision *FileDecision, change FileChange, opts FileChangeCardOptions) FileChangeResult {
if decision == nil || change.Path == "" {
panic("mujica: FileChangeCard needs a decision and a Path")
}
if opts.Preview < 0 {
panic("mujica: FileChangeCard Preview is negative")
}
preview := opts.Preview
if preview == 0 {
preview = 8
}
u := Density(c).Unit()
var r FileChangeResult
r.Element = agentCard(c).Disabled(opts.Disabled).Label(change.Path)
dc := agentDiffOf(r.Element, change)
locked := r.Element.IsDisabled()
r.Element.Children(func() {
ui.Row(c).Gap(u * 2).AlignItems(ui.Center).MinHeight(theme.MinHitSize).Children(func() {
ui.Icon(c, icons.Must("file-text")).Size(16, 16).TextColor(Tokens(c).TextMuted).Shrink(0)
ui.Text(c, change.Path).Font(theme.MonoFont).FontWeight(600).SingleLine().Grow(1).Shrink(1)
switch {
case change.Old == "" && change.New != "":
agentCaption(c, msg(c, "file_change_card.new"))
case change.New == "" && change.Old != "":
agentCaption(c, msg(c, "file_change_card.deleted"))
}
agentDiffStats(c, dc.add, dc.del)
agentDecisionMark(c, *decision)
})
from := max(0, dc.firstEdit-2)
shown := dc.lines[from:min(len(dc.lines), from+preview)]
if len(shown) > 0 {
agentDiffView(c, shown, 320).Font(theme.MonoFont)
}
ui.Row(c).Gap(u * 2).Justify(ui.End).Wrap().Children(func() {
if Button(c, msg(c, "file_change_card.open"), ButtonOptions{Variant: Ghost, Disabled: locked}).Clicked() && !locked {
r.OpenDiff = true
}
if *decision != FilePending {
if Button(c, msg(c, "file_change_card.undo"), ButtonOptions{Variant: Secondary, Disabled: locked}).Clicked() && !locked {
*decision, r.Decided = FilePending, true
}
return
}
if Button(c, msg(c, "file_change_card.reject"), ButtonOptions{Variant: Secondary, Disabled: locked}).Clicked() && !locked {
*decision, r.Decided = FileRejected, true
}
if Button(c, msg(c, "file_change_card.accept"), ButtonOptions{Disabled: locked}).Clicked() && !locked {
*decision, r.Decided = FileAccepted, true
}
})
})
if r.Decided || r.OpenDiff {
slog.Debug("mujica: file_change_card event", "path", change.Path, "decision", int(*decision), "open", r.OpenDiff)
}
return r
}