Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,4 @@ build/
vendor/

temp/
.agents/
14 changes: 7 additions & 7 deletions adapter/inbound/ui/form.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ var (
// Use standard bright ANSI colors to prevent dark gray rendering bugs
// that occur with some pastel hex colors (like #cad3f5) in certain terminal environments.
focusedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("15")) // Bright White
blurredStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("7")) // Normal White
cursorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("14")) // Bright Cyan
noStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("8")) // Bright Black (Dark Gray)
blurredStyle = lipgloss.NewStyle().Foreground(AppTheme.Text) // Normal White
cursorStyle = lipgloss.NewStyle().Foreground(AppTheme.Highlight) // Bright Cyan
noStyle = lipgloss.NewStyle().Foreground(AppTheme.MutedText) // Bright Black (Dark Gray)

btnStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("7")).Padding(0, 1)
focusedBtnStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("0")).Background(lipgloss.Color("14")).Bold(true).Padding(0, 1)
btnStyle = lipgloss.NewStyle().Foreground(AppTheme.Text).Padding(0, 1)
focusedBtnStyle = lipgloss.NewStyle().Foreground(AppTheme.Background).Background(AppTheme.Highlight).Bold(true).Padding(0, 1)

popupBorder = lipgloss.Color("14") // Bright Cyan
popupBorder = AppTheme.Highlight // Bright Cyan

SubmitOptOk = "OK"
SubmitOptCancel = "Cancel"
Expand Down Expand Up @@ -157,7 +157,7 @@ func (m FormModel) View() string {
buttons := lipgloss.JoinHorizontal(lipgloss.Top, okStyle.Render("[ OK ]"), " ", cancelStyle.Render("[ Cancel ]"))
fmt.Fprintf(&b, "%s\n", buttons)

return lipgloss.NewStyle().Border(appBorder).BorderForeground(lipgloss.Color("#8aadf4")).Padding(1, 2).Render(b.String())
return lipgloss.NewStyle().Border(appBorder).BorderForeground(AppTheme.Secondary).Padding(1, 2).Render(b.String())
}

