@@ -3,147 +3,52 @@ package ui
33import (
44 "context"
55 "errors"
6- "time "
6+ "os "
77
88 tea "github.com/charmbracelet/bubbletea"
9+ "github.com/localstack/lstk/internal/api"
910 "github.com/localstack/lstk/internal/auth"
10- "github.com/localstack/lstk/internal/ui/components"
11- "github.com/localstack/lstk/internal/ui/styles"
11+ "github.com/localstack/lstk/internal/output"
1212)
1313
14- const minSpinnerDuration = 400 * time .Millisecond
14+ func RunLogout (parentCtx context.Context , version string , platformClient api.PlatformAPI , tokenStorage auth.AuthTokenStorage ) error {
15+ _ , cancel := context .WithCancel (parentCtx )
16+ defer cancel ()
1517
16- type logoutSuccessMsg struct {}
17-
18- type logoutNotLoggedInMsg struct {}
19-
20- type logoutErrMsg struct {
21- err error
22- }
23-
24- type logoutState int
25-
26- const (
27- logoutStateLoading logoutState = iota
28- logoutStateSuccess
29- logoutStateNotLoggedIn
30- )
31-
32- type LogoutApp struct {
33- header components.Header
34- spinner components.Spinner
35- state logoutState
36- err error
37- }
38-
39- func NewLogoutApp (version string ) LogoutApp {
40- return LogoutApp {
41- header : components .NewHeader (version ),
42- spinner : components .NewSpinner ().Show ("Logging out" ),
43- state : logoutStateLoading ,
44- }
45- }
46-
47- func (a LogoutApp ) Init () tea.Cmd {
48- return a .spinner .Tick ()
49- }
50-
51- func (a LogoutApp ) Update (msg tea.Msg ) (tea.Model , tea.Cmd ) {
52- switch msg := msg .(type ) {
53- case tea.KeyMsg :
54- if msg .String () == "ctrl+c" || msg .String () == "q" {
55- return a , tea .Quit
56- }
57-
58- case logoutSuccessMsg :
59- a .spinner = a .spinner .Hide ()
60- a .state = logoutStateSuccess
61- return a , tea .Quit
62-
63- case logoutNotLoggedInMsg :
64- a .spinner = a .spinner .Hide ()
65- a .state = logoutStateNotLoggedIn
66- return a , tea .Quit
67-
68- case logoutErrMsg :
69- a .spinner = a .spinner .Hide ()
70- a .err = msg .err
71- return a , tea .Quit
72-
73- default :
74- var cmd tea.Cmd
75- a .spinner , cmd = a .spinner .Update (msg )
76- return a , cmd
77- }
78-
79- return a , nil
80- }
81-
82- func (a LogoutApp ) View () string {
83- var s string
84- s += a .header .View ()
85- s += "\n "
86-
87- if a .spinner .Visible () {
88- s += a .spinner .View () + "\n "
89- }
90-
91- switch a .state {
92- case logoutStateSuccess :
93- s += renderLogoutSuccess () + "\n "
94- case logoutStateNotLoggedIn :
95- s += renderLogoutNotLoggedIn () + "\n "
96- }
97-
98- return s
99- }
100-
101- func renderLogoutSuccess () string {
102- prefix := styles .Secondary .Render ("> " )
103- return prefix + styles .Success .Render ("Success:" ) + " " + styles .Message .Render ("Logged out successfully." )
104- }
105-
106- func renderLogoutNotLoggedIn () string {
107- prefix := styles .Secondary .Render ("> " )
108- return prefix + styles .Note .Render ("Note:" ) + " " + styles .Message .Render ("Not currently logged in." )
109- }
110-
111- func (a LogoutApp ) Err () error {
112- return a .err
113- }
114-
115- func RunLogout (ctx context.Context , version string , a * auth.Auth ) error {
116- app := NewLogoutApp (version )
117- p := tea .NewProgram (app )
18+ app := NewApp (version , cancel )
19+ p := tea .NewProgram (app , tea .WithInput (os .Stdin ), tea .WithOutput (os .Stdout ))
20+ runErrCh := make (chan error , 1 )
11821
11922 go func () {
120- start := time . Now ( )
23+ a := auth . New ( output . NewTUISink ( programSender { p : p }), platformClient , tokenStorage , false )
12124 err := a .Logout ()
122-
123- // Ensure spinner is visible for minimum duration
124- elapsed := time .Since (start )
125- if elapsed < minSpinnerDuration {
126- time .Sleep (minSpinnerDuration - elapsed )
127- }
128-
12925 if errors .Is (err , auth .ErrNotLoggedIn ) {
130- p .Send (logoutNotLoggedInMsg {})
131- return
26+ err = nil
13227 }
28+ runErrCh <- err
29+
13330 if err != nil {
134- p .Send (logoutErrMsg {err : err })
31+ if errors .Is (err , context .Canceled ) {
32+ return
33+ }
34+ p .Send (runErrMsg {err : err })
13535 return
13636 }
137- p .Send (logoutSuccessMsg {})
37+ p .Send (runDoneMsg {})
13838 }()
13939
14040 model , err := p .Run ()
14141 if err != nil {
14242 return err
14343 }
14444
145- if logoutApp , ok := model .(LogoutApp ); ok && logoutApp .Err () != nil {
146- return logoutApp .Err ()
45+ if app , ok := model .(App ); ok && app .Err () != nil {
46+ return app .Err ()
47+ }
48+
49+ runErr := <- runErrCh
50+ if runErr != nil && ! errors .Is (runErr , context .Canceled ) {
51+ return runErr
14752 }
14853
14954 return nil
0 commit comments