Add flags to history

Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
This commit is contained in:
Hadi
2026-05-19 14:48:15 +02:00
parent 6f56e0b26a
commit 28b070dafc
9 changed files with 46 additions and 8 deletions
+1
View File
@@ -82,6 +82,7 @@ keybindings:
delete_all: "X"
sql_query: ":"
filter: "/"
flag: "m"
home:
open: "enter,l"
+1
View File
@@ -39,6 +39,7 @@ type HistoryKeys struct {
DeleteAll string `mapstructure:"delete_all"`
Filter string `mapstructure:"filter"`
SqlQuery string `mapstructure:"sql_query"`
Flag string `mapstructure:"flag"`
}
type HomeKeys struct {
+2 -1
View File
@@ -40,7 +40,8 @@ func (d *DB) migrate() error {
status_code INTEGER NOT NULL,
request_raw TEXT NOT NULL,
response_raw TEXT NOT NULL,
body_hash TEXT NOT NULL DEFAULT ''
body_hash TEXT NOT NULL DEFAULT '',
flagged INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS replay_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
+12 -4
View File
@@ -17,6 +17,7 @@ type Entry struct {
StatusCode int
RequestRaw string
ResponseRaw string
Flagged bool
}
func bodyHash(body string) string {
@@ -71,10 +72,12 @@ func scanEntries(rows *sql.Rows) ([]Entry, error) {
for rows.Next() {
var e Entry
var ts string
if err := rows.Scan(&e.ID, &ts, &e.Method, &e.Host, &e.Path, &e.StatusCode, &e.RequestRaw, &e.ResponseRaw); err != nil {
var flagged int
if err := rows.Scan(&e.ID, &ts, &e.Method, &e.Host, &e.Path, &e.StatusCode, &e.RequestRaw, &e.ResponseRaw, &flagged); err != nil {
return nil, err
}
e.Timestamp, _ = time.Parse(time.RFC3339, ts)
e.Flagged = flagged != 0
entries = append(entries, e)
}
return entries, rows.Err()
@@ -82,7 +85,7 @@ func scanEntries(rows *sql.Rows) ([]Entry, error) {
func (d *DB) ListEntries() ([]Entry, error) {
rows, err := d.conn.Query(
`SELECT id, timestamp, method, host, path, status_code, request_raw, response_raw
`SELECT id, timestamp, method, host, path, status_code, request_raw, response_raw, flagged
FROM entries ORDER BY id DESC`,
)
if err != nil {
@@ -95,7 +98,7 @@ func (d *DB) ListEntries() ([]Entry, error) {
func (d *DB) SearchEntries(term string) ([]Entry, error) {
like := "%" + term + "%"
rows, err := d.conn.Query(
`SELECT id, timestamp, method, host, path, status_code, request_raw, response_raw
`SELECT id, timestamp, method, host, path, status_code, request_raw, response_raw, flagged
FROM entries
WHERE method LIKE ? OR host LIKE ? OR path LIKE ? OR request_raw LIKE ? OR response_raw LIKE ?
ORDER BY id DESC`,
@@ -121,7 +124,7 @@ func (d *DB) QueryEntries(where string) ([]Entry, error) {
if _, err := roConn.Exec("PRAGMA query_only=ON"); err != nil {
return nil, err
}
q := "SELECT id, timestamp, method, host, path, status_code, request_raw, response_raw FROM entries WHERE " + strings.TrimSpace(where)
q := "SELECT id, timestamp, method, host, path, status_code, request_raw, response_raw, flagged FROM entries WHERE " + strings.TrimSpace(where)
rows, err := roConn.Query(q)
if err != nil {
return nil, err
@@ -130,6 +133,11 @@ func (d *DB) QueryEntries(where string) ([]Entry, error) {
return scanEntries(rows)
}
func (d *DB) ToggleFlag(id int64) error {
_, err := d.conn.Exec(`UPDATE entries SET flagged = NOT flagged WHERE id = ?`, id)
return err
}
func (d *DB) DeleteEntry(id int64) error {
_, err := d.conn.Exec(`DELETE FROM entries WHERE id = ?`, id)
return err
+2
View File
@@ -20,6 +20,7 @@ type Icons struct {
New string
Temp string
Project string
Flag string
}
var I *Icons
@@ -44,6 +45,7 @@ func Init(cfg *config.Config) {
New: "󰐕 ",
Temp: "󰙨 ",
Project: "󰉋 ",
Flag: "󰈻 ",
}
} else {
I = &Icons{}
+3 -1
View File
@@ -10,6 +10,7 @@ type HistoryKeyMap struct {
DeleteAll key.Binding
Filter key.Binding
SqlQuery key.Binding
Flag key.Binding
}
func newHistoryKeyMap(cfg config.HistoryKeys) HistoryKeyMap {
@@ -18,9 +19,10 @@ func newHistoryKeyMap(cfg config.HistoryKeys) HistoryKeyMap {
DeleteAll: binding(cfg.DeleteAll, "delete all"),
Filter: binding(cfg.Filter, "filter"),
SqlQuery: binding(cfg.SqlQuery, "sql query"),
Flag: binding(cfg.Flag, "flag"),
}
}
func (h HistoryKeyMap) Bindings() []key.Binding {
return []key.Binding{h.DeleteEntry, h.DeleteAll}
return []key.Binding{h.DeleteEntry, h.DeleteAll, h.Flag}
}
+1 -1
View File
@@ -159,7 +159,7 @@ func (m historyKeyMap) FullHelp() [][]key.Binding {
h := keys.Keys.History
g := keys.Keys.Global
pageGlobals := []key.Binding{g.Up, g.Down, g.CycleFocus, g.ScrollUp, g.ScrollDown, g.Left, g.Right, g.Escape, g.SendToReplay, g.SendToDiff, g.Copy, g.CopyAs}
all := []key.Binding{h.DeleteEntry, h.DeleteAll, h.Filter, h.SqlQuery}
all := []key.Binding{h.Flag, h.DeleteEntry, h.DeleteAll, h.Filter, h.SqlQuery}
all = append(all, pageGlobals...)
all = append(all, g.CommonBindings()...)
return keys.ChunkByWidth(all, m.width)
+6
View File
@@ -230,6 +230,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
}
case key.Matches(msg, h.Flag):
if len(m.entries) > 0 && m.database != nil {
m.database.ToggleFlag(m.entries[m.cursor].ID)
return m, m.RefreshCmd()
}
case key.Matches(msg, h.DeleteEntry):
if len(m.entries) > 0 {
id := m.entries[m.cursor].ID
+18 -1
View File
@@ -113,7 +113,7 @@ func (m *Model) renderList() string {
w := m.listViewport.Width()
statusStr := fmt.Sprintf("%3d", e.StatusCode)
const fixedW = 2 + 7 + 1 + 3 + 1 + 10 + 1
const fixedW = 2 + 2 + 7 + 1 + 3 + 1 + 10 + 1
hostPathW := w - fixedW
if hostPathW < 0 {
hostPathW = 0
@@ -121,12 +121,21 @@ func (m *Model) renderList() string {
ts := e.Timestamp.Format("15:04:05")
statusSt := style.StatusStyle(e.StatusCode, 3)
flagSt := lipgloss.NewStyle().Foreground(s.Primary)
var line string
if selected {
bg := lipgloss.NewStyle().Background(selBg)
flagStr := " "
if e.Flagged {
flagStr = icons.I.Flag + " "
if icons.I.Flag == "" {
flagStr = "★ "
}
}
line = lipgloss.JoinHorizontal(lipgloss.Top,
bg.Bold(true).Foreground(s.Primary).Width(2).Render(">"),
bg.Foreground(s.Primary).Width(2).Render(flagStr),
s.Method(e.Method).Background(selBg).Render(e.Method),
bg.Width(1).Render(""),
statusSt.Background(selBg).Render(statusStr),
@@ -136,8 +145,16 @@ func (m *Model) renderList() string {
bg.Bold(true).Width(hostPathW).Render(e.Host+e.Path),
)
} else {
flagStr := " "
if e.Flagged {
flagStr = icons.I.Flag + " "
if icons.I.Flag == "" {
flagStr = "★ "
}
}
line = lipgloss.JoinHorizontal(lipgloss.Top,
" ",
flagSt.Width(2).Render(flagStr),
s.Method(e.Method).Render(e.Method),
" ",
statusSt.Render(statusStr),