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