messages.go

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