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
116 lines
2.7 KiB
Go
116 lines
2.7 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
)
|
|
|
|
var glitchChars = "!@#$%^&*()_+-=[]{}|;':,./<>?~`"
|
|
|
|
func init() {
|
|
rand.Seed(time.Now().UnixNano())
|
|
}
|
|
|
|
func randomGlitchChar() string {
|
|
return string(glitchChars[rand.Intn(len(glitchChars))])
|
|
}
|
|
|
|
func glitchText(text string, intensity int) string {
|
|
runes := []rune(text)
|
|
for i := 0; i < intensity; i++ {
|
|
pos := rand.Intn(len(runes))
|
|
if runes[pos] != ' ' && runes[pos] != '\n' {
|
|
runes[pos] = []rune(randomGlitchChar())[0]
|
|
}
|
|
}
|
|
return string(runes)
|
|
}
|
|
|
|
func generateScanLine(width int, frame int) string {
|
|
pos := frame % width
|
|
line := strings.Repeat(" ", pos) +
|
|
lipgloss.NewStyle().Foreground(cyberRed).Bold(true).Render(strings.Repeat("━", min(20, width-pos)))
|
|
if pos+20 < width {
|
|
line += strings.Repeat(" ", width-pos-20)
|
|
}
|
|
return line[:min(width, len(line))]
|
|
}
|
|
|
|
func typewriterRender(text string, pos int) string {
|
|
if pos >= len(text) {
|
|
return text
|
|
}
|
|
if pos <= 0 {
|
|
return ""
|
|
}
|
|
shown := text[:pos]
|
|
cursor := lipgloss.NewStyle().Foreground(cyberRed).Bold(true).Render("█")
|
|
return shown + cursor
|
|
}
|
|
|
|
func renderGlitchEffect(width, height, frame int) string {
|
|
var b strings.Builder
|
|
for y := 0; y < height; y++ {
|
|
line := ""
|
|
for x := 0; x < width; x++ {
|
|
if rand.Float64() < 0.15 {
|
|
c := randomGlitchChar()
|
|
style := lipgloss.NewStyle()
|
|
r := rand.Float64()
|
|
if r < 0.4 {
|
|
style = style.Foreground(cyberRed)
|
|
} else if r < 0.7 {
|
|
style = style.Foreground(cyberPink)
|
|
} else {
|
|
style = style.Foreground(textMuted)
|
|
}
|
|
line += style.Render(c)
|
|
} else {
|
|
line += " "
|
|
}
|
|
}
|
|
b.WriteString(line)
|
|
if y < height-1 {
|
|
b.WriteString("\n")
|
|
}
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
func renderScanEffect(width, height, frame int) string {
|
|
var b strings.Builder
|
|
scanY := frame % (height + 10)
|
|
for y := 0; y < height; y++ {
|
|
if y == scanY || y == scanY+1 {
|
|
b.WriteString(lipgloss.NewStyle().Foreground(cyberRed).Render(strings.Repeat("━", width)))
|
|
} else if y == scanY-1 || y == scanY+2 {
|
|
b.WriteString(lipgloss.NewStyle().Foreground(dimRed).Render(strings.Repeat("─", width)))
|
|
} else if y < scanY {
|
|
b.WriteString(lipgloss.NewStyle().Foreground(dimRed).Render(fmt.Sprintf("%*s", width, "")))
|
|
} else {
|
|
b.WriteString(strings.Repeat(" ", width))
|
|
}
|
|
if y < height-1 {
|
|
b.WriteString("\n")
|
|
}
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
func generateHexStream(width, lines int) string {
|
|
var b strings.Builder
|
|
for y := 0; y < lines; y++ {
|
|
for x := 0; x < width/3; x++ {
|
|
b.WriteString(fmt.Sprintf("%02X", rand.Intn(256)))
|
|
}
|
|
if y < lines-1 {
|
|
b.WriteString("\n")
|
|
}
|
|
}
|
|
return lipgloss.NewStyle().Foreground(dimRed).Render(b.String())
|
|
}
|