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