charmbracelet / bubbletea

A powerful little TUI framework 🏗
MIT License
25.65k stars 744 forks source link

When a large update is performed, it will cause a flash. #1032

Open yorukot opened 1 month ago

yorukot commented 1 month ago

Describe the bug When a large update is performed, it will cause a flash.

Setup

To Reproduce Steps to reproduce the behavior:

  1. go run main.go
  2. Press Tab to let tui update
  3. See error

Source Code

package main

import (
    tea "github.com/charmbracelet/bubbletea"
    "github.com/charmbracelet/lipgloss"
    "log"
    "math/rand"
    "strings"
)

type sessionState uint

const (
    timerView sessionState = iota
    spinnerView
)

var (
    modelStyle = lipgloss.NewStyle().
            Width(80).
            Height(35).
            Align(lipgloss.Center, lipgloss.Center).
            BorderStyle(lipgloss.HiddenBorder()).
            Background(lipgloss.Color("#4B4B4B"))

    focusedModelStyle = lipgloss.NewStyle().
                Width(80).
                Height(35).
                Align(lipgloss.Center, lipgloss.Center).
                BorderStyle(lipgloss.NormalBorder()).
                BorderForeground(lipgloss.Color("69")).
                Background(lipgloss.Color("#4B4B4B"))
)

type mainModel struct {
    state sessionState
}

func newModel() mainModel {
    m := mainModel{}
    return m
}

func (m mainModel) Init() tea.Cmd {
    return tea.Batch()
}

func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    var cmds []tea.Cmd
    switch msg := msg.(type) {
    case tea.KeyMsg:
        switch msg.String() {
        case "ctrl+c", "q":
            return m, tea.Quit
        case "tab":
            if m.state == timerView {
                m.state = spinnerView
            } else {
                m.state = timerView
            }
        }
    }
    return m, tea.Batch(cmds...)
}

func (m mainModel) View() string {
    var s string
    example1 := strings.Repeat("AAAA", 760)
    example2 := strings.Repeat("Test", 760)
    example := []string{example1, example2}
    if m.state == timerView {
        s += lipgloss.JoinHorizontal(lipgloss.Top, focusedModelStyle.Render(example[rand.Intn(2)]), modelStyle.Render(example[rand.Intn(2)]))
    } else {
        s += lipgloss.JoinHorizontal(lipgloss.Top, modelStyle.Render(example[rand.Intn(2)]), focusedModelStyle.Render(example[rand.Intn(2)]))
    }
    return s
}

func main() {
    p := tea.NewProgram(newModel(), tea.WithAltScreen())

    if _, err := p.Run(); err != nil {
        log.Fatal(err)
    }
}

Expected behavior Normal update without flash

Screenshots https://github.com/charmbracelet/bubbletea/assets/107802416/4f6337cb-2d4b-44b4-ade1-c31b7866ceef

Additional context https://github.com/yorukot/superfile/issues/122

meowgorithm commented 1 month ago

Hi! No ETA yet but we're actually working on a new renderer right now to addresses this very issue.