theckman / yacspin

Yet Another CLi Spinner; providing over 80 easy to use and customizable terminal spinners for multiple OSes
Apache License 2.0
434 stars 13 forks source link

Using uilive to render multiple outputs #70

Open Wulfheart opened 1 year ago

Wulfheart commented 1 year ago

I tried to use uilive to make multiple parallel spinners work based on this comment on stackoverflow.

The code itself looks like this:

package main

import (
    "fmt"
    "github.com/gosuri/uilive"
    "github.com/theckman/yacspin"
    "io"
    "time"
)

func main() {
    writer := uilive.New()
    writer2 := writer.Newline()
    writer.Start()
    defer writer.Stop()
    spinner1, _ := createSpinner1(writer)
    spinner2, _ := createSpinner2(writer2)
    spinner1.Start()
    time.Sleep(2 * time.Second)
    // update message
    spinner1.Message("uploading files")
    time.Sleep(2 * time.Second)
    spinner2.Start()
    time.Sleep(2 * time.Second)
    spinner1.Message("test")
    time.Sleep(2 * time.Second)
    spinner2.Stop()
    spinner1.Stop()
}

func createSpinner1(writer io.Writer) (*yacspin.Spinner, error) {
    // build the configuration, each field is documented
    cfg := yacspin.Config{
        Prefix:            "s1",
        Writer:            writer,
        Frequency:         100 * time.Millisecond,
        CharSet:           yacspin.CharSets[11],
        Suffix:            " ", // puts a least one space between the animating spinner and the Message
        Message:           "collecting files",
        SuffixAutoColon:   true,
        ColorAll:          true,
        Colors:            []string{"fgYellow"},
        StopCharacter:     "✓",
        StopColors:        []string{"fgGreen"},
        StopMessage:       "done",
        StopFailCharacter: "✗",
        StopFailColors:    []string{"fgRed"},
        StopFailMessage:   "failed",
    }

    s, err := yacspin.New(cfg)
    if err != nil {
        return nil, fmt.Errorf("failed to make spinner from struct: %w", err)
    }

    return s, nil
}
func createSpinner2(writer io.Writer) (*yacspin.Spinner, error) {
    // build the configuration, each field is documented
    cfg := yacspin.Config{
        Writer:            writer,
        Prefix:            "s2",
        Frequency:         100 * time.Millisecond,
        CharSet:           yacspin.CharSets[11],
        Suffix:            " ", // puts a least one space between the animating spinner and the Message
        Message:           "doing stuff",
        SuffixAutoColon:   true,
        ColorAll:          true,
        Colors:            []string{"fgYellow"},
        StopCharacter:     "✓",
        StopColors:        []string{"fgGreen"},
        StopMessage:       "done",
        StopFailCharacter: "✗",
        StopFailColors:    []string{"fgRed"},
        StopFailMessage:   "failed",
    }

    s, err := yacspin.New(cfg)
    if err != nil {
        return nil, fmt.Errorf("failed to make spinner from struct: %w", err)
    }

    return s, nil
}

I have absolutely no idea why this does not work as it should write to two different writers as in spinner.go in line 830 defined:

    if s.buffer.Len() > 0 {
        if _, err := s.writer.Write(s.buffer.Bytes()); err != nil {
            panic(fmt.Sprintf("failed to output buffer to writer: %v", err))
        }
    }

Could you please offer some assistance?

Thanks in advance.