fix: Refactor Update loop to ensure packets are processed in all views
This commit is contained in:
@@ -299,11 +299,61 @@ type ErrorMsg struct {
|
|||||||
|
|
||||||
// Update handles messages and updates the model
|
// Update handles messages and updates the model
|
||||||
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var cmd tea.Cmd
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
// Handle subview updates first
|
// GLOBAL HANDLERS: Handle signals independent of view
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case PacketMsg:
|
||||||
|
if msg.Packet != nil {
|
||||||
|
m.packetCount++
|
||||||
|
summary := formatPacketSummary(msg.Packet, m.networkMap)
|
||||||
|
m.lastPackets = append(m.lastPackets, summary)
|
||||||
|
if len(m.lastPackets) > 50 {
|
||||||
|
m.lastPackets = m.lastPackets[1:]
|
||||||
|
}
|
||||||
|
m.callFlowStore.AddPacket(msg.Packet)
|
||||||
|
|
||||||
|
// If we are in Call Detail view, we might need to update the viewport content dynamically!
|
||||||
|
if m.subView == SubViewCallDetail {
|
||||||
|
// Re-render subview content effectively updates the strings, but
|
||||||
|
// we need to set the content on viewport again if it changed.
|
||||||
|
// This is handled in View() normally, but viewport needs SetContent.
|
||||||
|
// Let's force a viewport update by triggering a dummy message or just re-setting it.
|
||||||
|
// Actually, View() calls renderCallDetail which calls SetContent.
|
||||||
|
// But View() is only called if Update returns a modified model.
|
||||||
|
// We modified the store, so that counts.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROCESS NEXT PACKET - CRITICAL loop
|
||||||
|
if m.capturing {
|
||||||
|
cmds = append(cmds, waitForPacket(m.packetChan))
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we processed a packet, we typically don't need to pass this msg to subviews
|
||||||
|
// UNLESS the subview reacts to it explicitly.
|
||||||
|
// For now, we return here to avoid double processing, BUT we must ensure
|
||||||
|
// UI refreshes.
|
||||||
|
return m, tea.Batch(cmds...)
|
||||||
|
|
||||||
|
case ErrorMsg:
|
||||||
|
m.captureError = msg.Error.Error()
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle standard key/window messages dependent on view
|
||||||
|
// Handle subview updates
|
||||||
if m.subView != SubViewNone {
|
if m.subView != SubViewNone {
|
||||||
return m.updateSubView(msg)
|
newM, cmd := m.updateSubView(msg)
|
||||||
|
// We need to type assert back to Model because updateSubView follows the interface but returns concrete logic
|
||||||
|
// Actually updateSubView returns tea.Model, tea.Cmd.
|
||||||
|
// Since we are inside Model.Update, we can cast or just return.
|
||||||
|
realM, ok := newM.(Model)
|
||||||
|
if ok {
|
||||||
|
m = realM
|
||||||
|
}
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
return m, tea.Batch(cmds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
@@ -321,7 +371,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
case "4":
|
case "4":
|
||||||
m.currentView = ViewNetworkMap
|
m.currentView = ViewNetworkMap
|
||||||
default:
|
default:
|
||||||
cmd = m.handleViewKeys(msg)
|
cmds = append(cmds, m.handleViewKeys(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
@@ -342,28 +392,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
|
|
||||||
m.viewport.Width = m.width / 2 // Right pane width
|
m.viewport.Width = m.width / 2 // Right pane width
|
||||||
m.viewport.Height = contentHeight
|
m.viewport.Height = contentHeight
|
||||||
|
|
||||||
case PacketMsg:
|
|
||||||
if msg.Packet != nil {
|
|
||||||
m.packetCount++
|
|
||||||
summary := formatPacketSummary(msg.Packet, m.networkMap)
|
|
||||||
m.lastPackets = append(m.lastPackets, summary)
|
|
||||||
if len(m.lastPackets) > 50 {
|
|
||||||
m.lastPackets = m.lastPackets[1:]
|
|
||||||
}
|
|
||||||
m.callFlowStore.AddPacket(msg.Packet)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue waiting if we are still capturing
|
return m, tea.Batch(cmds...)
|
||||||
if m.capturing {
|
|
||||||
return m, waitForPacket(m.packetChan)
|
|
||||||
}
|
|
||||||
|
|
||||||
case ErrorMsg:
|
|
||||||
m.captureError = msg.Error.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
return m, cmd
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) handleViewKeys(msg tea.KeyMsg) tea.Cmd {
|
func (m *Model) handleViewKeys(msg tea.KeyMsg) tea.Cmd {
|
||||||
|
|||||||
Reference in New Issue
Block a user