charmbracelet / bubbles

TUI components for Bubble Tea 🫧
MIT License
5.51k stars 265 forks source link

confused on how to use slice of components in another model #327

Closed neel-bp closed 1 year ago

neel-bp commented 1 year ago

hello everyone i am trying to use a component that i wrote in another model but am a little confused how to do it properly i have done something, but it behaves weirdly, by itself the component works fine, but when using it in a slice and rendering all of them together behaves weirdly, source for component

package bettertimer

import (
    "time"

    tea "github.com/charmbracelet/bubbletea"
)

type Bubble struct {
    startTime time.Time
    format    string
}

type TickerMsg struct{}

func (m Bubble) Init() tea.Cmd {
    return Tick
}

func Tick() tea.Msg {
    time.Sleep(time.Second)
    return TickerMsg{}
}

func (m Bubble) Update(msg tea.Msg) (Bubble, tea.Cmd) {
    switch msg.(type) {
    case TickerMsg:
        return m, Tick
    }
    return m, nil
}

func (m Bubble) View() string {

    startTime := m.startTime

    if m.startTime.After(time.Now()) {
        startTime = time.Now()
    }
    timeDiff := time.Since(startTime)
    out := time.Time{}.Add(timeDiff)
    return out.Format(m.format)
}

func InitializeTimer(t time.Time, f string) Bubble {
    return Bubble{
        startTime: t,
        format:    f,
    }
}

and source for main program

package main

import (
    "fmt"
    "os"
    "time"

    "bubbletimer.com/timer/bettertimer"
    tea "github.com/charmbracelet/bubbletea"
)

type MainModel struct {
    timers []bettertimer.Bubble
}

func (m MainModel) Init() tea.Cmd {
    return bettertimer.Tick
}

func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    cmds := make([]tea.Cmd, 0)
    switch msg.(type) {
    case bettertimer.TickerMsg:

        timers := make([]bettertimer.Bubble, 0)
        for _, timer := range m.timers {
            timer, cmd := timer.Update(msg)
            cmds = append(cmds, cmd)
            timers = append(timers, timer)
        }
        m.timers = append(m.timers, timers...)
    }
    return m, tea.Batch(cmds...)
}

func (m MainModel) View() string {
    var s string
    for _, timer := range m.timers {
        s += timer.View() + "\n"
    }
    return s
}

func main() {

    t1 := bettertimer.InitializeTimer(time.Now(), "15:04:05")
    t2 := bettertimer.InitializeTimer(time.Now().Add(-time.Hour), "15:04:05")

    timers := make([]bettertimer.Bubble, 0)
    timers = append(timers, t1, t2)

    m := MainModel{
        timers: timers,
    }

    p := tea.NewProgram(m)
    if _, err := p.Run(); err != nil {
        fmt.Printf("error: %v", err)
        os.Exit(1)
    }
}
neel-bp commented 1 year ago

image

neel-bp commented 1 year ago

sorry i fixed it, instead of m.timers = append(m.timers, timers...) i did m.timers = timers i already did create a slice and was appending timers to it. sorry for inconvenience.