1package tui
2
3import (
4 "github.com/floatpane/matcha/backend"
5 "github.com/floatpane/matcha/calendar"
6 "github.com/floatpane/matcha/config"
7 "github.com/floatpane/matcha/daemonrpc"
8 "github.com/floatpane/matcha/fetcher"
9)
10
11type MailboxKind string
12
13const (
14 MailboxInbox MailboxKind = "inbox"
15 MailboxSent MailboxKind = "sent"
16 MailboxTrash MailboxKind = "trash"
17 MailboxArchive MailboxKind = "archive"
18)
19
20type ViewEmailMsg struct {
21 Index int
22 UID uint32
23 AccountID string
24 Mailbox MailboxKind
25 Email *fetcher.Email
26}
27
28type SendEmailMsg struct {
29 To string
30 Cc string // Cc recipient(s)
31 Bcc string // Bcc recipient(s)
32 Subject string
33 Body string
34 AttachmentPaths []string
35 InReplyTo string
36 References []string
37 AccountID string // ID of the account to send from
38 FromOverride string // Custom From address (used when account is catch-all)
39 QuotedText string // Hidden quoted text appended when sending
40 Signature string // Signature to append to email body
41 SignSMIME bool // Whether to sign the email using S/MIME
42 EncryptSMIME bool // Whether to encrypt the email using S/MIME
43 SignPGP bool // Whether to sign the email using PGP
44}
45
46type Credentials struct {
47 Provider string
48 Name string
49 Host string // Host (this was the previous "Email Address" field in the UI)
50 FetchEmail string // Single email address to fetch messages for. If empty, code should default this to Host when creating the account.
51 SendAsEmail string // Optional From header email. If empty, sending falls back to FetchEmail, then Host.
52 CatchAll bool // Show all inbox messages regardless of To address.
53 Password string
54 IMAPServer string
55 IMAPPort int
56 SMTPServer string
57 SMTPPort int
58 Insecure bool
59 AuthMethod string // "password" or "oauth2"
60 Protocol string // "imap" (default), "jmap", or "pop3"
61 JMAPEndpoint string // JMAP session URL
62 POP3Server string // POP3 server hostname
63 POP3Port int // POP3 server port
64 MaildirPath string // Local Maildir root
65}
66
67// StartOAuth2Msg is sent when the user requests OAuth2 authorization for a Gmail account.
68type StartOAuth2Msg struct {
69 Email string
70}
71
72// OAuth2CompleteMsg is sent when OAuth2 authorization completes.
73type OAuth2CompleteMsg struct {
74 Email string
75 Err error
76}
77
78type ChooseServiceMsg struct {
79 Service string
80}
81
82type EmailResultMsg struct {
83 Err error
84}
85
86type ClearStatusMsg struct{}
87
88type EmailsFetchedMsg struct {
89 Emails []fetcher.Email
90 AccountID string
91 Mailbox MailboxKind
92}
93
94type UpdatePreviewMsg struct {
95 UID uint32
96 AccountID string
97}
98
99type PreviewBodyFetchedMsg struct {
100 UID uint32
101 AccountID string
102 Body string
103 BodyMIMEType string
104 Attachments []fetcher.Attachment
105 Err error
106}
107
108type FetchErr error
109
110type SearchRequestedMsg struct {
111 Query backend.SearchQuery
112 Mailbox MailboxKind
113 FolderName string
114 AccountID string
115}
116
117type SearchResultsMsg struct {
118 Query backend.SearchQuery
119 Emails []fetcher.Email
120 Err error
121}
122
123type ApplySearchResultsMsg struct {
124 Query backend.SearchQuery
125 Emails []fetcher.Email
126}
127
128type GoToInboxMsg struct{}
129
130type GoToSentInboxMsg struct{}
131
132type GoToSendMsg struct {
133 To string
134 Subject string
135 Body string
136}
137
138type GoToSettingsMsg struct{}
139
140type GoToTrashArchiveMsg struct{}
141
142type GoToSignatureEditorMsg struct {
143 AccountID string
144}
145
146type FetchMoreEmailsMsg struct {
147 Offset uint32
148 AccountID string
149 Mailbox MailboxKind
150 Limit uint32
151}
152
153type FetchingMoreEmailsMsg struct{}
154
155type EmailsAppendedMsg struct {
156 Emails []fetcher.Email
157 AccountID string
158 Mailbox MailboxKind
159}
160
161type ReplyToEmailMsg struct {
162 Email fetcher.Email
163}
164
165type ForwardEmailMsg struct {
166 Email fetcher.Email
167}
168
169type SetComposerCursorToStartMsg struct{}
170
171type GoToFilePickerMsg struct{}
172
173type FileSelectedMsg struct {
174 Paths []string
175}
176
177type CancelFilePickerMsg struct{}
178
179type DeleteEmailMsg struct {
180 UID uint32
181 AccountID string
182 Mailbox MailboxKind
183}
184
185type ArchiveEmailMsg struct {
186 UID uint32
187 AccountID string
188 Mailbox MailboxKind
189}
190
191type EmailActionDoneMsg struct {
192 UID uint32
193 AccountID string
194 Mailbox MailboxKind
195 Err error
196}
197
198// Batch operation messages
199type BatchDeleteEmailsMsg struct {
200 UIDs []uint32
201 AccountID string
202 Mailbox MailboxKind
203}
204
205type BatchArchiveEmailsMsg struct {
206 UIDs []uint32
207 AccountID string
208 Mailbox MailboxKind
209}
210
211type BatchMoveEmailsMsg struct {
212 UIDs []uint32
213 AccountID string
214 SourceFolder string
215 DestFolder string
216}
217
218type BatchEmailActionDoneMsg struct {
219 Count int
220 SuccessCount int
221 FailureCount int
222 Action string // "delete", "archive", or "move"
223 Mailbox MailboxKind
224 Err error
225}
226
227type GoToChoiceMenuMsg struct{}
228
229type DownloadAttachmentMsg struct {
230 Index int
231 Filename string
232 PartID string
233 Data []byte
234 AccountID string
235 Encoding string
236 Mailbox MailboxKind
237}
238
239type AttachmentDownloadedMsg struct {
240 Path string
241 Err error
242}
243
244type RestoreViewMsg struct{}
245
246type BackToInboxMsg struct{}
247
248type BackToMailboxMsg struct {
249 Mailbox MailboxKind
250}
251
252// --- Draft Messages ---
253
254// DiscardDraftMsg signals that a draft should be cached.
255type DiscardDraftMsg struct {
256 ComposerState *Composer
257}
258
259type EmailBodyFetchedMsg struct {
260 UID uint32
261 Body string
262 BodyMIMEType string
263 Attachments []fetcher.Attachment
264 Err error
265 AccountID string
266 Mailbox MailboxKind
267}
268
269// --- Multi-Account Messages ---
270
271// GoToAddAccountMsg signals navigation to the add account screen.
272type GoToAddAccountMsg struct{}
273
274// GoToAddMailingListMsg signals navigation to the add mailing list screen.
275type GoToAddMailingListMsg struct{}
276
277// GoToEditAccountMsg signals navigation to edit an existing account.
278type GoToEditAccountMsg struct {
279 AccountID string
280 Provider string
281 Name string
282 Email string
283 FetchEmail string
284 SendAsEmail string
285 CatchAll bool
286 IMAPServer string
287 IMAPPort int
288 SMTPServer string
289 SMTPPort int
290 Insecure bool
291 Protocol string
292 JMAPEndpoint string
293 POP3Server string
294 POP3Port int
295 MaildirPath string
296}
297
298// GoToEditMailingListMsg signals navigation to edit an existing mailing list.
299type GoToEditMailingListMsg struct {
300 Index int
301 Name string
302 Addresses string
303}
304
305// SaveMailingListMsg signals that a new or edited mailing list should be saved.
306type SaveMailingListMsg struct {
307 Name string
308 Addresses string
309 EditIndex int // -1 means new, >= 0 means editing existing
310}
311
312// AddAccountMsg signals that a new account should be added.
313type AddAccountMsg struct {
314 Credentials Credentials
315}
316
317// AccountAddedMsg signals that an account was successfully added.
318type AccountAddedMsg struct {
319 AccountID string
320 Err error
321}
322
323// DeleteAccountMsg signals that an account should be deleted.
324type DeleteAccountMsg struct {
325 AccountID string
326}
327
328// AccountDeletedMsg signals that an account was successfully deleted.
329type AccountDeletedMsg struct {
330 AccountID string
331 Err error
332}
333
334// SwitchAccountMsg signals switching to view a specific account's inbox.
335type SwitchAccountMsg struct {
336 AccountID string // Empty string means "ALL" accounts
337}
338
339// AllEmailsFetchedMsg signals that emails from all accounts have been fetched.
340type AllEmailsFetchedMsg struct {
341 EmailsByAccount map[string][]fetcher.Email
342 Mailbox MailboxKind
343}
344
345// SwitchFromAccountMsg signals changing the "From" account in composer.
346type SwitchFromAccountMsg struct {
347 AccountID string
348}
349
350// GoToAccountListMsg signals navigation to the account list in settings.
351type GoToAccountListMsg struct{}
352
353// --- Draft Messages (persisted) ---
354
355// SaveDraftMsg signals that the current draft should be saved to disk.
356type SaveDraftMsg struct {
357 Draft config.Draft
358}
359
360// DraftSavedMsg signals that a draft was saved successfully.
361type DraftSavedMsg struct {
362 DraftID string
363 Err error
364}
365
366// LoadDraftsMsg signals a request to load all saved drafts.
367type LoadDraftsMsg struct{}
368
369// DraftsLoadedMsg signals that drafts were loaded from disk.
370type DraftsLoadedMsg struct {
371 Drafts []config.Draft
372}
373
374// OpenDraftMsg signals that a specific draft should be opened in the composer.
375type OpenDraftMsg struct {
376 Draft config.Draft
377}
378
379// DeleteDraftMsg signals that a draft should be deleted.
380type DeleteSavedDraftMsg struct {
381 DraftID string
382}
383
384// DraftDeletedMsg signals that a draft was deleted.
385type DraftDeletedMsg struct {
386 DraftID string
387 Err error
388}
389
390// GoToDraftsMsg signals navigation to the drafts list.
391type GoToDraftsMsg struct{}
392
393// --- Cache Messages ---
394
395// CachedEmailsLoadedMsg signals that cached emails were loaded from disk.
396type CachedEmailsLoadedMsg struct {
397 Cache *config.EmailCache
398}
399
400// RefreshingEmailsMsg signals that a background refresh is in progress.
401type RefreshingEmailsMsg struct {
402 Mailbox MailboxKind
403}
404
405// EmailsRefreshedMsg signals that fresh emails have been fetched in the background.
406type EmailsRefreshedMsg struct {
407 EmailsByAccount map[string][]fetcher.Email
408 Mailbox MailboxKind
409}
410
411// RequestRefreshMsg signals a request to refresh emails from the server.
412type RequestRefreshMsg struct {
413 Mailbox MailboxKind
414 Counts map[string]int
415 FolderName string
416}
417
418// --- Folder Messages ---
419
420// FoldersFetchedMsg signals that IMAP folders have been fetched for all accounts.
421//
422// Errors holds per-account fetch failures (e.g. broken IMAP login, network
423// unreachable). Accounts that succeeded appear in FoldersByAccount; accounts
424// that failed appear in Errors. The two are disjoint by construction. This
425// lets the TUI surface a non-fatal warning instead of silently dropping the
426// affected account's folder list.
427type FoldersFetchedMsg struct {
428 FoldersByAccount map[string][]fetcher.Folder // accountID -> folders
429 MergedFolders []fetcher.Folder // unique folders across all accounts
430 Errors map[string]error // accountID -> fetch error, if any
431}
432
433// SwitchFolderMsg signals switching to a different IMAP folder.
434type SwitchFolderMsg struct {
435 FolderName string
436 PreviousFolder string
437 AccountID string
438}
439
440// FolderEmailsFetchedMsg signals that emails from a folder have been fetched.
441type FolderEmailsFetchedMsg struct {
442 Emails []fetcher.Email
443 AccountID string
444 FolderName string
445}
446
447// FolderEmailsAppendedMsg signals that more emails from a folder have been fetched (pagination).
448type FolderEmailsAppendedMsg struct {
449 Emails []fetcher.Email
450 AccountID string
451 FolderName string
452}
453
454// MoveEmailMsg signals a request to show the move-to-folder picker.
455type MoveEmailMsg struct {
456 UID uint32
457 AccountID string
458 SourceFolder string
459}
460
461// MoveEmailToFolderMsg signals that an email should be moved to a folder.
462type MoveEmailToFolderMsg struct {
463 UID uint32
464 AccountID string
465 SourceFolder string
466 DestFolder string
467}
468
469// EmailMovedMsg signals that an email was moved to a folder.
470type EmailMovedMsg struct {
471 UID uint32
472 AccountID string
473 SourceFolder string
474 DestFolder string
475 Err error
476}
477
478// MarkEmailAsReadMsg signals that an email should be marked as read on the server.
479type MarkEmailAsReadMsg struct {
480 UID uint32
481 AccountID string
482 FolderName string
483}
484
485// EmailMarkedReadMsg signals that an email was marked as read.
486type EmailMarkedReadMsg struct {
487 UID uint32
488 AccountID string
489 Err error
490}
491
492// FetchFolderMoreEmailsMsg signals a request to fetch more emails from a folder (pagination).
493type FetchFolderMoreEmailsMsg struct {
494 Offset uint32
495 AccountID string
496 FolderName string
497 Limit uint32
498}
499
500// --- External Editor Messages ---
501
502// OpenEditorMsg signals that the composer body should be opened in $EDITOR.
503type OpenEditorMsg struct{}
504
505// EditorFinishedMsg signals that the external editor has closed.
506type EditorFinishedMsg struct {
507 Body string
508 Err error
509}
510
511// --- IDLE Messages ---
512
513// IdleNewMailMsg signals that IMAP IDLE detected new mail for an account/folder.
514type IdleNewMailMsg struct {
515 AccountID string
516 FolderName string
517}
518
519// --- Daemon Messages ---
520
521// DaemonEventMsg wraps an event pushed from the daemon process.
522type DaemonEventMsg struct {
523 Event *daemonrpc.Event
524}
525
526// --- Plugin Messages ---
527
528// PluginNotifyMsg signals that a plugin wants to show a notification.
529type PluginNotifyMsg struct {
530 Message string
531 Duration float64 // Duration in seconds (default 2)
532}
533
534// PluginKeyBinding describes a plugin-registered keyboard shortcut for display in the help bar.
535type PluginKeyBinding struct {
536 Key string
537 Description string
538}
539
540// PluginPromptSubmitMsg signals that the user submitted a plugin prompt input.
541type PluginPromptSubmitMsg struct {
542 Value string
543}
544
545// PluginPromptCancelMsg signals that the user cancelled a plugin prompt input.
546type PluginPromptCancelMsg struct{}
547
548// GoToMarketplaceMsg signals navigation to the plugin marketplace.
549type GoToMarketplaceMsg struct{}
550
551// PasswordVerifiedMsg signals that the encryption password was verified (or failed).
552type PasswordVerifiedMsg struct {
553 Key []byte // The derived encryption key (nil on failure)
554 Err error // Non-nil if verification failed
555}
556
557// SecureModeEnabledMsg signals that encryption was enabled from settings.
558type SecureModeEnabledMsg struct {
559 Err error
560}
561
562// SecureModeDisabledMsg signals that encryption was disabled from settings.
563type SecureModeDisabledMsg struct {
564 Err error
565}
566
567// SendRSVPMsg signals that user wants to send RSVP to calendar invite
568type SendRSVPMsg struct {
569 OriginalICS []byte
570 Event *calendar.Event
571 Response string // "ACCEPTED", "DECLINED", "TENTATIVE"
572 AccountID string
573 InReplyTo string
574 References []string
575}
576
577// RSVPResultMsg signals that RSVP was sent (or failed)
578type LanguageChangedMsg struct{}
579
580// ConfigSavedMsg signals the config was written to disk and downstream
581// consumers (notably the daemon) should reload it.
582type ConfigSavedMsg struct{}
583
584type RSVPResultMsg struct {
585 Err error
586 Response string // "ACCEPTED", "DECLINED", "TENTATIVE"
587 Organizer string // organizer email for Google Calendar note
588}