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