mirror of
https://github.com/anotherhadi/spilltea.git
synced 2026-05-20 09:42:34 +02:00
CopyRequest -> Copy & CopyAs
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
This commit is contained in:
@@ -51,7 +51,8 @@ keybindings:
|
|||||||
left: "left,h"
|
left: "left,h"
|
||||||
right: "right,l"
|
right: "right,l"
|
||||||
cycle_focus: "tab"
|
cycle_focus: "tab"
|
||||||
copy_request: "ctrl+y"
|
copy_as: "ctrl+y"
|
||||||
|
copy: "y"
|
||||||
send_to_replay: "ctrl+r"
|
send_to_replay: "ctrl+r"
|
||||||
scroll_up: "pgup"
|
scroll_up: "pgup"
|
||||||
scroll_down: "pgdown"
|
scroll_down: "pgdown"
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ type GlobalKeys struct {
|
|||||||
Left string `mapstructure:"left"`
|
Left string `mapstructure:"left"`
|
||||||
Right string `mapstructure:"right"`
|
Right string `mapstructure:"right"`
|
||||||
CycleFocus string `mapstructure:"cycle_focus"`
|
CycleFocus string `mapstructure:"cycle_focus"`
|
||||||
CopyRequest string `mapstructure:"copy_request"`
|
CopyAs string `mapstructure:"copy_as"`
|
||||||
|
Copy string `mapstructure:"copy"`
|
||||||
SendToReplay string `mapstructure:"send_to_replay"`
|
SendToReplay string `mapstructure:"send_to_replay"`
|
||||||
ScrollUp string `mapstructure:"scroll_up"`
|
ScrollUp string `mapstructure:"scroll_up"`
|
||||||
ScrollDown string `mapstructure:"scroll_down"`
|
ScrollDown string `mapstructure:"scroll_down"`
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ type GlobalKeyMap struct {
|
|||||||
Left key.Binding
|
Left key.Binding
|
||||||
Right key.Binding
|
Right key.Binding
|
||||||
CycleFocus key.Binding
|
CycleFocus key.Binding
|
||||||
CopyRequest key.Binding
|
CopyAs key.Binding
|
||||||
|
Copy key.Binding
|
||||||
Escape key.Binding
|
Escape key.Binding
|
||||||
SendToReplay key.Binding
|
SendToReplay key.Binding
|
||||||
ScrollUp key.Binding
|
ScrollUp key.Binding
|
||||||
@@ -34,7 +35,8 @@ func newGlobalKeyMap(cfg config.GlobalKeys) GlobalKeyMap {
|
|||||||
Left: binding(cfg.Left, "scroll left"),
|
Left: binding(cfg.Left, "scroll left"),
|
||||||
Right: binding(cfg.Right, "scroll right"),
|
Right: binding(cfg.Right, "scroll right"),
|
||||||
CycleFocus: binding(cfg.CycleFocus, "cycle focus"),
|
CycleFocus: binding(cfg.CycleFocus, "cycle focus"),
|
||||||
CopyRequest: binding(cfg.CopyRequest, "copy as..."),
|
CopyAs: binding(cfg.CopyAs, "copy as..."),
|
||||||
|
Copy: binding(cfg.Copy, "copy..."),
|
||||||
Escape: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "cancel")),
|
Escape: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "cancel")),
|
||||||
SendToReplay: binding(cfg.SendToReplay, "send to replay"),
|
SendToReplay: binding(cfg.SendToReplay, "send to replay"),
|
||||||
ScrollUp: binding(cfg.ScrollUp, "scroll up"),
|
ScrollUp: binding(cfg.ScrollUp, "scroll up"),
|
||||||
@@ -47,7 +49,7 @@ func (g GlobalKeyMap) Bindings() []key.Binding {
|
|||||||
return []key.Binding{
|
return []key.Binding{
|
||||||
g.Up, g.Down, g.Left, g.Right, g.CycleFocus,
|
g.Up, g.Down, g.Left, g.Right, g.CycleFocus,
|
||||||
g.Quit, g.Escape, g.Help,
|
g.Quit, g.Escape, g.Help,
|
||||||
g.OpenLogs, g.ToggleSidebar, g.CopyRequest,
|
g.OpenLogs, g.ToggleSidebar, g.CopyAs, g.Copy,
|
||||||
g.SendToReplay, g.SendToDiff,
|
g.SendToReplay, g.SendToDiff,
|
||||||
g.ScrollUp, g.ScrollDown,
|
g.ScrollUp, g.ScrollDown,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/anotherhadi/spilltea/internal/intercept"
|
"github.com/anotherhadi/spilltea/internal/intercept"
|
||||||
"github.com/anotherhadi/spilltea/internal/plugins"
|
"github.com/anotherhadi/spilltea/internal/plugins"
|
||||||
proxyPkg "github.com/anotherhadi/spilltea/internal/proxy"
|
proxyPkg "github.com/anotherhadi/spilltea/internal/proxy"
|
||||||
|
copyUI "github.com/anotherhadi/spilltea/internal/ui/components/copy"
|
||||||
copyasUI "github.com/anotherhadi/spilltea/internal/ui/components/copyas"
|
copyasUI "github.com/anotherhadi/spilltea/internal/ui/components/copyas"
|
||||||
notificationsUI "github.com/anotherhadi/spilltea/internal/ui/components/notifications"
|
notificationsUI "github.com/anotherhadi/spilltea/internal/ui/components/notifications"
|
||||||
diffUI "github.com/anotherhadi/spilltea/internal/ui/diff"
|
diffUI "github.com/anotherhadi/spilltea/internal/ui/diff"
|
||||||
@@ -66,6 +67,7 @@ type Model struct {
|
|||||||
pluginsPage pluginsUI.Model
|
pluginsPage pluginsUI.Model
|
||||||
findingsPage findingsUI.Model
|
findingsPage findingsUI.Model
|
||||||
copyAs copyasUI.Model
|
copyAs copyasUI.Model
|
||||||
|
copy copyUI.Model
|
||||||
notifications notificationsUI.Model
|
notifications notificationsUI.Model
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +89,7 @@ func New(broker *intercept.Broker, name, path string) Model {
|
|||||||
pluginsPage: pluginsUI.New(mgr),
|
pluginsPage: pluginsUI.New(mgr),
|
||||||
findingsPage: findingsUI.New(),
|
findingsPage: findingsUI.New(),
|
||||||
copyAs: copyasUI.New(),
|
copyAs: copyasUI.New(),
|
||||||
|
copy: copyUI.New(),
|
||||||
notifications: notificationsUI.New(),
|
notifications: notificationsUI.New(),
|
||||||
sidebarState: sidebarState(cfg.TUI.DefaultSidebarState),
|
sidebarState: sidebarState(cfg.TUI.DefaultSidebarState),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/anotherhadi/spilltea/internal/keys"
|
"github.com/anotherhadi/spilltea/internal/keys"
|
||||||
"github.com/anotherhadi/spilltea/internal/plugins"
|
"github.com/anotherhadi/spilltea/internal/plugins"
|
||||||
proxyPkg "github.com/anotherhadi/spilltea/internal/proxy"
|
proxyPkg "github.com/anotherhadi/spilltea/internal/proxy"
|
||||||
|
copyUI "github.com/anotherhadi/spilltea/internal/ui/components/copy"
|
||||||
copyasUI "github.com/anotherhadi/spilltea/internal/ui/components/copyas"
|
copyasUI "github.com/anotherhadi/spilltea/internal/ui/components/copyas"
|
||||||
notificationsUI "github.com/anotherhadi/spilltea/internal/ui/components/notifications"
|
notificationsUI "github.com/anotherhadi/spilltea/internal/ui/components/notifications"
|
||||||
diffUI "github.com/anotherhadi/spilltea/internal/ui/diff"
|
diffUI "github.com/anotherhadi/spilltea/internal/ui/diff"
|
||||||
@@ -81,6 +82,19 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, cmd
|
return m, cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.copy.IsOpen() {
|
||||||
|
if ws, ok := msg.(tea.WindowSizeMsg); ok {
|
||||||
|
m.width = ws.Width
|
||||||
|
m.height = ws.Height
|
||||||
|
m.copy.SetSize(ws.Width, ws.Height)
|
||||||
|
m.resizeChildren()
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
var cmd tea.Cmd
|
||||||
|
m.copy, cmd = m.copy.Update(msg)
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.width = msg.Width
|
m.width = msg.Width
|
||||||
@@ -161,7 +175,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
|
|
||||||
if !m.activeIsEditing() {
|
if !m.activeIsEditing() {
|
||||||
switch {
|
switch {
|
||||||
case key.Matches(msg, keys.Keys.Global.CopyRequest):
|
case key.Matches(msg, keys.Keys.Global.CopyAs):
|
||||||
if m.page == pageDiff {
|
if m.page == pageDiff {
|
||||||
if raw := m.diff.CurrentRaw(); raw != "" {
|
if raw := m.diff.CurrentRaw(); raw != "" {
|
||||||
m.copyAs.SetSize(m.width, m.height)
|
m.copyAs.SetSize(m.width, m.height)
|
||||||
@@ -181,6 +195,28 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
|
|
||||||
|
case key.Matches(msg, keys.Keys.Global.Copy):
|
||||||
|
var raw, scheme string
|
||||||
|
switch m.page {
|
||||||
|
case pageIntercept:
|
||||||
|
raw = m.intercept.CurrentRaw()
|
||||||
|
scheme = m.intercept.CurrentScheme()
|
||||||
|
case pageDiff:
|
||||||
|
raw = m.diff.CurrentRaw()
|
||||||
|
scheme = "https"
|
||||||
|
case pageHistory:
|
||||||
|
raw = m.history.CurrentRaw()
|
||||||
|
scheme = m.history.CurrentScheme()
|
||||||
|
case pageReplay:
|
||||||
|
raw = m.replay.CurrentRaw()
|
||||||
|
scheme = m.replay.CurrentScheme()
|
||||||
|
}
|
||||||
|
if raw != "" {
|
||||||
|
m.copy.SetSize(m.width, m.height)
|
||||||
|
m.copy.Open(copyUI.OpenMsg{RawRequest: raw, Scheme: scheme})
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
|
||||||
case key.Matches(msg, keys.Keys.Global.ToggleSidebar):
|
case key.Matches(msg, keys.Keys.Global.ToggleSidebar):
|
||||||
m.cycleSidebarState()
|
m.cycleSidebarState()
|
||||||
m.resizeChildren()
|
m.resizeChildren()
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ func (m Model) View() tea.View {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.copy.IsOpen() {
|
||||||
|
v := tea.NewView(m.copy.View(normal))
|
||||||
|
v.AltScreen = true
|
||||||
|
v.MouseMode = tea.MouseModeCellMotion
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
rendered := normal
|
rendered := normal
|
||||||
if m.notifications.HasNotifications() {
|
if m.notifications.HasNotifications() {
|
||||||
rendered = m.notifications.View(normal)
|
rendered = m.notifications.View(normal)
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
package copy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"charm.land/bubbles/v2/list"
|
||||||
|
tea "charm.land/bubbletea/v2"
|
||||||
|
"charm.land/lipgloss/v2"
|
||||||
|
"github.com/anotherhadi/spilltea/internal/style"
|
||||||
|
)
|
||||||
|
|
||||||
|
const popupInnerW = 40
|
||||||
|
|
||||||
|
func writeClipboard(text string) {
|
||||||
|
encoded := base64.StdEncoding.EncodeToString([]byte(text))
|
||||||
|
fmt.Fprintf(os.Stderr, "\033]52;c;%s\a", encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenMsg struct {
|
||||||
|
RawRequest string
|
||||||
|
Scheme string
|
||||||
|
}
|
||||||
|
|
||||||
|
type copyItem struct {
|
||||||
|
id string
|
||||||
|
title string
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c copyItem) Title() string { return c.title }
|
||||||
|
func (c copyItem) Description() string { return c.desc }
|
||||||
|
func (c copyItem) FilterValue() string { return c.title }
|
||||||
|
|
||||||
|
var allItems = []list.Item{
|
||||||
|
copyItem{"raw", "Raw", "full HTTP request"},
|
||||||
|
copyItem{"headers", "Headers", "request headers only"},
|
||||||
|
copyItem{"body", "Body", "request body only"},
|
||||||
|
copyItem{"url", "URL", "request URL"},
|
||||||
|
}
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
open bool
|
||||||
|
list list.Model
|
||||||
|
rawRequest string
|
||||||
|
scheme string
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() Model {
|
||||||
|
s := style.S
|
||||||
|
|
||||||
|
delegate := list.NewDefaultDelegate()
|
||||||
|
delegate.SetSpacing(0)
|
||||||
|
delegate.Styles.NormalTitle = lipgloss.NewStyle().Foreground(s.Text).PaddingLeft(2)
|
||||||
|
delegate.Styles.NormalDesc = lipgloss.NewStyle().Foreground(s.Subtle).PaddingLeft(2)
|
||||||
|
delegate.Styles.SelectedTitle = lipgloss.NewStyle().
|
||||||
|
Border(lipgloss.NormalBorder(), false, false, false, true).
|
||||||
|
BorderForeground(s.Primary).
|
||||||
|
Foreground(s.Primary).Bold(true).PaddingLeft(1)
|
||||||
|
delegate.Styles.SelectedDesc = lipgloss.NewStyle().
|
||||||
|
Border(lipgloss.NormalBorder(), false, false, false, true).
|
||||||
|
BorderForeground(s.Primary).
|
||||||
|
Foreground(s.MutedFg).PaddingLeft(1)
|
||||||
|
|
||||||
|
l := list.New(allItems, delegate, popupInnerW, 8)
|
||||||
|
l.SetShowTitle(false)
|
||||||
|
l.SetShowStatusBar(false)
|
||||||
|
l.SetShowHelp(false)
|
||||||
|
l.SetFilteringEnabled(true)
|
||||||
|
l.KeyMap.Quit.SetEnabled(false)
|
||||||
|
l.KeyMap.ForceQuit.SetEnabled(false)
|
||||||
|
l.KeyMap.ShowFullHelp.SetEnabled(false)
|
||||||
|
l.KeyMap.CloseFullHelp.SetEnabled(false)
|
||||||
|
|
||||||
|
return Model{list: l}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) Init() tea.Cmd { return nil }
|
||||||
|
|
||||||
|
func (m Model) IsOpen() bool { return m.open }
|
||||||
|
|
||||||
|
func (m *Model) Open(msg OpenMsg) {
|
||||||
|
m.rawRequest = msg.RawRequest
|
||||||
|
m.scheme = msg.Scheme
|
||||||
|
m.open = true
|
||||||
|
m.list.ResetFilter()
|
||||||
|
m.list.Select(0)
|
||||||
|
m.list.SetSize(popupInnerW, m.listHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) SetSize(w, h int) {
|
||||||
|
m.width = w
|
||||||
|
m.height = h
|
||||||
|
m.list.SetSize(popupInnerW, m.listHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) popupHeight() int {
|
||||||
|
h := 12
|
||||||
|
if m.height > 0 && m.height-4 < h {
|
||||||
|
h = m.height - 4
|
||||||
|
}
|
||||||
|
if h < 6 {
|
||||||
|
h = 6
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) listHeight() int {
|
||||||
|
return style.PanelContentH(m.popupHeight()) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) extract(id string) string {
|
||||||
|
raw := m.rawRequest
|
||||||
|
lines := strings.Split(strings.ReplaceAll(raw, "\r\n", "\n"), "\n")
|
||||||
|
|
||||||
|
switch id {
|
||||||
|
case "raw":
|
||||||
|
return raw
|
||||||
|
|
||||||
|
case "headers":
|
||||||
|
var sb strings.Builder
|
||||||
|
for _, l := range lines[1:] {
|
||||||
|
if l == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sb.WriteString(l + "\n")
|
||||||
|
}
|
||||||
|
return strings.TrimRight(sb.String(), "\n")
|
||||||
|
|
||||||
|
case "body":
|
||||||
|
for i, l := range lines {
|
||||||
|
if l == "" && i > 0 {
|
||||||
|
return strings.TrimRight(strings.Join(lines[i+1:], "\n"), "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
|
||||||
|
case "url":
|
||||||
|
scheme := m.scheme
|
||||||
|
if scheme == "" {
|
||||||
|
scheme = "https"
|
||||||
|
}
|
||||||
|
var host, path string
|
||||||
|
if len(lines) > 0 {
|
||||||
|
parts := strings.SplitN(lines[0], " ", 3)
|
||||||
|
if len(parts) >= 2 {
|
||||||
|
path = parts[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, l := range lines[1:] {
|
||||||
|
if l == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if kv := strings.SplitN(l, ": ", 2); len(kv) == 2 && strings.EqualFold(kv[0], "host") {
|
||||||
|
host = strings.TrimSpace(kv[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scheme + "://" + host + path
|
||||||
|
}
|
||||||
|
return raw
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package copy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"charm.land/bubbles/v2/key"
|
||||||
|
tea "charm.land/bubbletea/v2"
|
||||||
|
"github.com/anotherhadi/spilltea/internal/keys"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
||||||
|
if kp, ok := msg.(tea.KeyPressMsg); ok {
|
||||||
|
switch {
|
||||||
|
case kp.String() == "enter":
|
||||||
|
if item, ok := m.list.SelectedItem().(copyItem); ok {
|
||||||
|
writeClipboard(m.extract(item.id))
|
||||||
|
}
|
||||||
|
m.open = false
|
||||||
|
return m, nil
|
||||||
|
case key.Matches(kp, keys.Keys.Global.Escape):
|
||||||
|
if m.list.SettingFilter() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
m.open = false
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd tea.Cmd
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package copy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"charm.land/lipgloss/v2"
|
||||||
|
"github.com/anotherhadi/spilltea/internal/style"
|
||||||
|
copyasUI "github.com/anotherhadi/spilltea/internal/ui/components/copyas"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m *Model) View(background string) string {
|
||||||
|
s := style.S
|
||||||
|
|
||||||
|
hint := lipgloss.NewStyle().Foreground(s.Subtle).
|
||||||
|
Render(" enter: copy • /: filter • esc: cancel")
|
||||||
|
|
||||||
|
inner := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
m.list.View(),
|
||||||
|
hint,
|
||||||
|
)
|
||||||
|
|
||||||
|
border := lipgloss.NewStyle().
|
||||||
|
Border(lipgloss.RoundedBorder()).
|
||||||
|
BorderForeground(s.Primary)
|
||||||
|
|
||||||
|
popupH := m.popupHeight()
|
||||||
|
popup := style.RenderWithTitle(border, "Copy", inner, popupInnerW+2, popupH)
|
||||||
|
|
||||||
|
return copyasUI.OverlayCenter(background, popup, m.width, m.height)
|
||||||
|
}
|
||||||
@@ -66,6 +66,8 @@ func (pr parsedRequest) fullURL() string {
|
|||||||
func formatAs(id, raw, scheme string) string {
|
func formatAs(id, raw, scheme string) string {
|
||||||
pr := parseRaw(raw, scheme)
|
pr := parseRaw(raw, scheme)
|
||||||
switch id {
|
switch id {
|
||||||
|
case "raw":
|
||||||
|
return raw
|
||||||
case "curl":
|
case "curl":
|
||||||
return toCurl(pr)
|
return toCurl(pr)
|
||||||
case "python":
|
case "python":
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func (f formatItem) Description() string { return f.desc }
|
|||||||
func (f formatItem) FilterValue() string { return f.title }
|
func (f formatItem) FilterValue() string { return f.title }
|
||||||
|
|
||||||
var allFormats = []list.Item{
|
var allFormats = []list.Item{
|
||||||
|
formatItem{"raw", "Raw", "raw HTTP request"},
|
||||||
formatItem{"curl", "cURL", "command line HTTP request"},
|
formatItem{"curl", "cURL", "command line HTTP request"},
|
||||||
formatItem{"python", "Python", "requests library"},
|
formatItem{"python", "Python", "requests library"},
|
||||||
formatItem{"go", "Go", "net/http package"},
|
formatItem{"go", "Go", "net/http package"},
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ func (m *Model) View(background string) string {
|
|||||||
popupH := m.popupHeight()
|
popupH := m.popupHeight()
|
||||||
popup := style.RenderWithTitle(border, "Copy as", inner, popupInnerW+2, popupH)
|
popup := style.RenderWithTitle(border, "Copy as", inner, popupInnerW+2, popupH)
|
||||||
|
|
||||||
return overlayCenter(background, popup, m.width, m.height)
|
return OverlayCenter(background, popup, m.width, m.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func overlayCenter(bg, popup string, w, h int) string {
|
func OverlayCenter(bg, popup string, w, h int) string {
|
||||||
s := style.S
|
s := style.S
|
||||||
|
|
||||||
stripped := ansi.Strip(bg)
|
stripped := ansi.Strip(bg)
|
||||||
|
|||||||
@@ -55,6 +55,15 @@ func (m Model) IsEditing() bool {
|
|||||||
return m.searchKind != searchKindOff && !m.searchAccepted
|
return m.searchKind != searchKindOff && !m.searchAccepted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Model) CurrentRaw() string {
|
||||||
|
if len(m.entries) == 0 || m.cursor >= len(m.entries) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return m.entries[m.cursor].RequestRaw
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) CurrentScheme() string { return "https" }
|
||||||
|
|
||||||
// RefreshCmd returns the appropriate load command given the current search state.
|
// RefreshCmd returns the appropriate load command given the current search state.
|
||||||
// The app model should call this instead of LoadEntriesCmd directly so that
|
// The app model should call this instead of LoadEntriesCmd directly so that
|
||||||
// background refreshes re-run the active search rather than resetting it.
|
// background refreshes re-run the active search rather than resetting it.
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (m *Model) renderDetailPanel(h int) string {
|
|||||||
}
|
}
|
||||||
info, ok := m.selected()
|
info, ok := m.selected()
|
||||||
if !ok {
|
if !ok {
|
||||||
return style.RenderWithTitle(panelStyle, "Detail", "", m.width, h)
|
return style.RenderWithTitle(panelStyle, icons.I.Detail+"Detail", "", m.width, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
statusSt := lipgloss.NewStyle().Foreground(s.Error)
|
statusSt := lipgloss.NewStyle().Foreground(s.Error)
|
||||||
@@ -84,7 +84,7 @@ func (m *Model) renderDetailPanel(h int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner := lipgloss.JoinVertical(lipgloss.Left, parts...)
|
inner := lipgloss.JoinVertical(lipgloss.Left, parts...)
|
||||||
return style.RenderWithTitle(panelStyle, "Detail", inner, m.width, h)
|
return style.RenderWithTitle(panelStyle, icons.I.Detail+"Detail", inner, m.width, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderPluginDescription(desc string, width int) string {
|
func renderPluginDescription(desc string, width int) string {
|
||||||
|
|||||||
@@ -68,6 +68,23 @@ func (m Model) Init() tea.Cmd { return nil }
|
|||||||
|
|
||||||
func (m Model) IsEditing() bool { return m.editing }
|
func (m Model) IsEditing() bool { return m.editing }
|
||||||
|
|
||||||
|
func (m Model) CurrentRaw() string {
|
||||||
|
if len(m.entries) == 0 || m.cursor >= len(m.entries) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return m.entries[m.cursor].RequestRaw
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) CurrentScheme() string {
|
||||||
|
if len(m.entries) == 0 || m.cursor >= len(m.entries) {
|
||||||
|
return "https"
|
||||||
|
}
|
||||||
|
if s := m.entries[m.cursor].Scheme; s != "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return "https"
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Model) SetDB(d *db.DB) {
|
func (m *Model) SetDB(d *db.DB) {
|
||||||
m.database = d
|
m.database = d
|
||||||
if d == nil {
|
if d == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user