messages.go

  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}