--- /dev/null
+package screens
+
+// A simple program demonstrating the text area component from the Bubbles
+// component library.
+
+import (
+ "fmt"
+ "strings"
+ "os"
+ "github.com/repoman-cli/ui"
+ "github.com/repoman-cli/api"
+ "github.com/charmbracelet/bubbles/textarea"
+ "github.com/charmbracelet/bubbles/viewport"
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
+)
+
+
+type (
+ errMsg error
+)
+
+type cmdReturn struct {
+ ReturnCode int
+ Terminated bool
+}
+
+type CmdExecMsg cmdReturn
+
+type RepomanShellModel struct {
+ APIStatus api.APIStatusMsg
+ viewport viewport.Model
+ messages []string
+ textarea textarea.Model
+ senderStyle lipgloss.Style
+ err error
+ Width int
+ Height int
+ topBar string
+ footer string
+ CmdExecStatus CmdExecMsg
+}
+
+func NewShellScreenModel() RepomanShellModel {
+ // Get terminal size
+ w, h, err := ui.GetWindowSize()
+ if err != nil {
+ fmt.Printf("Could not get terminal window size.")
+ os.Exit(1)
+ }
+
+ // Top bar styling
+ roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
+ labelArrow := ui.LabelArrowStyle.Render("")
+ titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
+ rightTopBarBlock := ui.TopBarRightLabel.Render(" Repoman Shell ")
+
+ topBarBlock := ui.TopBarStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
+ ui.TopBarLeftStyle.Width((w / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
+ ui.TopBarRightStyle.Width((w / 2 ) - 1).Render(rightTopBarBlock)))
+
+ topBarBlockHeight := lipgloss.Height(topBarBlock)
+
+ // Footer styling
+ copyrightBlock := ui.SubtleStyle.Render("2024 Copyright - Repoman")
+
+ helpBlock := fmt.Sprintf("%s\n%s\n%s",
+ ui.SubtleStyle.Render("Ctrl+C, Esc - Exit program"),
+ ui.SubtleStyle.Render("Ctrl+D - Main menu"),
+ ui.SubtleStyle.Render("Ctrl+L - Clear Screen"))
+
+ footerBlock := ui.FooterStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
+ ui.FooterLeftStyle.Width((w / 2 ) - 1).Render(copyrightBlock),
+ ui.FooterRightStyle.Width((w / 2 ) - 1).Render(helpBlock)))
+
+ footerBlockHeight := lipgloss.Height(footerBlock)
+
+
+ ta := textarea.New()
+ ta.Placeholder = "Type in a command or enter 'help' if you are lost"
+ ta.Focus()
+
+ ta.Prompt = "┃ repoman $ ❯ "
+ ta.CharLimit = 280
+
+ ta.SetWidth(w - 2)
+ ta.SetHeight(1)
+
+ // Remove cursor line styling
+ ta.FocusedStyle.CursorLine = lipgloss.NewStyle()
+
+ ta.ShowLineNumbers = false
+
+ var initialViewportMsg []string
+ initialViewportMsg = append(initialViewportMsg, ui.SubtleStyle.Render(fmt.Sprintf("No, you can't run any scripts here\nThis is not Bash, Zshhh or any type of fish \nHowever, you can manage your self-hosted git repos from here, isn't that even better ?! ( ^ . ^ )")))
+
+ vp := viewport.New(w - 2, h - topBarBlockHeight - footerBlockHeight - 1)
+ vp.SetContent(strings.Join(initialViewportMsg, "\n"))
+
+ ta.KeyMap.InsertNewline.SetEnabled(false)
+
+ return RepomanShellModel{
+ APIStatus: api.APIStatusMsg{},
+ textarea: ta,
+ messages: initialViewportMsg,
+ viewport: vp,
+ senderStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("5")),
+ err: nil,
+ Width: w,
+ Height: h,
+ topBar: topBarBlock,
+ footer: footerBlock,
+ CmdExecStatus: CmdExecMsg{ Terminated: true },
+ }
+}
+
+func (m *RepomanShellModel) Init() tea.Cmd {
+ return textarea.Blink
+}
+
+func (m *RepomanShellModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ var (
+ tiCmd tea.Cmd
+ vpCmd tea.Cmd
+ )
+
+ m.textarea, tiCmd = m.textarea.Update(msg)
+ m.viewport, vpCmd = m.viewport.Update(msg)
+
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ switch msg.Type {
+ case tea.KeyCtrlC, tea.KeyEsc:
+ fmt.Println(m.textarea.Value())
+ return m, tea.Quit
+
+ case tea.KeyCtrlD:
+ mainMenu := MainMenu()
+ return RootScreen().SwitchScreen(&mainMenu)
+
+ case tea.KeyEnter:
+ if m.CmdExecStatus.Terminated {
+ m, cmd := parseCmd(m, m.textarea.Value())
+ return m, tea.Batch(cmd, ExecNotify(0, false))
+ }
+
+ case tea.KeyCtrlL:
+ m.messages = []string{}
+ m.viewport.SetContent("$ ❯ ")
+ }
+
+ // We handle errors just like any other message
+ case errMsg:
+ m.err = msg
+ return m, nil
+
+ case tea.WindowSizeMsg:
+ w, h, _ := ui.GetWindowSize()
+ m.Width = w
+ m.Height = h
+ m.textarea.SetWidth(w - 2)
+ m.viewport = viewport.New(w - 2, h - lipgloss.Height(m.topBar) - lipgloss.Height(m.footer) - 1)
+ m.viewport.SetContent(strings.Join(m.messages, "\n"))
+
+ case api.APIStatusMsg:
+ m.APIStatus = msg
+ cmdResult := fmt.Sprintf("%s\n%s", m.senderStyle.Render("$ ❯ ") + m.textarea.Value(), m.APIStatus )
+ m.messages = append(m.messages, cmdResult)
+ m.viewport.SetContent(strings.Join(m.messages, "\n"))
+ m.textarea.Reset()
+ //m.CmdExecStatus.Terminated = true
+ return m, ExecNotify(0, true)
+
+ case CmdExecMsg:
+ m.CmdExecStatus.Terminated = msg.Terminated
+ }
+
+ return m, tea.Batch(tiCmd, vpCmd)
+}
+
+func (m *RepomanShellModel) View() string {
+
+ // Top bar styling
+ roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
+ labelArrow := ui.LabelArrowStyle.Render("")
+ titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
+ rightTopBarBlock := ui.TopBarRightLabel.Render(" Repoman Shell ")
+
+ topBarBlock := ui.TopBarStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
+ ui.TopBarLeftStyle.Width((m.Width / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
+ ui.TopBarRightStyle.Width((m.Width / 2 ) - 1).Render(rightTopBarBlock)))
+
+ m.topBar = topBarBlock
+
+// Footer styling
+ copyrightBlock := ui.SubtleStyle.Render("2024 Copyright - Repoman")
+
+ helpBlock := fmt.Sprintf("%s\n%s\n%s",
+ ui.SubtleStyle.Render("Ctrl+C, Esc - Exit program"),
+ ui.SubtleStyle.Render("Ctrl+D - Main menu"),
+ ui.SubtleStyle.Render("Ctrl+L - Clear Screen"))
+
+ footerBlock := ui.FooterStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
+ ui.FooterLeftStyle.Width((m.Width / 2 ) - 1).Render(copyrightBlock),
+ ui.FooterRightStyle.Width((m.Width / 2 ) - 1).Render(helpBlock)))
+
+ m.footer = footerBlock
+
+
+ return lipgloss.PlaceHorizontal(m.Width, lipgloss.Center, lipgloss.JoinVertical(lipgloss.Left, m.topBar, m.viewport.View(), m.textarea.View(), m.footer ))
+}
+
+
+func parseCmd(m *RepomanShellModel, cmd string) (tea.Model, tea.Cmd){
+ var cmdReturn string
+
+ if cmd != "" {
+ switch cmd {
+ case "help", "?":
+ cmdReturn = "Well I can't help you neither buddy"
+ m.messages = append(m.messages, m.senderStyle.Render(fmt.Sprintf("$ ❯ %s\n%s", m.textarea.Value(), cmdReturn)))
+
+ case "checkapi":
+ return m, api.HandleAPIStatusRequest(api.StatusUrl)
+
+ case "menu", "quit":
+ mainMenuModel := MainMenu()
+ return RootScreen().SwitchScreen(&mainMenuModel)
+
+ case "clear":
+ m.messages = []string{}
+ m.viewport.SetContent("$ ❯ ")
+
+ case "exit":
+ return m, tea.Quit
+
+ default:
+ m.messages = append(m.messages, m.senderStyle.Render("$ ❯ Unknown command: " + m.textarea.Value()))
+
+ }
+ } else {
+ m.messages = append(m.messages, m.senderStyle.Render("$ ❯ "))
+ }
+
+ m.viewport.SetContent(strings.Join(m.messages, "\n"))
+ m.textarea.Reset()
+ m.viewport.GotoBottom()
+
+ return m, ExecNotify(0, true)
+}
+
+func ExecNotify(returnCode int, terminated bool ) tea.Cmd {
+ cmdReturn := CmdExecMsg{ ReturnCode: returnCode,
+ Terminated: terminated, }
+ return func() tea.Msg {
+ return cmdReturn
+ }
+ }
+
+++ /dev/null
-package screens
-
-// A simple program demonstrating the text area component from the Bubbles
-// component library.
-
-import (
- "fmt"
- "strings"
- "os"
- "github.com/repoman-cli/ui"
- "github.com/charmbracelet/bubbles/textarea"
- "github.com/charmbracelet/bubbles/viewport"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
-)
-
-
-type (
- errMsg error
-)
-
-type RepomanShellModel struct {
- viewport viewport.Model
- messages []string
- textarea textarea.Model
- senderStyle lipgloss.Style
- err error
- Width int
- Height int
- topBar string
-}
-
-func NewShellScreenModel() RepomanShellModel {
- // Get terminal size
- w, h, err := ui.GetWindowSize()
- if err != nil {
- fmt.Printf("Could not get terminal window size.")
- os.Exit(1)
- }
-
- // Top bar styling
- roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
- labelArrow := ui.LabelArrowStyle.Render("")
- titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
- rightTopBarBlock := ui.TopBarRightLabel.Render(" Repoman Shell ")
-
- topBarBlock := ui.TopBarStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
- ui.TopBarLeftStyle.Width((w / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
- ui.TopBarRightStyle.Width((w / 2 ) - 1).Render(rightTopBarBlock)))
-
- topBarBlockHeight := lipgloss.Height(topBarBlock)
-
- ta := textarea.New()
- ta.Placeholder = "Type in a command or enter 'help' if you are lost"
- ta.Focus()
-
- ta.Prompt = "┃ repoman $ ❯ "
- ta.CharLimit = 280
-
- ta.SetWidth(w)
- ta.SetHeight(1)
-
- // Remove cursor line styling
- ta.FocusedStyle.CursorLine = lipgloss.NewStyle()
-
- ta.ShowLineNumbers = false
-
- vp := viewport.New(w, h - topBarBlockHeight - 1)
- vp.SetContent(ui.SubtleStyle.Render(`This is not Bash, Zshhh or some type of fish `))
-
- ta.KeyMap.InsertNewline.SetEnabled(false)
-
- return RepomanShellModel{
- textarea: ta,
- messages: []string{},
- viewport: vp,
- senderStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("5")),
- err: nil,
- Width: w,
- Height: h,
- topBar: topBarBlock,
- }
-}
-
-func (m *RepomanShellModel) Init() tea.Cmd {
- return textarea.Blink
-}
-
-func (m *RepomanShellModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
- var (
- tiCmd tea.Cmd
- vpCmd tea.Cmd
- )
-
- m.textarea, tiCmd = m.textarea.Update(msg)
- m.viewport, vpCmd = m.viewport.Update(msg)
-
- switch msg := msg.(type) {
- case tea.KeyMsg:
- switch msg.Type {
- case tea.KeyCtrlC, tea.KeyEsc:
- fmt.Println(m.textarea.Value())
- return m, tea.Quit
-
- case tea.KeyEnter:
- m, cmd := parseCmd(m, m.textarea.Value())
- return m, cmd
- case tea.KeyCtrlL:
- m.messages = []string{}
- m.viewport.SetContent("$ ❯ ")
- }
-
- // We handle errors just like any other message
- case errMsg:
- m.err = msg
- return m, nil
-
- case tea.WindowSizeMsg:
- w, h, _ := ui.GetWindowSize()
- m.Width = w
- m.Height = h
- m.textarea.SetWidth(w)
- m.viewport = viewport.New(w, h - lipgloss.Height(m.topBar) - 1)
- m.viewport.SetContent(strings.Join(m.messages, "\n"))
- }
-
- return m, tea.Batch(tiCmd, vpCmd)
-}
-
-func (m *RepomanShellModel) View() string {
-
- // Top bar styling
- roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
- labelArrow := ui.LabelArrowStyle.Render("")
- titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
- rightTopBarBlock := ui.TopBarRightLabel.Render(" Repoman Shell ")
-
- topBarBlock := ui.TopBarStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
- ui.TopBarLeftStyle.Width((m.Width / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
- ui.TopBarRightStyle.Width((m.Width / 2 ) - 1).Render(rightTopBarBlock)))
-
- m.topBar = topBarBlock
-
- return lipgloss.PlaceHorizontal(m.Width, lipgloss.Center, lipgloss.JoinVertical(lipgloss.Left, m.topBar, m.viewport.View(), m.textarea.View()))
-}
-
-
-func parseCmd(m *RepomanShellModel, cmd string) (tea.Model, tea.Cmd){
- var cmdReturn string
- if cmd != "" {
- switch cmd {
- case "help", "?":
- cmdReturn = "Well I can't help you neither buddy"
- m.messages = append(m.messages, m.senderStyle.Render(fmt.Sprintf("$ ❯ %s\n%s", m.textarea.Value(), cmdReturn)))
-
- case "menu", "quit":
- mainMenuModel := MainMenu()
- return RootScreen().SwitchScreen(&mainMenuModel)
-
- case "exit":
- return m, tea.Quit
-
- default:
- m.messages = append(m.messages, m.senderStyle.Render("$ ❯ Unknown command: " + m.textarea.Value()))
-
- }
- } else {
- m.messages = append(m.messages, m.senderStyle.Render("$ ❯ "))
- }
-
- m.viewport.SetContent(strings.Join(m.messages, "\n"))
- m.textarea.Reset()
- m.viewport.GotoBottom()
-
- return m, nil
-}