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