Some checks failed
Stable Release / stable (push) Failing after 22s
- Dark theme with red accents (cyberpunk aesthetic) - Epuré cyberpunk style: clean dark backgrounds, sharp red highlights - Full cyberpunk animations: glitch effect, scan line, typewriter - Mixed Unicode + ASCII icons - Rounded borders (╭ ╮ ╯ ╰) on cards and panels - ASCII art block titles (■) with red styling - Header: MUYUE branding, status indicators, live clock - Footer: shortcuts, version, update indicator - Tab transitions: glitch → scan → typewriter sequence - Extracted header.go, footer.go, animations.go as new files Controls unchanged: ctrl+t tabs, ctrl+s sidebar, ctrl+a AI panel file changes: - styles.go: new color palette (cyberRed, bgVoid, dimRed), block titles - types.go: added transition state, clock tick, glitch/scan/done messages - animations.go: new file with glitch, scan, typewriter, hex stream effects - header.go: new file with logo, tabs, status dots, live clock - footer.go: new file with shortcuts, version, update indicator - model.go: integrated transition state machine, clock updates - dashboard.go, studio.go, terminal.go, config_tab.go: updated icons/styles Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land> Co-authored-by: Augustin <muyue@legion-muyue.fr> Reviewed-on: #1
115 lines
3.9 KiB
Go
115 lines
3.9 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
)
|
|
|
|
func (m Model) renderConfig() string {
|
|
colWidth := m.width / 2
|
|
if colWidth < 30 {
|
|
colWidth = 30
|
|
}
|
|
|
|
var left, right strings.Builder
|
|
|
|
left.WriteString(renderSectionHeader("PROFILE", "[@]"))
|
|
left.WriteString("\n")
|
|
if m.config != nil {
|
|
fields := []struct {
|
|
label string
|
|
value string
|
|
}{
|
|
{"Name", m.config.Profile.Name},
|
|
{"Pseudo", m.config.Profile.Pseudo},
|
|
{"Email", m.config.Profile.Email},
|
|
{"Editor", m.config.Profile.Preferences.Editor},
|
|
{"Shell", m.config.Profile.Preferences.Shell},
|
|
{"Theme", m.config.Profile.Preferences.Theme},
|
|
{"Default AI", m.config.Profile.Preferences.DefaultAI},
|
|
}
|
|
for _, f := range fields {
|
|
left.WriteString(fmt.Sprintf(" %s %s\n",
|
|
labelStyle.Render(f.label+":"),
|
|
valueStyle.Render(f.value)))
|
|
}
|
|
if len(m.config.Profile.Languages) > 0 {
|
|
left.WriteString(fmt.Sprintf(" %s %s\n",
|
|
labelStyle.Render("Languages:"),
|
|
valueStyle.Render(strings.Join(m.config.Profile.Languages, ", "))))
|
|
}
|
|
}
|
|
left.WriteString("\n")
|
|
|
|
left.WriteString(renderSectionHeader("AI PROVIDERS", "[AI]"))
|
|
left.WriteString("\n")
|
|
if m.config != nil {
|
|
for _, p := range m.config.AI.Providers {
|
|
active := ""
|
|
if p.Active {
|
|
active = lipgloss.NewStyle().Foreground(cyberRed).Bold(true).Render(" >>")
|
|
}
|
|
keyStatus := itemMissingStyle.Render("no key")
|
|
if p.APIKey != "" {
|
|
keyStatus = itemOKStyle.Render("configured")
|
|
}
|
|
nameStyle := lipgloss.NewStyle().Foreground(textBright).Bold(true)
|
|
left.WriteString(fmt.Sprintf(" %s %s key=%s%s\n",
|
|
nameStyle.Render(p.Name),
|
|
lipgloss.NewStyle().Foreground(dimRed).Render("model="+p.Model),
|
|
keyStatus, active))
|
|
}
|
|
}
|
|
left.WriteString("\n")
|
|
|
|
right.WriteString(renderSectionHeader("TERMINAL", "[$]"))
|
|
right.WriteString("\n")
|
|
if m.config != nil {
|
|
right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Custom Prompt:"), valueStyle.Render(fmt.Sprintf("%v", m.config.Terminal.CustomPrompt))))
|
|
right.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Prompt Theme:"), valueStyle.Render(m.config.Terminal.PromptTheme)))
|
|
right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Auto Update:"), valueStyle.Render(fmt.Sprintf("%v", m.config.Profile.Preferences.AutoUpdate))))
|
|
right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Check on Start:"), valueStyle.Render(fmt.Sprintf("%v", m.config.Profile.Preferences.CheckOnStart))))
|
|
}
|
|
right.WriteString("\n")
|
|
|
|
right.WriteString(renderSectionHeader("BMAD METHOD", "[B]"))
|
|
right.WriteString("\n")
|
|
if m.config != nil {
|
|
installed := itemMissingStyle.Render("[--] no")
|
|
if m.config.BMAD.Installed {
|
|
installed = itemOKStyle.Render("[OK] yes")
|
|
}
|
|
right.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Installed:"), installed))
|
|
right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Global:"), valueStyle.Render(fmt.Sprintf("%v", m.config.BMAD.Global))))
|
|
if m.config.BMAD.Version != "" {
|
|
right.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Version:"), valueStyle.Render(m.config.BMAD.Version)))
|
|
}
|
|
}
|
|
right.WriteString("\n")
|
|
|
|
right.WriteString(renderSectionHeader(fmt.Sprintf("SKILLS (%d)", len(m.skillList)), "[!]"))
|
|
right.WriteString("\n")
|
|
if len(m.skillList) > 0 {
|
|
for _, s := range m.skillList {
|
|
target := s.Target
|
|
if target == "" {
|
|
target = "both"
|
|
}
|
|
right.WriteString(fmt.Sprintf(" %s %s %s\n",
|
|
lipgloss.NewStyle().Foreground(textMain).Render(s.Name),
|
|
lipgloss.NewStyle().Foreground(cyberRed).Render("["+target+"]"),
|
|
lipgloss.NewStyle().Foreground(dimRed).Render(s.Description)))
|
|
}
|
|
} else {
|
|
right.WriteString(lipgloss.NewStyle().Foreground(textMuted).Render(" No skills. Run `muyue skills init`."))
|
|
right.WriteString("\n")
|
|
}
|
|
|
|
leftCol := lipgloss.NewStyle().Width(colWidth).Render(left.String())
|
|
rightCol := lipgloss.NewStyle().Width(colWidth).Render(right.String())
|
|
|
|
return lipgloss.JoinHorizontal(lipgloss.Top, leftCol, rightCol)
|
|
}
|