Skip to content

Commit 26b80fb

Browse files
andriy-chernovandrinoff
authored andcommitted
fix: option in the settings, documentation
Signed-off-by: drew <me@andrinoff.com>
1 parent 2d9311e commit 26b80fb

19 files changed

Lines changed: 140 additions & 12 deletions

File tree

config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ type Config struct {
9191
HideTips bool `json:"hide_tips,omitempty"`
9292
DisableNotifications bool `json:"disable_notifications,omitempty"`
9393
EnableSplitPane bool `json:"enable_split_pane,omitempty"`
94+
EnableThreaded bool `json:"enable_threaded,omitempty"`
9495
Theme string `json:"theme,omitempty"`
9596
MailingLists []MailingList `json:"mailing_lists,omitempty"`
9697
DateFormat string `json:"date_format,omitempty"`

config/folder_cache.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,22 @@ func LoadFolderEmailHeaders(folderName string) ([]threading.EmailHeader, error)
204204
return headers, nil
205205
}
206206

207-
func IsFolderThreaded(folderName string) bool {
207+
// IsFolderThreaded returns the threading state for a folder. If the user has
208+
// explicitly toggled threading for this folder, that override is returned.
209+
// Otherwise defaultEnabled (from Config.EnableThreaded) is used.
210+
func IsFolderThreaded(folderName string, defaultEnabled bool) bool {
208211
cache, err := LoadFolderCache()
209212
if err != nil || cache.ThreadedFolders == nil {
210-
return false
213+
return defaultEnabled
211214
}
212-
return cache.ThreadedFolders[folderName]
215+
v, ok := cache.ThreadedFolders[folderName]
216+
if !ok {
217+
return defaultEnabled
218+
}
219+
return v
213220
}
214221

222+
// SetFolderThreaded stores an explicit per-folder threading override.
215223
func SetFolderThreaded(folderName string, threaded bool) error {
216224
cache, err := LoadFolderCache()
217225
if err != nil {
@@ -220,11 +228,7 @@ func SetFolderThreaded(folderName string, threaded bool) error {
220228
if cache.ThreadedFolders == nil {
221229
cache.ThreadedFolders = make(map[string]bool)
222230
}
223-
if threaded {
224-
cache.ThreadedFolders[folderName] = true
225-
} else {
226-
delete(cache.ThreadedFolders, folderName)
227-
}
231+
cache.ThreadedFolders[folderName] = threaded
228232
return SaveFolderCache(cache)
229233
}
230234

docs/docs/Features/Keybinds.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ Plain text, not encrypted. Edit with any text editor. Restart matcha to apply ch
2222
},
2323
"inbox": {
2424
"visual_mode": "v",
25+
"toggle_threaded": "T",
2526
"delete": "d",
2627
"archive": "a",
2728
"refresh": "r",
29+
"search": "/",
30+
"filter": "f",
2831
"open": "enter",
2932
"next_tab": "l",
3033
"prev_tab": "h"
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: Threaded View
3+
sidebar_position: 13
4+
---
5+
6+
# Threaded Conversation View
7+
8+
Matcha can group related emails into conversations using the JWZ threading
9+
algorithm (the same approach used by mutt and other classic mail clients).
10+
Replies, forwards, and quoted threads collapse under their root message so an
11+
inbox of 200 individual messages can render as 30 conversations.
12+
13+
## Enabling threaded view
14+
15+
There are three ways to control threading:
16+
17+
### 1. Settings menu (global default)
18+
19+
- Press `Esc` from the inbox to open the main menu.
20+
- Open **Settings****General**.
21+
- Toggle **Threaded Conversation View** to ON.
22+
23+
This sets the default for every folder. New folders without an explicit
24+
override inherit this default immediately.
25+
26+
### 2. Configuration file
27+
28+
Edit `~/.config/matcha/config.json` and add:
29+
30+
```json
31+
{
32+
"enable_threaded": true
33+
}
34+
```
35+
36+
### 3. Keybind (per-folder override)
37+
38+
Press `T` (configurable as `inbox.toggle_threaded` in `keybinds.json`) from any
39+
inbox view to toggle threading **for the current folder only**. The override is
40+
persisted in the folder cache and survives restarts.
41+
42+
A per-folder override always wins over the global default. To return a folder
43+
to the default, toggle it back to match the default value.
44+
45+
## Using threaded view
46+
47+
When threading is enabled the email list shows the root message of each
48+
conversation with a count of replies. The default state is collapsed.
49+
50+
| Key | Action |
51+
| -------- | --------------------------------------- |
52+
| `T` | Toggle threaded view for the folder |
53+
| `enter` | Open the focused message |
54+
| `space` | Expand or collapse the focused thread |
55+
| `j`/`k` | Navigate threads or messages within |
56+
57+
Visual mode (`v`), delete (`d`), archive (`a`), and the other inbox keybinds
58+
behave the same as in flat view — operations applied to a collapsed thread
59+
target the root message; expand the thread first to act on a single reply.
60+
61+
## How threading works
62+
63+
Matcha threads emails entirely on the client. Threading uses:
64+
65+
1. `Message-ID`, `In-Reply-To`, and `References` headers (RFC 5322).
66+
2. A subject-based fallback that strips `Re:`, `Fwd:`, and locale-specific
67+
prefixes when reply headers are missing.
68+
69+
Threading is recomputed whenever the email cache changes for a folder, so new
70+
mail slots into existing conversations without a manual refresh.
71+
72+
## Per-folder overrides
73+
74+
The setting is split into two layers:
75+
76+
- **Global default**`Config.EnableThreaded` in `config.json`.
77+
- **Per-folder override** — stored in `folder_cache.json` under
78+
`threaded_folders`. Only folders the user has explicitly toggled appear here.
79+
80+
If you change the global default in settings, every folder without an override
81+
flips to the new default on the next render. Folders with an override keep
82+
their explicit value until toggled again.

i18n/locales/ar.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
"hide_tips": "إخفاء النصائح السياقية",
152152
"disable_notifications": "تعطيل الإشعارات",
153153
"enable_split_pane": "عرض مقسم",
154+
"enable_threaded": "عرض المحادثات",
154155
"date_format": "تنسيق التاريخ",
155156
"language": "اللغة",
156157
"signature": "تعديل التوقيع",

i18n/locales/de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
"hide_tips": "Kontextuelle Tipps Ausblenden",
148148
"disable_notifications": "Benachrichtigungen Deaktivieren",
149149
"enable_split_pane": "Geteilte Ansicht",
150+
"enable_threaded": "Konversations-Threads",
150151
"date_format": "Datumsformat",
151152
"language": "Sprache",
152153
"signature": "Signatur Bearbeiten",

i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
"hide_tips": "Hide Contextual Tips",
148148
"disable_notifications": "Disable Notifications",
149149
"enable_split_pane": "Split Pane View",
150+
"enable_threaded": "Threaded Conversation View",
150151
"date_format": "Date Format",
151152
"language": "Language",
152153
"signature": "Edit Signature",

i18n/locales/es.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
"hide_tips": "Ocultar Consejos Contextuales",
148148
"disable_notifications": "Deshabilitar Notificaciones",
149149
"enable_split_pane": "Vista dividida",
150+
"enable_threaded": "Vista de conversación",
150151
"date_format": "Formato de Fecha",
151152
"language": "Idioma",
152153
"signature": "Editar Firma",

i18n/locales/fr.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
"hide_tips": "Masquer les Conseils Contextuels",
148148
"disable_notifications": "Désactiver les Notifications",
149149
"enable_split_pane": "Vue divisée",
150+
"enable_threaded": "Vue par conversation",
150151
"date_format": "Format de Date",
151152
"language": "Langue",
152153
"signature": "Modifier la Signature",

i18n/locales/ja.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@
145145
"hide_tips": "コンテキストヒントを非表示",
146146
"disable_notifications": "通知を無効化",
147147
"enable_split_pane": "分割ビュー",
148+
"enable_threaded": "スレッド表示",
148149
"date_format": "日付形式",
149150
"language": "言語",
150151
"signature": "署名を編集",

0 commit comments

Comments
 (0)