Skip to content

Commit

Permalink
feat: separate results and request params
Browse files Browse the repository at this point in the history
  • Loading branch information
jackMort committed Jan 5, 2024
1 parent f2cfba6 commit ea7fcd3
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 98 deletions.
14 changes: 11 additions & 3 deletions cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"restman/app"
"restman/components/collections"
"restman/components/footer"
"restman/components/request"
"restman/components/results"
"restman/components/tabs"
"restman/components/url"
Expand Down Expand Up @@ -95,24 +96,31 @@ Restman is a CLI tool for RESTful API.`,
m := Model{tui: boxer.Boxer{}, focused: "url", initalCall: call}

url := url.New()
middle := results.New()
resultsBox := results.New()
requestBox := request.New()
footerBox := footer.New()
colBox := collections.New()
tabs := tabs.New()

centerNode := boxer.CreateNoBorderNode()
centerNode.VerticalStacked = true
centerNode.SizeFunc = func(node boxer.Node, widthOrHeight int) []int {
size := widthOrHeight - 5
paramsSize := int(float64(size) * 0.4)
resultsSize := size - paramsSize

return []int{
2,
3,
widthOrHeight - 5,
paramsSize,
resultsSize,
}
}
centerNode.Children = []boxer.Node{
stripErr(m.tui.CreateLeaf("tabs", tabs)),
stripErr(m.tui.CreateLeaf("url", url)),
stripErr(m.tui.CreateLeaf("middle", middle)),
stripErr(m.tui.CreateLeaf("request", requestBox)),
stripErr(m.tui.CreateLeaf("results", resultsBox)),
}

// middle Node
Expand Down
2 changes: 1 addition & 1 deletion components/results/body.go → components/request/body.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package results
package request

import (
"restman/components"
Expand Down
236 changes: 236 additions & 0 deletions components/request/box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
package request

import (
"net/url"
"restman/app"
"restman/components/auth"
"restman/components/config"
"restman/components/headers"
"restman/components/params"
"restman/components/tabs"
"strings"

tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
zone "github.com/lrstanley/bubblezone"
)

func tabBorderWithBottom(left, middle, right string) lipgloss.Border {
border := lipgloss.RoundedBorder()
border.BottomLeft = left
border.Bottom = middle
border.BottomRight = right
return border
}

var (
inactiveTabBorder = tabBorderWithBottom("┴", "─", "┴")
activeTabBorder = tabBorderWithBottom("┘", " ", "└")
docStyle = lipgloss.NewStyle()
highlightColor = lipgloss.AdaptiveColor{Light: "#874BFD", Dark: "#7D56F4"}
inactiveTabStyle = lipgloss.NewStyle().Border(inactiveTabBorder, true).BorderForeground(highlightColor).Padding(0, 1)
activeTabStyle = inactiveTabStyle.Copy().Border(activeTabBorder, true)
windowStyle = lipgloss.NewStyle().BorderForeground(highlightColor).Border(lipgloss.NormalBorder()).UnsetBorderTop()
tabGap = inactiveTabStyle.Copy().
BorderTop(false).
BorderLeft(false).
BorderRight(false)

emptyMessage = lipgloss.NewStyle().Padding(2, 2).Foreground(config.COLOR_GRAY)

testStyle = lipgloss.NewStyle().
Bold(true).
Border(lipgloss.NormalBorder()).
BorderForeground(config.COLOR_SUBTLE).
PaddingLeft(1)

testStyleFocused = lipgloss.NewStyle().
Bold(true).
Border(lipgloss.NormalBorder()).
BorderForeground(config.COLOR_HIGHLIGHT).
PaddingLeft(1)

listHeader = lipgloss.NewStyle().
BorderStyle(lipgloss.NormalBorder()).
BorderBottom(true).
BorderForeground(config.COLOR_SUBTLE).
Render
)

type Request struct {
title string
focused bool
body string
width int
height int
Tabs []string
activeTab int
content tea.Model
call *app.Call
}

func New() Request {
return Request{
title: "Params",
Tabs: []string{"Params", "Headers", "Auth", "Body"},
}
}

// satisfy the tea.Model interface
func (b Request) Init() tea.Cmd {
b.activeTab = 0
return nil
}

func (b Request) GetContent() tea.Model {
if b.activeTab == 2 {
return auth.New(b.width, b.call)
} else if b.activeTab == 3 {
body := ""
if b.call != nil {
body = b.call.Data
}
return NewBody(body, b.width-2, b.height-4)
}
return nil
}

func (b Request) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {

case tabs.TabFocusedMsg:
b.call = msg.Tab.Call
b.body = msg.Tab.Results
b.content = b.GetContent()

case tea.WindowSizeMsg:
testStyle.Width(msg.Width - 2)
testStyle.Height(msg.Height - 2)
testStyleFocused.Width(msg.Width - 2)
testStyleFocused.Height(msg.Height - 2)
b.width = msg.Width
b.height = msg.Height
b.content = b.GetContent()

case tea.KeyMsg:
switch msg.String() {
case "ctrl+l":
b.activeTab = min(b.activeTab+1, len(b.Tabs)-1)
b.content = b.GetContent()

case "ctrl+h":
b.activeTab = max(b.activeTab-1, 0)
b.content = b.GetContent()
}

case config.WindowFocusedMsg:
b.focused = msg.State

}
var cmds []tea.Cmd
var cmd tea.Cmd
cmds = append(cmds, cmd)

if b.content != nil {
b.content, cmd = b.content.Update(msg)
cmds = append(cmds, cmd)
}

return b, tea.Batch(cmds...)
}

func (b *Request) SetActiveTab(tab int) {
b.activeTab = tab
b.content = b.GetContent()
}

func (b Request) View() string {
doc := strings.Builder{}

var renderedTabs []string

if b.focused {
inactiveTabStyle.BorderForeground(config.COLOR_HIGHLIGHT)
activeTabStyle.BorderForeground(config.COLOR_HIGHLIGHT)
windowStyle.BorderForeground(config.COLOR_HIGHLIGHT)
tabGap.BorderForeground(config.COLOR_HIGHLIGHT)
} else {
inactiveTabStyle.BorderForeground(config.COLOR_SUBTLE)
activeTabStyle.BorderForeground(config.COLOR_SUBTLE)
windowStyle.BorderForeground(config.COLOR_SUBTLE)
tabGap.BorderForeground(config.COLOR_SUBTLE)
}

for i, t := range b.Tabs {
var style lipgloss.Style
isFirst, isActive := i == 0, i == b.activeTab
if isActive {
style = activeTabStyle.Copy()
} else {
style = inactiveTabStyle.Copy()
}
border, _, _, _, _ := style.GetBorder()
if isFirst && isActive {
border.BottomLeft = "│"
} else if isFirst && !isActive {
border.BottomLeft = "├"
}

style = style.Border(border)
renderedTabs = append(renderedTabs, zone.Mark("tab_"+t, style.Render(t)))
}
renderedTabs = append(renderedTabs, tabGap.Render(strings.Repeat(" ", b.width-43)))

windowStyle.Height(b.height - 4)

style := inactiveTabStyle.Copy()
border, _, _, _, _ := style.GetBorder()
border.Right = " "
border.BottomRight = "┐"
style = style.Border(border).BorderTop(false).BorderLeft(false)
renderedTabs = append(renderedTabs, style.Render(" "))
row := lipgloss.JoinHorizontal(lipgloss.Bottom, renderedTabs...)
doc.WriteString(row)
doc.WriteString("\n")

var content string
if b.activeTab == 0 {
content = emptyMessage.Render("No url params")
if b.call != nil {

u, err := url.Parse(b.call.Url)
if err == nil && b.call.Url != "" {
m, _ := url.ParseQuery(u.RawQuery)
if len(m) > 0 {

table := params.New(m, b.width, b.height)
content = lipgloss.NewStyle().
UnsetBold().
Render(
table.View(),
)
}
}
}
} else if b.activeTab == 1 {
h := []string{}
if b.call != nil {
h = b.call.Headers
}
table := headers.New(h, b.width-2, b.width)
content = lipgloss.NewStyle().
UnsetBold().
Render(
table.View(),
)
} else if b.activeTab == 2 {
content = b.content.View()
} else if b.activeTab == 3 {
content = b.content.View()
} else {
content = emptyMessage.Render("Not implemented yet")
}

doc.WriteString(windowStyle.Width((lipgloss.Width(row) - windowStyle.GetHorizontalFrameSize())).Render(content))
return docStyle.Render(doc.String())
}
Loading

0 comments on commit ea7fcd3

Please sign in to comment.