Add F keybinding to flush the mail queue via postqueue -f
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9c0ca254f5
commit
9ba845e5f4
3 changed files with 34 additions and 2 deletions
|
|
@ -48,6 +48,7 @@ go install github.com/nemunaire/mqv@latest
|
||||||
| `↑` / `↓` | Navigate messages |
|
| `↑` / `↓` | Navigate messages |
|
||||||
| `Enter` | Open message |
|
| `Enter` | Open message |
|
||||||
| `r` | Refresh queue |
|
| `r` | Refresh queue |
|
||||||
|
| `F` | Flush queue (`postqueue -f`) |
|
||||||
| `q` | Quit |
|
| `q` | Quit |
|
||||||
|
|
||||||
Subjects are fetched lazily in parallel via `postcat` as the list loads; a progress bar tracks completion.
|
Subjects are fetched lazily in parallel via `postcat` as the list loads; a progress bar tracks completion.
|
||||||
|
|
@ -59,6 +60,7 @@ Subjects are fetched lazily in parallel via `postcat` as the list loads; a progr
|
||||||
| `↑↓` / `Space` / `PgUp` / `PgDn` | Scroll |
|
| `↑↓` / `Space` / `PgUp` / `PgDn` | Scroll |
|
||||||
| `H` | Toggle full headers / short headers |
|
| `H` | Toggle full headers / short headers |
|
||||||
| `s` | Save raw EML to `~/QUEUEID.eml` |
|
| `s` | Save raw EML to `~/QUEUEID.eml` |
|
||||||
|
| `F` | Requeue message (`postsuper -r`) |
|
||||||
| `v` | Browse MIME parts |
|
| `v` | Browse MIME parts |
|
||||||
| `q` | Back to queue list |
|
| `q` | Back to queue list |
|
||||||
|
|
||||||
|
|
|
||||||
14
model.go
14
model.go
|
|
@ -210,6 +210,14 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
m.list.SetItems(nil)
|
m.list.SetItems(nil)
|
||||||
_ = m.progress.SetPercent(0)
|
_ = m.progress.SetPercent(0)
|
||||||
return m, loadQueueCmd()
|
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":
|
case "enter":
|
||||||
if item, ok := m.list.SelectedItem().(queueItem); ok {
|
if item, ok := m.list.SelectedItem().(queueItem); ok {
|
||||||
return m, loadMessageCmd(item.entry.ID)
|
return m, loadMessageCmd(item.entry.ID)
|
||||||
|
|
@ -254,6 +262,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
m.refreshViewport()
|
m.refreshViewport()
|
||||||
m.viewport.GotoTop()
|
m.viewport.GotoTop()
|
||||||
return m, nil
|
return m, nil
|
||||||
|
case "F":
|
||||||
|
return m, requeueMessageCmd(m.currentID)
|
||||||
case "v":
|
case "v":
|
||||||
m.parts = extractParts(m.currentRaw)
|
m.parts = extractParts(m.currentRaw)
|
||||||
m.partsCursor = 0
|
m.partsCursor = 0
|
||||||
|
|
@ -384,7 +394,7 @@ func (m Model) View() string {
|
||||||
headersHint = "H: short headers"
|
headersHint = "H: short headers"
|
||||||
}
|
}
|
||||||
status := statusBarStyle.Render(
|
status := statusBarStyle.Render(
|
||||||
fmt.Sprintf(" ↑↓/SPC/PgUp/Dn: scroll │ s: save EML │ v: parts │ %s │ q: back │ %d%% ", headersHint, scrollPct),
|
fmt.Sprintf(" ↑↓/SPC/PgUp/Dn: scroll │ s: save EML │ F: requeue │ v: parts │ %s │ q: back │ %d%% ", headersHint, scrollPct),
|
||||||
)
|
)
|
||||||
notice := ""
|
notice := ""
|
||||||
if m.messageSaving {
|
if m.messageSaving {
|
||||||
|
|
@ -464,7 +474,7 @@ func (m Model) renderBottom() string {
|
||||||
return dimStyle.Render(label) + "\n " + m.progress.View()
|
return dimStyle.Render(label) + "\n " + m.progress.View()
|
||||||
}
|
}
|
||||||
status := statusBarStyle.Render(
|
status := statusBarStyle.Render(
|
||||||
fmt.Sprintf(" %d message(s) │ Enter: open │ r: refresh │ q: quit ", len(m.list.Items())),
|
fmt.Sprintf(" %d message(s) │ Enter: open │ r: refresh │ F: flush │ q: quit ", len(m.list.Items())),
|
||||||
)
|
)
|
||||||
if item, ok := m.list.SelectedItem().(queueItem); ok {
|
if item, ok := m.list.SelectedItem().(queueItem); ok {
|
||||||
if reason := item.entry.Reason; reason != "" {
|
if reason := item.entry.Reason; reason != "" {
|
||||||
|
|
|
||||||
20
msgs.go
20
msgs.go
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -34,6 +36,24 @@ 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 requeueMessageCmd(id string) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
exec.Command("postsuper", "-r", id).Run()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func fetchSubjectCmd(id string) tea.Cmd {
|
func fetchSubjectCmd(id string) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
raw, err := fetchHeaders(id)
|
raw, err := fetchHeaders(id)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue