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