Compare commits

..

No commits in common. "17525622793c981e4dcb41188d834ab178855dcb" and "70b0eedb9cb077035223ef3b0c043b0da4a7730a" have entirely different histories.

4 changed files with 6 additions and 73 deletions

View file

@ -48,7 +48,6 @@ go install github.com/nemunaire/mqv@latest
| `↑` / `↓` | Navigate messages |
| `Enter` | Open message |
| `r` | Refresh queue |
| `F` | Flush queue (`postqueue -f`) |
| `q` | Quit |
Subjects are fetched lazily in parallel via `postcat` as the list loads; a progress bar tracks completion.
@ -60,8 +59,6 @@ Subjects are fetched lazily in parallel via `postcat` as the list loads; a progr
| `↑↓` / `Space` / `PgUp` / `PgDn` | Scroll |
| `H` | Toggle full headers / short headers |
| `s` | Save raw EML to `~/QUEUEID.eml` |
| `D` | Delete message (`postsuper -d`) |
| `F` | Requeue message (`postsuper -r`) |
| `v` | Browse MIME parts |
| `q` | Back to queue list |

View file

@ -10,7 +10,6 @@ import (
"github.com/charmbracelet/bubbles/textinput"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/x/ansi"
)
@ -43,7 +42,7 @@ type Model struct {
saveNotice string
width int
height int
messageSaving bool
messageSaving bool
// stateParts fields
parts []MessagePart
partsCursor int
@ -210,14 +209,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.list.SetItems(nil)
_ = m.progress.SetPercent(0)
return m, loadQueueCmd()
case "F":
m.entries = nil
m.entryIndex = nil
m.loadingTotal = 0
m.loadingDone = 0
m.list.SetItems(nil)
_ = m.progress.SetPercent(0)
return m, flushQueueCmd()
case "enter":
if item, ok := m.list.SelectedItem().(queueItem); ok {
return m, loadMessageCmd(item.entry.ID)
@ -262,13 +253,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.refreshViewport()
m.viewport.GotoTop()
return m, nil
case "D":
id := m.currentID
m.state = stateList
m.saveNotice = ""
return m, deleteMessageCmd(id)
case "F":
return m, requeueMessageCmd(m.currentID)
case "v":
m.parts = extractParts(m.currentRaw)
m.partsCursor = 0
@ -382,24 +366,14 @@ func (m Model) View() string {
return m.list.View() + "\n" + m.renderBottom()
case stateMessage:
title := titleStyle.Render(fmt.Sprintf("Message: %s", m.currentID))
header := title
if idx, ok := m.entryIndex[m.currentID]; ok {
if reason := m.entries[idx].Reason; reason != "" {
gap := m.width - lipgloss.Width(title) - lipgloss.Width(reason) - 2
if gap < 1 {
gap = 1
}
header = title + strings.Repeat(" ", gap) + reasonStyle.Render(reason)
}
}
header := titleStyle.Render(fmt.Sprintf("Message: %s", m.currentID))
scrollPct := int(m.viewport.ScrollPercent() * 100)
headersHint := "H: full headers"
if m.showFullHeaders {
headersHint = "H: short headers"
}
status := statusBarStyle.Render(
fmt.Sprintf(" ↑↓/SPC/PgUp/Dn: scroll │ s: save EML │ D: delete │ F: requeue │ v: parts │ %s │ q: back │ %d%% ", headersHint, scrollPct),
fmt.Sprintf(" ↑↓/SPC/PgUp/Dn: scroll │ s: save EML │ v: parts │ %s │ q: back │ %d%% ", headersHint, scrollPct),
)
notice := ""
if m.messageSaving {
@ -478,17 +452,7 @@ func (m Model) renderBottom() string {
label := fmt.Sprintf(" Fetching subjects: %d / %d ", m.loadingDone, m.loadingTotal)
return dimStyle.Render(label) + "\n " + m.progress.View()
}
left := fmt.Sprintf(" %d message(s) │ Enter: open │ r: refresh │ F: flush │ q: quit ", len(m.list.Items()))
reason := ""
if item, ok := m.list.SelectedItem().(queueItem); ok {
reason = item.entry.Reason
}
if reason == "" {
return statusBarStyle.Render(left)
}
right := " " + reason + " "
rightWidth := lipgloss.Width(right)
leftPart := statusBarStyle.Width(m.width - rightWidth).Render(left)
rightPart := lipgloss.NewStyle().Foreground(lipgloss.Color("196")).Background(lipgloss.Color("241")).Render(right)
return leftPart + rightPart
return statusBarStyle.Render(
fmt.Sprintf(" %d message(s) │ Enter: open │ r: refresh │ q: quit ", len(m.list.Items())),
)
}

27
msgs.go
View file

@ -1,8 +1,6 @@
package main
import (
"os/exec"
tea "github.com/charmbracelet/bubbletea"
)
@ -36,31 +34,6 @@ func loadQueueCmd() tea.Cmd {
}
}
func flushQueueCmd() tea.Cmd {
return func() tea.Msg {
exec.Command("postqueue", "-f").Run()
entries, err := loadQueue()
if err != nil {
return queueErrMsg{err}
}
return queueParsedMsg{entries}
}
}
func deleteMessageCmd(id string) tea.Cmd {
return func() tea.Msg {
exec.Command("postsuper", "-d", id).Run()
return nil
}
}
func requeueMessageCmd(id string) tea.Cmd {
return func() tea.Msg {
exec.Command("postsuper", "-r", id).Run()
return nil
}
}
func fetchSubjectCmd(id string) tea.Cmd {
return func() tea.Msg {
raw, err := fetchHeaders(id)

View file

@ -12,5 +12,4 @@ var (
partSepStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
attachStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("214"))
headerKeyStyle = lipgloss.NewStyle().Bold(true)
reasonStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("196"))
)