Files
spilltea/internal/ui/diff/update.go
T
2026-05-12 19:12:29 +02:00

144 lines
3.4 KiB
Go

package diff
import (
"charm.land/bubbles/v2/key"
tea "charm.land/bubbletea/v2"
"github.com/anotherhadi/spilltea/internal/keys"
notificationsUI "github.com/anotherhadi/spilltea/internal/ui/components/notifications"
)
// SendToDiffMsg carries a raw HTTP request or response to the diff page.
type SendToDiffMsg struct {
Label string
Raw string
}
// DiffReadyMsg is emitted when both slots are filled and the diff is ready to view.
type DiffReadyMsg struct{}
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case SendToDiffMsg:
if m.left.raw == "" {
m.left = slot{label: msg.Label, raw: msg.Raw}
m.refreshViewports()
return m, func() tea.Msg {
return notificationsUI.NotificationMsg{
Title: "Entry selected",
Body: "Select a second entry to compare",
Kind: notificationsUI.KindInfo,
}
}
} else if m.right.raw == "" {
m.right = slot{label: msg.Label, raw: msg.Raw}
m.computeDiff()
m.focus = bothSlots
m.leftViewport.SetYOffset(0)
m.rightViewport.SetYOffset(0)
m.leftViewport.SetXOffset(0)
m.rightViewport.SetXOffset(0)
m.refreshViewports()
return m, func() tea.Msg { return DiffReadyMsg{} }
} else {
// Both full: reset and start new comparison
m.left = slot{label: msg.Label, raw: msg.Raw}
m.right = slot{}
m.leftLines = nil
m.rightLines = nil
m.focus = bothSlots
m.leftViewport.SetYOffset(0)
m.rightViewport.SetYOffset(0)
m.leftViewport.SetXOffset(0)
m.rightViewport.SetXOffset(0)
m.refreshViewports()
return m, func() tea.Msg {
return notificationsUI.NotificationMsg{
Title: "Entry replaced",
Body: "Select a second entry to compare",
Kind: notificationsUI.KindInfo,
}
}
}
case tea.MouseWheelMsg:
switch msg.Button {
case tea.MouseWheelUp:
if msg.Mod.Contains(tea.ModShift) {
m.scrollH(-6)
} else {
m.scroll(-1)
}
case tea.MouseWheelDown:
if msg.Mod.Contains(tea.ModShift) {
m.scrollH(6)
} else {
m.scroll(1)
}
case tea.MouseWheelLeft:
m.scrollH(-6)
case tea.MouseWheelRight:
m.scrollH(6)
}
case tea.KeyPressMsg:
switch {
case key.Matches(msg, keys.Keys.Global.CycleFocus):
m.focus = m.focus.next()
case key.Matches(msg, keys.Keys.Global.Up):
m.scroll(-1)
case key.Matches(msg, keys.Keys.Global.Down):
m.scroll(1)
case key.Matches(msg, keys.Keys.Global.ScrollUp):
step := m.leftViewport.Height() / 2
if step < 1 {
step = 1
}
m.scroll(-step)
case key.Matches(msg, keys.Keys.Global.ScrollDown):
step := m.leftViewport.Height() / 2
if step < 1 {
step = 1
}
m.scroll(step)
case key.Matches(msg, keys.Keys.Global.Left):
m.scrollH(-6)
case key.Matches(msg, keys.Keys.Global.Right):
m.scrollH(6)
case key.Matches(msg, keys.Keys.Diff.Clear):
switch m.focus {
case leftSlot:
m.left = m.right
m.right = slot{}
m.leftLines = nil
m.rightLines = nil
m.focus = bothSlots
case rightSlot:
m.right = slot{}
m.leftLines = nil
m.rightLines = nil
m.focus = bothSlots
default:
m.left = slot{}
m.right = slot{}
m.leftLines = nil
m.rightLines = nil
m.focus = bothSlots
}
m.leftViewport.SetYOffset(0)
m.rightViewport.SetYOffset(0)
m.leftViewport.SetXOffset(0)
m.rightViewport.SetXOffset(0)
m.refreshViewports()
case key.Matches(msg, keys.Keys.Global.Help):
m.help.ShowAll = !m.help.ShowAll
m.recalcSizes()
}
}
return m, nil
}