feat: style changes and event reworks.
Going to work on process restart so I can test those messages.
This commit is contained in:
parent
b43cab8b0a
commit
adcee5f69e
@ -65,7 +65,7 @@ func proxyHandler(ch chan<- model.Event) http.Handler {
|
||||
ch <- model.Event{
|
||||
Time: time.Now().Local(),
|
||||
Type: model.EventTypeWarn,
|
||||
Body: fmt.Sprintf("(%s) failed to read request body", request.ID),
|
||||
Body: fmt.Sprintf("(%s) failed to read request body: %v", getEndOfUUID(request.ID), err),
|
||||
Request: request,
|
||||
}
|
||||
} else {
|
||||
@ -86,7 +86,7 @@ func proxyHandler(ch chan<- model.Event) http.Handler {
|
||||
ch <- model.Event{
|
||||
Time: time.Now().Local(),
|
||||
Type: model.EventTypeRequestStarted,
|
||||
Body: fmt.Sprintf("-> %+v", request),
|
||||
Body: fmt.Sprintf("(%s) %s %s", getEndOfUUID(request.ID), request.Method, request.RawURL),
|
||||
Request: request,
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ func proxyHandler(ch chan<- model.Event) http.Handler {
|
||||
ch <- model.Event{
|
||||
Time: time.Now().Local(),
|
||||
Type: model.EventTypeRequestFailed,
|
||||
Body: fmt.Sprintf("upstream error for %s %s: %v", outReq.Method, outReq.URL.String(), err),
|
||||
Body: fmt.Sprintf("(%s) upstream error: %v", getEndOfUUID(request.ID), err),
|
||||
Request: request,
|
||||
}
|
||||
return
|
||||
@ -115,7 +115,7 @@ func proxyHandler(ch chan<- model.Event) http.Handler {
|
||||
ch <- model.Event{
|
||||
Time: time.Now().Local(),
|
||||
Type: model.EventTypeWarn,
|
||||
Body: fmt.Sprintf("(%s) failed to read response body", request.ID),
|
||||
Body: fmt.Sprintf("(%s) failed to read response body: %v", getEndOfUUID(request.ID), err),
|
||||
Request: request,
|
||||
}
|
||||
} else {
|
||||
@ -133,7 +133,7 @@ func proxyHandler(ch chan<- model.Event) http.Handler {
|
||||
ch <- model.Event{
|
||||
Time: time.Now().Local(),
|
||||
Type: model.EventTypeRequestFailed,
|
||||
Body: fmt.Sprintf("write response body %s %s: %v", outReq.Method, outReq.URL.String(), err),
|
||||
Body: fmt.Sprintf("(%s) failed to write response body: %v", getEndOfUUID(request.ID), err),
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -146,7 +146,7 @@ func proxyHandler(ch chan<- model.Event) http.Handler {
|
||||
ch <- model.Event{
|
||||
Time: time.Now().Local(),
|
||||
Type: model.EventTypeRequestFinished,
|
||||
Body: fmt.Sprintf("<- %+v %s", request, formatHeaders(resp.Request.Header)),
|
||||
Body: fmt.Sprintf("(%s) %s %s %d %dms", getEndOfUUID(request.ID), request.Method, request.RawURL, request.Status, request.Duration.Milliseconds()),
|
||||
Request: request,
|
||||
}
|
||||
})
|
||||
@ -199,6 +199,10 @@ func formatHeaders(headers http.Header) string {
|
||||
return strings.Join(parts, ", ")
|
||||
}
|
||||
|
||||
func getEndOfUUID(id uuid.UUID) string {
|
||||
return id.String()[24:]
|
||||
}
|
||||
|
||||
// BUG: Not sure if this actually works, seems to favor the 502
|
||||
func statusFromUpstreamError(req *http.Request, resp *http.Response, err error) int {
|
||||
if resp != nil {
|
||||
|
||||
@ -23,7 +23,7 @@ func (m Model) renderStatusBar(w int) string {
|
||||
|
||||
avg := int(msSum) / max(1, len(m.requests))
|
||||
left := fmt.Sprintf(" tap %3d reqs | %d err | avg %dms", len(m.requests), errCount, avg)
|
||||
right := "j/k nav / search tab panel e events o output r replay q quit "
|
||||
right := "j/k nav / search tab panel e events o output r replay ctrl+r restart q quit "
|
||||
|
||||
spaceSize := max(w-(len(left)+len(right)), 0)
|
||||
space := strings.Repeat(" ", spaceSize)
|
||||
@ -31,6 +31,7 @@ func (m Model) renderStatusBar(w int) string {
|
||||
return m.theme.Header.Render(left + space + right)
|
||||
}
|
||||
|
||||
// TODO: Implement
|
||||
func (m Model) renderSearchPane(w, h int) []string {
|
||||
lines := make([]string, h)
|
||||
for y := range lines {
|
||||
@ -91,6 +92,7 @@ func (m Model) renderRequestPane(w, h int) []string {
|
||||
return lines
|
||||
}
|
||||
|
||||
// TODO: Implement
|
||||
func (m Model) renderDetailsPane(w, h int) []string {
|
||||
lines := make([]string, h)
|
||||
for y := range lines {
|
||||
@ -123,22 +125,33 @@ func (m Model) renderEventsPane(w, h int) []string {
|
||||
lines := []string{status}
|
||||
|
||||
for _, event := range events {
|
||||
line := fmt.Sprintf(
|
||||
"%s %-15s %s",
|
||||
event.Time.Format("15:04:05"),
|
||||
event.Type,
|
||||
event.Body,
|
||||
var (
|
||||
eTime string = m.theme.TextMuted.Render(event.Time.Format("15:04:05") + " ")
|
||||
eType string = getEventColor(m.theme, event.Type).Render(fmt.Sprintf("%-15s ", event.Type))
|
||||
|
||||
avail int = max(0, w-lipgloss.Width(eTime+eType))
|
||||
body string = clampRendered(m.theme.Text.Render(event.Body), avail)
|
||||
)
|
||||
if event.PID > 0 {
|
||||
line = fmt.Sprintf(
|
||||
"%s %-15s %d %s",
|
||||
event.Time.Format("15:04:05"),
|
||||
event.Type,
|
||||
event.PID,
|
||||
event.Body,
|
||||
)
|
||||
|
||||
if event.Type == model.EventTypeRequestFailed || event.Type == model.EventTypeFatal {
|
||||
body = clampRendered(m.theme.TextError.Render(event.Body), avail)
|
||||
eTime = m.theme.TextMutedError.Render(event.Time.Format("15:04:05") + " ")
|
||||
}
|
||||
lines = append(lines, truncate(line, w))
|
||||
|
||||
line := eTime + eType + body
|
||||
if event.PID > 0 {
|
||||
pid := m.theme.TextMuted.Render(fmt.Sprintf("%d ", event.PID))
|
||||
|
||||
avail = max(0, w-lipgloss.Width(eTime+eType+pid))
|
||||
body = clampRendered(m.theme.Text.Render(event.Body), avail)
|
||||
line = eTime + eType + pid + body
|
||||
}
|
||||
|
||||
if event.Type == model.EventTypeRequestFailed || event.Type == model.EventTypeFatal {
|
||||
line += m.theme.TextError.Render(strings.Repeat(" ", w-lipgloss.Width(line)))
|
||||
}
|
||||
|
||||
lines = append(lines, line)
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@ -3,6 +3,7 @@ package tui
|
||||
import (
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/charmbracelet/x/ansi"
|
||||
"termtap.dev/internal/model"
|
||||
)
|
||||
|
||||
type Theme struct {
|
||||
@ -17,10 +18,15 @@ type Theme struct {
|
||||
TextError lipgloss.Style
|
||||
TextMutedError lipgloss.Style
|
||||
|
||||
EventGreen lipgloss.Style
|
||||
EventRed lipgloss.Style
|
||||
EventBlue lipgloss.Style
|
||||
EventOrange lipgloss.Style
|
||||
EventDefault lipgloss.Style
|
||||
EventSession lipgloss.Style
|
||||
EventProcess lipgloss.Style
|
||||
EventProxy lipgloss.Style
|
||||
EventRequestInFlight lipgloss.Style
|
||||
EventSuccess lipgloss.Style
|
||||
EventWarn lipgloss.Style
|
||||
EventError lipgloss.Style
|
||||
EventFatal lipgloss.Style
|
||||
}
|
||||
|
||||
const background = lipgloss.Color("#010e1f")
|
||||
@ -29,8 +35,11 @@ const text = lipgloss.Color("#dfe5ed")
|
||||
const textMuted = lipgloss.Color("#7c7e80")
|
||||
|
||||
const blue = lipgloss.Color("#2280f2")
|
||||
const cyan = lipgloss.Color("#22b8f2")
|
||||
const violetBlue = lipgloss.Color("#6f7dff")
|
||||
const orange = lipgloss.Color("#f2a813")
|
||||
const red = lipgloss.Color("#e6130b")
|
||||
const fatalRed = lipgloss.Color("#ff4d4d")
|
||||
const green = lipgloss.Color("#10e31e")
|
||||
|
||||
func newTheme() Theme {
|
||||
@ -64,18 +73,42 @@ func newTheme() Theme {
|
||||
Foreground(textMuted).
|
||||
Background(backgroundError),
|
||||
|
||||
EventGreen: lipgloss.NewStyle().
|
||||
Foreground(green).
|
||||
Background(background),
|
||||
EventBlue: lipgloss.NewStyle().
|
||||
EventDefault: lipgloss.NewStyle().
|
||||
Foreground(text).
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventSession: lipgloss.NewStyle().
|
||||
Foreground(textMuted).
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventProcess: lipgloss.NewStyle().
|
||||
Foreground(blue).
|
||||
Background(background),
|
||||
EventRed: lipgloss.NewStyle().
|
||||
Foreground(red).
|
||||
Background(backgroundError),
|
||||
EventOrange: lipgloss.NewStyle().
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventProxy: lipgloss.NewStyle().
|
||||
Foreground(violetBlue).
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventRequestInFlight: lipgloss.NewStyle().
|
||||
Foreground(cyan).
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventSuccess: lipgloss.NewStyle().
|
||||
Foreground(green).
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventWarn: lipgloss.NewStyle().
|
||||
Foreground(orange).
|
||||
Background(background),
|
||||
Background(background).
|
||||
Bold(true),
|
||||
EventError: lipgloss.NewStyle().
|
||||
Foreground(red).
|
||||
Background(backgroundError).
|
||||
Bold(true),
|
||||
EventFatal: lipgloss.NewStyle().
|
||||
Foreground(fatalRed).
|
||||
Background(backgroundError).
|
||||
Bold(true),
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,3 +121,42 @@ func clampRendered(s string, maxCols int) string {
|
||||
}
|
||||
return ansi.Truncate(s, maxCols, "...")
|
||||
}
|
||||
|
||||
func getEventColor(theme Theme, event model.EventType) lipgloss.Style {
|
||||
switch event {
|
||||
case model.EventTypeSessionStarted,
|
||||
model.EventTypeSessionStopped:
|
||||
return theme.EventSession
|
||||
|
||||
case model.EventTypeProxyStarted,
|
||||
model.EventTypeProxyStarting,
|
||||
model.EventTypeProxyStopped:
|
||||
return theme.EventProxy
|
||||
|
||||
case model.EventTypeRequestStarted:
|
||||
return theme.EventRequestInFlight
|
||||
|
||||
case model.EventTypeRequestFinished:
|
||||
return theme.EventSuccess
|
||||
|
||||
case model.EventTypeFatal:
|
||||
return theme.EventFatal
|
||||
|
||||
case model.EventTypeRequestFailed:
|
||||
return theme.EventError
|
||||
|
||||
case model.EventTypeProcessStarting,
|
||||
model.EventTypeProcessStarted,
|
||||
model.EventTypeProcessExited,
|
||||
model.EventTypeProcessSignaled,
|
||||
model.EventTypeProcessStdout,
|
||||
model.EventTypeProcessStderr:
|
||||
return theme.EventProcess
|
||||
|
||||
case model.EventTypeWarn:
|
||||
return theme.EventWarn
|
||||
|
||||
default:
|
||||
return theme.EventDefault
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user