messages.go

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