feat: TUI visual improvements (nav bar, flow details) and timestamp support
This commit is contained in:
@@ -129,16 +129,18 @@ func (r *PcapReader) extractSIPPacket(packet gopacket.Packet, packetNum int) *si
|
||||
|
||||
payloadStr := string(payload)
|
||||
|
||||
// Log first 200 chars to see full SIP headers
|
||||
preview := payloadStr
|
||||
if len(preview) > 200 {
|
||||
preview = preview[:200]
|
||||
}
|
||||
logger.Debug("PcapReader: Packet %d full payload preview: %q", packetNum, preview)
|
||||
// Log first 200 chars to see full SIP headers (only on trace/debug if needed)
|
||||
/*
|
||||
preview := payloadStr
|
||||
if len(preview) > 200 {
|
||||
preview = preview[:200]
|
||||
}
|
||||
logger.Debug("PcapReader: Packet %d full payload preview: %q", packetNum, preview)
|
||||
*/
|
||||
|
||||
// Check if it looks like SIP
|
||||
if !isSIPPayload(payloadStr) {
|
||||
logger.Debug("PcapReader: Packet %d is not SIP", packetNum)
|
||||
// logger.Debug("PcapReader: Packet %d is not SIP", packetNum)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -160,6 +162,7 @@ func (r *PcapReader) extractSIPPacket(packet gopacket.Packet, packetNum int) *si
|
||||
sipPacket.SourcePort = srcPort
|
||||
sipPacket.DestIP = dstIP
|
||||
sipPacket.DestPort = dstPort
|
||||
sipPacket.Timestamp = packet.Metadata().Timestamp
|
||||
|
||||
return sipPacket
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package sip
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Method represents a SIP method
|
||||
@@ -27,6 +28,7 @@ const (
|
||||
|
||||
// Packet represents a parsed SIP packet
|
||||
type Packet struct {
|
||||
Timestamp time.Time
|
||||
Raw string
|
||||
IsRequest bool
|
||||
Method Method
|
||||
|
||||
@@ -635,14 +635,21 @@ func (m Model) renderCallDetail() string {
|
||||
if !pkt.IsRequest {
|
||||
arrow = "←"
|
||||
}
|
||||
b.WriteString(fmt.Sprintf(" %d. %s %s\n", i+1, arrow, pkt.Summary()))
|
||||
|
||||
// Format timestamp
|
||||
ts := pkt.Timestamp.Format("15:04:05.000")
|
||||
|
||||
// Detailed packet info line
|
||||
b.WriteString(fmt.Sprintf(" %d. [%s] %s %s %s:%d -> %s:%d\n",
|
||||
i+1, ts, arrow, pkt.Summary(),
|
||||
pkt.SourceIP, pkt.SourcePort, pkt.DestIP, pkt.DestPort))
|
||||
|
||||
// Show SDP info if present
|
||||
if pkt.SDP != nil {
|
||||
mediaIP := pkt.SDP.GetSDPMediaIP()
|
||||
if mediaIP != "" {
|
||||
label := m.networkMap.LabelForIP(mediaIP)
|
||||
b.WriteString(fmt.Sprintf(" SDP Media: %s\n", label))
|
||||
b.WriteString(fmt.Sprintf(" SDP Media: %s (%s)\n", mediaIP, label))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -655,17 +662,45 @@ func (m Model) renderCallDetail() string {
|
||||
|
||||
func (m Model) renderNav() string {
|
||||
tabs := []string{"[1] Dashboard", "[2] Capture", "[3] Analysis", "[4] Network Map"}
|
||||
var rendered []string
|
||||
|
||||
// Calculate tab width for even distribution
|
||||
tabWidth := m.width / len(tabs)
|
||||
if tabWidth < 15 {
|
||||
tabWidth = 15
|
||||
}
|
||||
|
||||
// Style for active and inactive tabs with fixed width
|
||||
activeStyle := lipgloss.NewStyle().
|
||||
Bold(true).
|
||||
Foreground(lipgloss.Color("#FFFFFF")).
|
||||
Background(lipgloss.Color("#7D56F4")).
|
||||
Width(tabWidth).
|
||||
Align(lipgloss.Center)
|
||||
|
||||
inactiveStyle := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#AFAFAF")).
|
||||
Background(lipgloss.Color("#282A36")).
|
||||
Width(tabWidth).
|
||||
Align(lipgloss.Center)
|
||||
|
||||
var rendered []string
|
||||
for i, tab := range tabs {
|
||||
if View(i) == m.currentView {
|
||||
rendered = append(rendered, m.styles.Active.Render(tab))
|
||||
rendered = append(rendered, activeStyle.Render(tab))
|
||||
} else {
|
||||
rendered = append(rendered, m.styles.Inactive.Render(tab))
|
||||
rendered = append(rendered, inactiveStyle.Render(tab))
|
||||
}
|
||||
}
|
||||
|
||||
return lipgloss.JoinHorizontal(lipgloss.Top, rendered...) + "\n"
|
||||
// Join tabs and add background bar
|
||||
navBar := lipgloss.JoinHorizontal(lipgloss.Top, rendered...)
|
||||
|
||||
// Fill remaining width with background
|
||||
barStyle := lipgloss.NewStyle().
|
||||
Background(lipgloss.Color("#282A36")).
|
||||
Width(m.width)
|
||||
|
||||
return barStyle.Render(navBar) + "\n"
|
||||
}
|
||||
|
||||
func (m Model) renderStatusBar() string {
|
||||
|
||||
Reference in New Issue
Block a user