package imap import ( "github.com/emersion/go-imap" sortthread "github.com/emersion/go-imap-sortthread" "git.sr.ht/~sircmpwn/aerc/worker/types" ) func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) { imapw.worker.Logger.Printf("Opening %s", msg.Directory) _, err := imapw.client.Select(msg.Directory, false) if err != nil { imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) } else { imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) if imapw.idleStop == nil { imapw.idleStop = make(chan struct{}) } } } func (imapw *IMAPWorker) handleFetchDirectoryContents( msg *types.FetchDirectoryContents) { imapw.worker.Logger.Printf("Fetching UID list") seqSet := &imap.SeqSet{} seqSet.AddRange(1, imapw.selected.Messages) uids, err := imapw.client.UidSearch(&imap.SearchCriteria{ SeqNum: seqSet, }) if err != nil { imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) } else { imapw.worker.Logger.Printf("Found %d UIDs", len(uids)) imapw.seqMap = make([]uint32, len(uids)) imapw.worker.PostMessage(&types.DirectoryContents{ Message: types.RespondTo(msg), Uids: uids, }, nil) imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) } } func (imapw *IMAPWorker) handleNativeThreadSupport( msg *types.FetchNativeThreadSupport) { hasSupport, err := imapw.client.tc.SupportThread() if err != nil { imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) } else { imapw.worker.PostMessage(&types.NativeThreadSupport{ Message: types.RespondTo(msg), HasSupport: hasSupport, }, nil) imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) } } func (imapw *IMAPWorker) handleDirectoryThreaded( msg *types.FetchDirectoryThreaded) { imapw.worker.Logger.Printf("Fetching threaded UID list") seqSet := &imap.SeqSet{} seqSet.AddRange(1, imapw.selected.Messages) threads, err := imapw.client.tc.UidThread(sortthread.References, &imap.SearchCriteria{SeqNum: seqSet}) if err != nil { imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) } else { root := &types.Thread{ Uid: 0, Dummy: true, } aercThreads, count := convertThreads(threads, root) root.Children = aercThreads imapw.seqMap = make([]uint32, count) imapw.worker.PostMessage(&types.DirectoryThreaded{ Message: types.RespondTo(msg), ThreadRoot: root, }, nil) imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) } } // This sucks... TODO: find a better way to do this. func convertThreads(threads []*sortthread.Thread, parent *types.Thread) ([]*types.Thread, int) { if threads == nil { return nil, 0 } conv := make([]*types.Thread, len(threads)) count := 0 for i := 0; i < len(threads); i++ { t := threads[i] conv[i] = &types.Thread{ Uid: t.Id, Dummy: false, } conv[i].Parent = parent children, childCount := convertThreads(t.Children, conv[i]) conv[i].Children = children count += childCount + 1 } return conv, count }