func (m FormModel) GetValues() []string {
Expand Down
33 changes: 33 additions & 0 deletions adapter/inbound/ui/theme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ui

import "github.com/charmbracelet/lipgloss"

type Theme struct {
Primary lipgloss.Color
Secondary lipgloss.Color
Success lipgloss.Color
Warning lipgloss.Color
Error lipgloss.Color
Info lipgloss.Color
Border lipgloss.Color
Text lipgloss.Color
MutedText lipgloss.Color
Highlight lipgloss.Color
Background lipgloss.Color
ActiveItem lipgloss.Color
}

var AppTheme = Theme{
Primary: lipgloss.Color("#c6a0f6"), // Pink/Purple (Headers)
Secondary: lipgloss.Color("#8aadf4"), // Blue (Focus)
Success: lipgloss.Color("#a6da95"), // Green (Connected, Success)
Warning: lipgloss.Color("208"), // Orange/Yellow (Warnings)
Error: lipgloss.Color("#ed8796"), // Red (Disconnected, Error)
Info: lipgloss.Color("#91d7e3"), // Cyan (Info, Memory, Temps)
Border: lipgloss.Color("#5b6078"), // Muted Blue/Gray (Borders)
Text: lipgloss.Color("#cad3f5"), // White/Light Gray (Normal text)
MutedText: lipgloss.Color("#8087a2"), // Darker Gray (Hints, Unfocused)
Highlight: lipgloss.Color("14"), // Bright Cyan (Search highlights)
Background: lipgloss.Color("#181926"), // Dark Base (Buttons, etc.)
ActiveItem: lipgloss.Color("#eed49f"), // Yellow (Active selection)
}
14 changes: 7 additions & 7 deletions adapter/inbound/ui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const (
)

type AppModel struct {
uc *usecase.ActiveMQUseCase
uc usecase.UseCase
env string
refreshInterval time.Duration
viewStats bool
Expand Down Expand Up @@ -120,7 +120,7 @@ func (m *AppModel) initViewport() {

type tickMsg time.Time

func NewAppModel(uc *usecase.ActiveMQUseCase, interval time.Duration, host string, env string, readOnly bool) *AppModel {
func NewAppModel(uc usecase.UseCase, interval time.Duration, host string, env string, readOnly bool) *AppModel {
// Original profile detection for conditional styling
detectedProfile := lipgloss.ColorProfile()

Expand All @@ -132,9 +132,9 @@ func NewAppModel(uc *usecase.ActiveMQUseCase, interval time.Duration, host strin
// Initialize dynamic global styles based on profile
isHighColor := (detectedProfile == termenv.ANSI256 || detectedProfile == termenv.TrueColor)
if isHighColor {
titleStyle = lipgloss.NewStyle().MarginLeft(2).Bold(true).Foreground(lipgloss.Color("#c6a0f6"))
titleStyle = lipgloss.NewStyle().MarginLeft(2).Bold(true).Foreground(AppTheme.Primary)
} else {
titleStyle = lipgloss.NewStyle().MarginLeft(2).Bold(true).Foreground(lipgloss.Color("#c6a0f6"))
titleStyle = lipgloss.NewStyle().MarginLeft(2).Bold(true).Foreground(AppTheme.Primary)
}

// 1. Queue Table
Expand Down Expand Up @@ -180,17 +180,17 @@ func NewAppModel(uc *usecase.ActiveMQUseCase, interval time.Duration, host strin
conTable := table.New(table.WithColumns(conCols), table.WithFocused(true))

s := table.DefaultStyles()
s.Header = s.Header.BorderStyle(appBorder).BorderForeground(lipgloss.Color("#5b6078")).BorderBottom(true).Bold(false)
s.Header = s.Header.BorderStyle(appBorder).BorderForeground(AppTheme.Border).BorderBottom(true).Bold(false)

// Determine theme based on detected profile
isHighColor = (detectedProfile == termenv.ANSI256 || detectedProfile == termenv.TrueColor)

if isHighColor {
// Original 256-color theme
s.Selected = s.Selected.Foreground(lipgloss.Color("#181926")).Background(lipgloss.Color("#8aadf4")).Bold(false)
s.Selected = s.Selected.Foreground(AppTheme.Background).Background(AppTheme.Secondary).Bold(false)
} else {
// Limited terminal: Use high-contrast Black on White theme (as requested)
s.Selected = s.Selected.Foreground(lipgloss.Color("0")).Background(lipgloss.Color("15")).Bold(false)
s.Selected = s.Selected.Foreground(AppTheme.Background).Background(lipgloss.Color("15")).Bold(false)
}

qTable.SetStyles(s)
Expand Down
34 changes: 17 additions & 17 deletions adapter/inbound/ui/tui_time_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,27 @@ func (m *AppModel) updateTimeDeletePopup(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m *AppModel) viewTimeDeletePopup() string {
border := lipgloss.NewStyle().
Border(appBorder).
BorderForeground(lipgloss.Color("#8aadf4")).
BorderForeground(AppTheme.Secondary).
Padding(1, 2)

title := lipgloss.NewStyle().Foreground(lipgloss.Color("#c6a0f6")).Bold(true).Render("Delete By Time")
desc := lipgloss.NewStyle().Foreground(lipgloss.Color("#cad3f5")).Render("Delete messages older than:")
title := lipgloss.NewStyle().Foreground(AppTheme.Primary).Bold(true).Render("Delete By Time")
desc := lipgloss.NewStyle().Foreground(AppTheme.Text).Render("Delete messages older than:")

valColor := lipgloss.Color("#181926")
valColor := AppTheme.Background
if m.timeDeleteFocus != 0 {
valColor = lipgloss.Color("#8087a2")
valColor = AppTheme.MutedText
}
valStr := lipgloss.NewStyle().Foreground(valColor).Render(m.timeDeleteVal)
if m.timeDeleteVal == "" {
valStr = "_"
}

unitStr := "days"
mStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#8087a2"))
hStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#8087a2"))
dStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#8087a2"))
mStyle := lipgloss.NewStyle().Foreground(AppTheme.MutedText)
hStyle := lipgloss.NewStyle().Foreground(AppTheme.MutedText)
dStyle := lipgloss.NewStyle().Foreground(AppTheme.MutedText)

activeStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#181926")).Bold(true)
activeStyle := lipgloss.NewStyle().Foreground(AppTheme.Background).Bold(true)

switch m.timeDeleteUnit {
case "m":
Expand All @@ -125,22 +125,22 @@ func (m *AppModel) viewTimeDeletePopup() string {
dStyle.Render("(d)ays"),
)

bracketLeft := lipgloss.NewStyle().Foreground(lipgloss.Color("#8087a2")).Render("[ ")
bracketRight := lipgloss.NewStyle().Foreground(lipgloss.Color("#8087a2")).Render(" ]")
bracketLeft := lipgloss.NewStyle().Foreground(AppTheme.MutedText).Render("[ ")
bracketRight := lipgloss.NewStyle().Foreground(AppTheme.MutedText).Render(" ]")
if m.timeDeleteFocus == 0 {
bracketLeft = lipgloss.NewStyle().Foreground(lipgloss.Color("#181926")).Render("[ ")
bracketRight = lipgloss.NewStyle().Foreground(lipgloss.Color("#181926")).Render(" ]")
bracketLeft = lipgloss.NewStyle().Foreground(AppTheme.Background).Render("[ ")
bracketRight = lipgloss.NewStyle().Foreground(AppTheme.Background).Render(" ]")
}

inputLine := fmt.Sprintf("%s%s%s %s", bracketLeft, valStr, bracketRight, units)

selectionInfo := lipgloss.NewStyle().Foreground(lipgloss.Color("208")).Render(fmt.Sprintf("Current selection: %s %s", m.timeDeleteVal, unitStr))
selectionInfo := lipgloss.NewStyle().Foreground(AppTheme.Warning).Render(fmt.Sprintf("Current selection: %s %s", m.timeDeleteVal, unitStr))
if m.timeDeleteVal == "" {
selectionInfo = lipgloss.NewStyle().Foreground(lipgloss.Color("208")).Render("Current selection: (invalid)")
selectionInfo = lipgloss.NewStyle().Foreground(AppTheme.Warning).Render("Current selection: (invalid)")
}

btnStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#a5adcb")).Padding(0, 1)
focusedBtnStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#181926")).Background(lipgloss.Color("#8aadf4")).Bold(true).Padding(0, 1)
btnStyle := lipgloss.NewStyle().Foreground(AppTheme.MutedText).Padding(0, 1)
focusedBtnStyle := lipgloss.NewStyle().Foreground(AppTheme.Background).Background(AppTheme.Secondary).Bold(true).Padding(0, 1)

delStyle := btnStyle
canStyle := btnStyle
Expand Down
11 changes: 11 additions & 0 deletions adapter/inbound/ui/tui_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ui

import (
"fmt"
"github.com/atotto/clipboard"
"github.com/xvlet/amqcli/domain"
"os"
"sort"
Expand Down Expand Up @@ -551,6 +552,16 @@ func (m *AppModel) updateMessageDetail(msg tea.Msg) (tea.Model, tea.Cmd) {
m.currentState = stateMessageList
m.selectedMessage = nil
return m, nil
case "c", "C", "y", "Y": // Copy Payload
if m.selectedMessage != nil && m.selectedMessage.Body != "" {
err := clipboard.WriteAll(m.selectedMessage.Body)
if err != nil {
m.err = err
} else {
m.err = fmt.Errorf("success: Payload copied to clipboard")
}
}
return m, nil
case "d", "D", "alt+d": // Delete
if m.readOnly {
m.err = fmt.Errorf("read-only mode is active")
Expand Down
Loading
Loading