mirror of
https://github.com/anotherhadi/spilltea.git
synced 2026-05-20 01:32:33 +02:00
CopyRequest -> Copy & CopyAs
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user