···33# 2026-04-13
44- **Emoji reactions (`ctrl+e`)** — fast, keyboard-driven emoji reactions from inbox or reader; press `ctrl+e` to open emoji picker overlay, select with `1`-`8` for instant send or navigate with `j`/`k` and press `enter`; sends minimal reaction email (emoji + italic footer + quoted original message) with proper threading headers; available reactions: 👍 ❤️ 😂 🎉 🙏 💯 👀 ✅; original email marked with `\Answered` flag; reaction saved to Sent folder; auto-selects From address matching recipient (same logic as regular replies)
55- **Email threading headers** — all replies (regular `r`/`R` and emoji reactions `ctrl+e`) now include proper `In-Reply-To` and `References` headers for conversation threading; ensures replies appear correctly grouped in Gmail, Outlook, and Apple Mail conversation views; `References` header extracted from IMAP message body and preserved in reply chain
66+- **Fix: refresh not showing new emails immediately** — pressing `R` now correctly displays new emails on first refresh; previously the IMAP client cached the selected mailbox state, so the first `R` would skip re-SELECT and use stale UID SEARCH results (showing the old unread count but no new messages in the list); required a second `R` or tab switch to see new emails; now forces a fresh SELECT to ensure mailbox state is current
677889# 2026-04-10
+9
internal/imap/client.go
···196196 }
197197}
198198199199+// ResetMailboxSelection clears the cached selected mailbox, forcing the next
200200+// FetchHeaders or similar operation to re-SELECT the mailbox and fetch fresh state.
201201+// This is useful when refreshing to ensure new messages are visible.
202202+func (c *Client) ResetMailboxSelection() {
203203+ c.mu.Lock()
204204+ defer c.mu.Unlock()
205205+ c.selectedMailbox = ""
206206+}
207207+199208// TokenSource returns the OAuth2 token source for this client, or nil for
200209// password-authenticated accounts.
201210func (c *Client) TokenSource() func() (string, error) { return c.cfg.TokenSource }
+2
internal/ui/model.go
···24242424 return m, nil
2425242524262426 case "R":
24272427+ m.imapCli().ResetMailboxSelection() // force fresh SELECT to see new messages
24272428 m.loading = true
24282429 return m, tea.Batch(m.spinner.Tick, m.fetchFolderCmd(m.activeFolder()))
24292430···27902791 return m.launchReplyCmd()
27912792 }
27922793 case "R":
27942794+ m.imapCli().ResetMailboxSelection() // force fresh SELECT to see new messages
27932795 m.loading = true
27942796 return m, tea.Batch(m.spinner.Tick, m.fetchFolderCmd(m.activeFolder()))
27952797 case "ctrl+r":