Skip to content

feat(tui): add unread-only filter - #1743

Open
christos-chatzifountas-biotz-io wants to merge 11 commits into
floatpane:masterfrom
christos-chatzifountas-biotz-io:feature/unread-only-1530
Open

christos-chatzifountas-biotz-io wants to merge 11 commits into
floatpane:masterfrom
christos-chatzifountas-biotz-io:feature/unread-only-1530

Conversation

@christos-chatzifountas-biotz-io

@christos-chatzifountas-biotz-io christos-chatzifountas-biotz-io commented Oct 17, 2026 •

Copy link
Copy Markdown

What?

  • Add U and a command-palette action to toggle an unread-only view in the inbox and folders. The filter follows the active account tab and can be remapped with inbox.toggle_unread_only.
  • Load subsequent pages when read messages leave too few visible rows, including in folder views and the ALL account tab.
  • Add pagination_page_size to config. It accepts a numeric cap such as 40, "height", or a fraction such as "0.5*height". The default is 40. The same size controls the first folder fetch and later pages, and the visible pager uses the available inbox pane rows up to the configured cap.
  • Keep folder sidebar names and unread counts on one row, and align mouse clicks with the visible sidebar title. Add a regression test for clicks on lower folders with long names and unread counts.
  • Update keybinding and configuration documentation, with tests for account filtering, read state, folder pagination, config persistence, page size modes, and first-page limits.

Why?

Scrolling past read messages to find unread mail is slow, and filtering only the initially loaded page could hide unread messages later in a folder. The inbox pager previously used half the pane height regardless of the fetch size, and the first folder fetch requested every message. The page size setting now controls the visible and fetched page size. Folder unread counts could wrap to another row while mouse clicks still assumed one row per folder, causing the selected folder to drift farther above the cursor down the sidebar.

Fixes #1530.

Verification

  • make lint
  • go test ./config ./tui ./app ./internal/fetchcmd -timeout 90s
  • go test ./... -skip '^(TestConn_SendEvent|TestFetchEmails|TestFetchEmailsWithCustomServer)$' -timeout 90s

The three skipped existing tests require a live mail setup or hang in this environment; they are unchanged by this PR.

AI-assisted implementation, reviewed and tested locally.

@floatpanebot floatpanebot added area/tui Terminal UI / view layer area/config Configuration / settings area/docs Docs site / README bug Something isn't working documentation Documentation changes enhancement New feature or request size/L Diff: 201–800 lines labels Oct 17, 2026
@floatpanebot

floatpanebot commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Benchmark report — no significant change

Metrics worse: 0 · better: 0 (threshold: ±3%).

benchstat output
goos: linux
goarch: amd64
pkg: github.com/floatpane/matcha/backend
cpu: AMD EPYC 7763 64-Core Processor                
                           │   old.txt    │               new.txt               │
                           │    sec/op    │    sec/op      vs base              │
ParseSearchQuery_Simple-4    2.905µ ± 29%   2.844µ ± 345%       ~ (p=0.699 n=6)
ParseSearchQuery_Complex-4   8.257µ ± 34%   8.446µ ±  87%       ~ (p=0.485 n=6)
TokenizeSearchQuery-4        4.679µ ± 27%   3.683µ ±  27%       ~ (p=0.132 n=6)
geomean                      4.823µ         4.456µ         -7.62%

                           │  old.txt   │              new.txt               │
                           │    B/op    │    B/op     vs base                │
ParseSearchQuery_Simple-4    26.00 ± 0%   26.00 ± 0%       ~ (p=1.000 n=6) ¹
ParseSearchQuery_Complex-4   762.0 ± 0%   762.0 ± 0%       ~ (p=1.000 n=6) ¹
TokenizeSearchQuery-4        176.0 ± 0%   176.0 ± 0%       ~ (p=1.000 n=6) ¹
geomean                      151.6        151.6       +0.00%
¹ all samples are equal

                           │  old.txt   │              new.txt               │
                           │ allocs/op  │ allocs/op   vs base                │
ParseSearchQuery_Simple-4    2.000 ± 0%   2.000 ± 0%       ~ (p=1.000 n=6) ¹
ParseSearchQuery_Complex-4   23.00 ± 0%   23.00 ± 0%       ~ (p=1.000 n=6) ¹
TokenizeSearchQuery-4        9.000 ± 0%   9.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                      7.453        7.453       +0.00%
¹ all samples are equal

pkg: github.com/floatpane/matcha/tui
                    │   old.txt    │               new.txt               │
                    │    sec/op    │    sec/op      vs base              │
LogPanelView-4        156.1µ ± 10%    156.0µ ±  6%       ~ (p=0.937 n=6)
SearchOverlayView-4   175.6µ ±  3%    180.4µ ±  8%       ~ (p=0.180 n=6)
InboxConstruction-4   963.4µ ± 13%   1073.1µ ± 25%       ~ (p=0.180 n=6)
geomean               297.8µ          311.4µ        +4.59%

                    │   old.txt    │                new.txt                │
                    │     B/op     │     B/op       vs base                │
LogPanelView-4        44.67Ki ± 0%   44.67Ki ±  0%       ~ (p=1.000 n=6) ¹
SearchOverlayView-4   56.15Ki ± 0%   56.15Ki ± 41%       ~ (p=0.253 n=6)
InboxConstruction-4   874.5Ki ± 0%   874.6Ki ±  0%       ~ (p=0.331 n=6)
geomean               129.9Ki        129.9Ki        -0.00%
¹ all samples are equal

                    │   old.txt   │               new.txt               │
                    │  allocs/op  │  allocs/op   vs base                │
LogPanelView-4         714.0 ± 0%    714.0 ± 0%       ~ (p=1.000 n=6) ¹
SearchOverlayView-4    926.0 ± 0%    926.0 ± 0%       ~ (p=0.273 n=6)
InboxConstruction-4   3.483k ± 0%   3.483k ± 0%       ~ (p=0.680 n=6)
geomean               1.321k        1.321k       +0.00%
¹ all samples are equal

auto-generated by benchmarks.yml

@floatpanebot floatpanebot added the size/XL Diff: 800+ lines label Oct 17, 2026
@floatpanebot

Copy link
Copy Markdown
Member

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@floatpanebot

Copy link
Copy Markdown
Member

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@floatpanebot

Copy link
Copy Markdown
Member

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Configuration / settings area/docs Docs site / README area/tui Terminal UI / view layer bug Something isn't working documentation Documentation changes enhancement New feature or request size/L Diff: 201–800 lines size/XL Diff: 800+ lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FEAT: Toggle to show unread-only in folder

2 participants