From: christiangoeschel Date: Tue, 1 Oct 2024 23:37:52 +0000 (-0400) Subject: Refactoring X-Git-Url: https://git.christiangoeschel.com/?a=commitdiff_plain;h=920722eba326f2d8f976d5a9ec3600f11ba15525;p=repoman-cli.git Refactoring --- diff --git a/api/api.go b/api/api.go new file mode 100644 index 0000000..6b1bdd2 --- /dev/null +++ b/api/api.go @@ -0,0 +1,66 @@ +package api + + +import( + "fmt" + "net/http" + "io/ioutil" + "encoding/json" + "time" + tea "github.com/charmbracelet/bubbletea" +) + +const ( + StatusUrl = "https://repoman.christiangoeschel.com:8443/status" +) + +// API Status Handle +func HandleAPIStatusRequest(url string) tea.Cmd { + + return func() tea.Msg { + var ApiStatus APIStatusMsg + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + fmt.Print(err.Error()) + } + + client := http.Client{ + Timeout: 10 * time.Second, + } + + res, err := client.Do(req) + if err != nil { + return APIStatusMsg { + Status: "Unreachable", + Description: "", + StartDateTime: "", + EstimatedEndTime: "", + } + } + defer res.Body.Close() + + body, readErr := ioutil.ReadAll(res.Body) + if readErr != nil { + fmt.Print(err.Error()) + } + + if err := json.Unmarshal(body, &ApiStatus); err != nil { // Parse []byte to the go struct pointer + fmt.Println("Can not unmarshal JSON") + } + + return ApiStatus + } +} + +type APIStatusMsg APIStatus + +type APIStatus struct { + Status string `json:"Status"` + Description string `json:"Description"` + StartDateTime string `json:"StartDateTime"` + EstimatedEndTime string `json:"EstimatedEndTime"` +} + + + diff --git a/api/go.mod b/api/go.mod new file mode 100644 index 0000000..dc6a822 --- /dev/null +++ b/api/go.mod @@ -0,0 +1,24 @@ +module git.christiangoeschel.com/repoman-cli/api + +go 1.23.0 + +require github.com/charmbracelet/bubbletea v1.1.1 + +require ( + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/lipgloss v0.13.0 // indirect + github.com/charmbracelet/x/ansi v0.2.3 // indirect + github.com/charmbracelet/x/term v0.2.0 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/termenv v0.15.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.3.8 // indirect +) diff --git a/api/go.sum b/api/go.sum new file mode 100644 index 0000000..161a3de --- /dev/null +++ b/api/go.sum @@ -0,0 +1,37 @@ +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY= +github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= +github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= +github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= +github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY= +github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= +github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/go.mod b/go.mod index d1ae828..673c02a 100644 --- a/go.mod +++ b/go.mod @@ -10,17 +10,18 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/bubbles v0.20.0 // indirect github.com/charmbracelet/x/ansi v0.2.3 // indirect github.com/charmbracelet/x/term v0.2.0 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.15.2 // indirect - github.com/repoman-cli/lib v0.0.0-00010101000000-000000000000 // indirect + github.com/repoman-cli/api v0.0.0-00010101000000-000000000000 // indirect github.com/repoman-cli/themes v0.0.0-00010101000000-000000000000 // indirect github.com/rivo/uniseg v0.4.7 // indirect golang.org/x/sync v0.8.0 // indirect @@ -33,3 +34,5 @@ replace github.com/repoman-cli/lib => /home/cgoesche/repoman-cli/lib replace github.com/repoman-cli/themes => /home/cgoesche/repoman-cli/themes replace github.com/repoman-cli/screens => /home/cgoesche/repoman-cli/screens + +replace github.com/repoman-cli/api => /home/cgoesche/repoman-cli/api diff --git a/go.sum b/go.sum index 161a3de..daac317 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= +github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY= github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= @@ -16,8 +18,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= diff --git a/main b/main index d69066c..3bb7e68 100755 Binary files a/main and b/main differ diff --git a/main.go b/main.go index a3e0e58..d6e01bb 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( // Main func main(){ - p := tea.NewProgram(screens.RootScreen(0), tea.WithAltScreen()) + p := tea.NewProgram(screens.RootScreen(), tea.WithAltScreen()) if _, err := p.Run(); err != nil { fmt.Println("Error starting program:", err) os.Exit(1) diff --git a/screens/apistatus.go b/screens/apistatus.go index 388c5fa..daad6a2 100644 --- a/screens/apistatus.go +++ b/screens/apistatus.go @@ -2,17 +2,23 @@ package screens import ( - //"fmt" + "fmt" tea "github.com/charmbracelet/bubbletea" "github.com/repoman-cli/themes" + "github.com/charmbracelet/bubbles/spinner" + "github.com/repoman-cli/api" ) type APIStatusScreenModel struct { - APIStatus string + APIStatus api.APIStatusMsg URL string Err error StatusCode int + Spinner spinner.Model + ReqReceived bool + Requested bool + //PrevScreen tea.Model } @@ -20,17 +26,24 @@ type APIStatusScreenModel struct { // Creates a new mainMenuScreenModel func NewAPIStatusScreen() APIStatusScreenModel { + s := spinner.New() + s.Spinner = spinner.Pulse + s.Style = themes.SpinnerStyle + return APIStatusScreenModel { - APIStatus: "Normal", + APIStatus: api.APIStatusMsg{}, URL: "https://repoman.christiangoeschel.com:8443/status", Err: nil, StatusCode: 200, + Spinner: s, + ReqReceived: false, + Requested: false, } } // Init func (m *APIStatusScreenModel) Init() tea.Cmd { - return nil + return m.Spinner.Tick } // Update @@ -39,14 +52,32 @@ func (m *APIStatusScreenModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { - case "q": + case "q", "backspace": mainMenu := MainMenu() - return RootScreen(0).SwitchScreen(&mainMenu) - - } + return RootScreen().SwitchScreen(&mainMenu) + + case "enter": + m.APIStatus = api.APIStatusMsg{} + m.ReqReceived = false + m.Requested = true + return m, api.HandleAPIStatusRequest(api.StatusUrl) + + } + + case api.APIStatusMsg: + m.APIStatus = msg + m.ReqReceived = true + m.Requested = false + return m, nil - default: - return m, nil + case spinner.TickMsg: + + //if m.ReqReceived == false && m.Requested == true { + var cmd tea.Cmd + m.Spinner, cmd = m.Spinner.Update(msg) + return m, cmd + //} + } return m, nil @@ -56,7 +87,32 @@ func (m *APIStatusScreenModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *APIStatusScreenModel) View() string { msg := themes.KeywordStyle.Render("API Status") + + statusResponse := fmt.Sprintf("Status: %s\nDescription: %s\nStart: %s\nExpected End: %s\n", + themes.KeywordStyle.Render(m.APIStatus.Status), + themes.KeywordStyle.Render(m.APIStatus.Description), + themes.KeywordStyle.Render(m.APIStatus.StartDateTime), + themes.KeywordStyle.Render(m.APIStatus.EstimatedEndTime)) + + msg = fmt.Sprintf("%s\n\nRequesting API Server Status from:\n\n", + themes.TitleStyle.Render("[ +-+ API Server Status +-+ ]")) + + msg += fmt.Sprintf("%s\n\n%s\n%s\n", + themes.KeywordStyle.Render(api.StatusUrl), + statusResponse, + themes.SubtleStyle.Render("Press Enter to refresh")) + + msg += "\n%s" + + + switch m.ReqReceived { + case false: + if m.Requested == true { + return themes.MainStyle.Render(fmt.Sprintf(msg, m.Spinner.View() + " Fetching ...")) + } + } + + return themes.MainStyle.Render(fmt.Sprintf(msg, "")) - return msg + "\n\n" } diff --git a/screens/go.mod b/screens/go.mod index 62191bb..b6b930d 100644 --- a/screens/go.mod +++ b/screens/go.mod @@ -3,8 +3,9 @@ module git.christiangoeschel.com/repoman-cli/screens go 1.23.0 require ( + github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.1.1 - github.com/repoman-cli/lib v0.0.0-00010101000000-000000000000 + github.com/repoman-cli/themes v0.0.0-00010101000000-000000000000 ) require ( @@ -16,7 +17,7 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.15.2 // indirect @@ -27,4 +28,5 @@ require ( ) replace github.com/repoman-cli/themes => /home/cgoesche/repoman-cli/themes + replace github.com/repoman-cli/lib => /home/cgoesche/repoman-cli/lib diff --git a/screens/go.sum b/screens/go.sum index 161a3de..daac317 100644 --- a/screens/go.sum +++ b/screens/go.sum @@ -1,5 +1,7 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= +github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY= github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= @@ -16,8 +18,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= diff --git a/screens/root.go b/screens/root.go index 5b7709f..d108578 100644 --- a/screens/root.go +++ b/screens/root.go @@ -2,8 +2,8 @@ package screens import ( "fmt" - "github.com/repoman-cli/lib" - //"github.com/repoman-cli/themes" + //"github.com/repoman-cli/lib" + "github.com/repoman-cli/themes" tea "github.com/charmbracelet/bubbletea" ) @@ -12,13 +12,23 @@ import ( // Root Screen Model type rootScreenModel struct { model tea.Model // Contains the current screen model which represents the programs current state - theme int } //Main Menu Screen type mainMenuScreenModel struct { - Title string - Message string + Title string + Message string + OptionChoice int + } + +var mainMenuOptions = []string{ + "List all repos", + "Create a new repository", + "Delete a repository", + "Manage API Keys", + "Check API Status", + "Settings", + "Quit", } @@ -40,18 +50,18 @@ func (m rootScreenModel) View() string { // --- Utils // Creates a new model based on what RootScreenModel.model Contains -func RootScreen(theme int) rootScreenModel { +func RootScreen() rootScreenModel { var rootModel tea.Model // Set the rootModel (current state) to be the mainMenuScreen mainMenu := MainMenu() rootModel = &mainMenu - + + _ = themes.ChangeTheme(themes.DefaultTheme) return rootScreenModel { model: rootModel, - theme: theme, } } @@ -80,21 +90,38 @@ func (m *mainMenuScreenModel) Init() tea.Cmd { // Update func (m *mainMenuScreenModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - + switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "q": - return m, tea.Quit - - case "n": + case tea.KeyMsg: + var lastChoice int = len(mainMenuOptions) - 1 + + switch msg.String() { + + case "j", "down": + m.OptionChoice++ + if m.OptionChoice > lastChoice { + m.OptionChoice = 0 + } + + case "k", "up": + m.OptionChoice-- + if m.OptionChoice < 0 { + m.OptionChoice = lastChoice + } + + case "enter", " ": + + if mainMenuOptions[m.OptionChoice] == "Check API Status" { apiStatusScreen := NewAPIStatusScreen() - return RootScreen(0).SwitchScreen(&apiStatusScreen) - } - + return RootScreen().SwitchScreen(&apiStatusScreen) + } else if mainMenuOptions[m.OptionChoice] == "Quit" { + return m, tea.Quit + } + + return m, nil + } - default: - return m, nil + return m, nil } return m, nil @@ -103,10 +130,29 @@ func (m *mainMenuScreenModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // View func (m *mainMenuScreenModel) View() string { - programInfo := lib.GetProgramInfo() + c := m.OptionChoice + + tpl := fmt.Sprintf("%s\n\n", themes.TitleStyle.Render("[ +-+ Repoman CLI +-+ ]")) + tpl += "Main Menu\n\n" + tpl += "%s\n\n" + tpl += fmt.Sprintf("%s\n%s\n%s\n%s\n", + themes.SubtleStyle.Render("j/k, up/down: select"), + themes.SubtleStyle.Render("enter, spacebar: choose"), + themes.SubtleStyle.Render("q, esc: quit"), + themes.SubtleStyle.Render("backspace: main menu")) + + var opts string + for i := 0;i < len(mainMenuOptions);i++{ + opts += fmt.Sprintf("%s\n", checkbox(mainMenuOptions[i], c == i)) + } - message := fmt.Sprintf("%s\n\n%s", programInfo.ProgramName, programInfo.BuildID) - return message + return themes.MainStyle.Render(fmt.Sprintf(tpl, opts)) + } - +func checkbox(label string, checked bool) string { + if checked { + return themes.CheckboxStyle.Render("+ " + label) + } + return fmt.Sprintf("- %s", label) +} diff --git a/themes/default-theme.go b/themes/default-theme.go index 9cf35df..6a31224 100644 --- a/themes/default-theme.go +++ b/themes/default-theme.go @@ -6,22 +6,37 @@ import ( ) var ( - spinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) + DefaultTheme = 0 + CurrentTheme = 0 + + SpinnerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) KeywordStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("211")) - subtleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")) - checkboxStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#03A9F4")) - titleStyle = lipgloss.NewStyle().Background(lipgloss.Color("#448AFF")).Foreground(lipgloss.Color("#FFFFFF")) - statusOK = lipgloss.NewStyle().Foreground(lipgloss.Color("200")) - mainStyle = lipgloss.NewStyle().Margin(15).Padding(10) + SubtleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")) + CheckboxStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#03A9F4")) + TitleStyle = lipgloss.NewStyle().Background(lipgloss.Color("#448AFF")).Foreground(lipgloss.Color("#FFFFFF")) + StatusOK = lipgloss.NewStyle().Foreground(lipgloss.Color("200")) + MainStyle = lipgloss.NewStyle().MarginLeft(10).MarginTop(20) Altstyle = lipgloss.NewStyle().BorderStyle(lipgloss.NormalBorder()).BorderForeground(lipgloss.Color("63")) ) func ChangeTheme(themeID int) (err error) { - if themeID == 0 { + switch themeID { + case 0: KeywordStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("200")) return nil + + case 1: + KeywordStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("190")) + return nil } + + return nil +} + +func SetTheme(themeID int) (err error) { + DefaultTheme = themeID + _ = ChangeTheme(DefaultTheme) return nil }