github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/pkg/terminal/glint_status.go (about) 1 package terminal 2 3 import ( 4 "context" 5 "sync" 6 7 "github.com/mitchellh/go-glint" 8 gc "github.com/mitchellh/go-glint/components" 9 ) 10 11 // glintStatus implements Status and uses a spinner to show updates. 12 type glintStatus struct { 13 mu sync.Mutex 14 closed bool 15 msg string 16 spinner glint.Component 17 text []glint.Component 18 } 19 20 func newGlintStatus() *glintStatus { 21 return &glintStatus{ 22 spinner: gc.Spinner(), 23 } 24 } 25 26 func (s *glintStatus) Update(msg string) { 27 s.mu.Lock() 28 defer s.mu.Unlock() 29 s.msg = msg 30 } 31 32 func (s *glintStatus) Step(status, msg string) { 33 s.mu.Lock() 34 defer s.mu.Unlock() 35 36 // Determine our color 37 var style []glint.StyleOption 38 switch status { 39 case StatusOK: 40 style = append(style, glint.Color("lightGreen")) 41 42 case StatusError: 43 style = append(style, glint.Color("lightRed")) 44 45 case StatusWarn: 46 style = append(style, glint.Color("lightYellow")) 47 } 48 49 // If we have a prefix, set that 50 if icon, ok := statusIcons[status]; ok { 51 msg = icon + " " + msg 52 } 53 54 // Clear the message so we don't draw a spinner 55 s.msg = "" 56 57 // Add our final message 58 s.text = append(s.text, glint.Finalize(glint.Style( 59 glint.Text(msg), 60 style..., 61 ))) 62 } 63 64 func (s *glintStatus) Close() error { 65 s.mu.Lock() 66 defer s.mu.Unlock() 67 s.closed = true 68 return nil 69 } 70 71 func (s *glintStatus) reset() { 72 s.mu.Lock() 73 defer s.mu.Unlock() 74 s.text = nil 75 s.msg = "" 76 } 77 78 func (s *glintStatus) Body(context.Context) glint.Component { 79 s.mu.Lock() 80 defer s.mu.Unlock() 81 82 var cs []glint.Component 83 84 // If we have text we draw that first 85 if len(s.text) > 0 { 86 cs = append(cs, glint.Finalize(glint.Fragment(s.text...))) 87 } 88 89 // If we have a message the spinner is active and we draw that 90 if !s.closed && len(s.msg) > 0 { 91 cs = append(cs, glint.Layout( 92 s.spinner, 93 glint.Text(" "), 94 glint.Text(s.msg), 95 ).Row()) 96 } 97 98 c := glint.Fragment(cs...) 99 if s.closed { 100 c = glint.Finalize(c) 101 } 102 103 return c 104 }