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