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
|
||||
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 {
|
||||
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) {
|
||||
@@ -321,7 +371,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case "4":
|
||||
m.currentView = ViewNetworkMap
|
||||
default:
|
||||
cmd = m.handleViewKeys(msg)
|
||||
cmds = append(cmds, m.handleViewKeys(msg))
|
||||
}
|
||||
|
||||
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.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
|
||||
if m.capturing {
|
||||
return m, waitForPacket(m.packetChan)
|
||||
}
|
||||
|
||||
case ErrorMsg:
|
||||
m.captureError = msg.Error.Error()
|
||||
}
|
||||
|
||||
return m, cmd
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func (m *Model) handleViewKeys(msg tea.KeyMsg) tea.Cmd {
|
||||
|
||||
Reference in New Issue
Block a user