aboutsummaryrefslogtreecommitdiffstats
path: root/lib/msgstore.go
Commit message (Collapse)AuthorAgeFilesLines
* store: fix split view blinkingNicolas Dichtel2024-02-151-10/+14
| | | | | | | | | | | | | | | | | | | | | When split view and threading mode are enabled, the message is blinking. First, since commit ddfa5cac1fe9 ("msgstore: fix deadlock in thread builder"), the threadCallback is never set to nil: the thread builder calls it continuously. After setting it to nil, the message is still blinking once. To avoid this, don't call the onSelect method (which points to AccountView.updateSplitView()) from the thread builder: the message is already displayed. Let's rewrite Select and selectPriv: - Select(): it takes the lock and calls the onSelect callback; - selectPriv: the assumption is that the lock is held. It doesn't call the onSelect callback. This function is only used by the thread builder. Fixes: 588be1a28422 ("store: improve cursor position") Fixes: ddfa5cac1fe9 ("msgstore: fix deadlock in thread builder") Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: create destination folder on store.AppendJohannes Thyssen Tishman2024-01-251-0/+7
| | | | | | | | | When appending a message to a folder, always create the destination folder if it doesn't exist. Signed-off-by: Johannes Thyssen Tishman <johannes@thyssentishman.com> Acked-by: Robin Jarry <robin@jarry.cc>
* hooks: add mail-added hookJason Cox2023-11-021-2/+28
| | | | | | | | | | | | | | The mail-added hook runs whenever a message is added to a folder. Note that the hook does not run when a new message is received (the mail-received hook already covers that) but instead runs whenever aerc itself adds a message to a folder, e.g. when moving or copying a message. Changelog-added: `mail-added` hook that triggers when a message is added to a folder. References: https://todo.sr.ht/~rjarry/aerc/136 Signed-off-by: Jason Cox <me@jasoncarloscox.com> Acked-by: Robin Jarry <robin@jarry.cc>
* hooks: add mail-deleted hookJason Cox2023-11-021-2/+8
| | | | | | | | | | | | The mail-deleted hook runs whenever a message is deleted from a folder. Note that this means moving a message from one folder to another triggers the mail-deleted hook. Changelog-added: `mail-deleted` hook that triggers when a message is removed/moved from a folder. References: https://todo.sr.ht/~rjarry/aerc/136 Signed-off-by: Jason Cox <me@jasoncarloscox.com> Acked-by: Robin Jarry <robin@jarry.cc>
* fold: add an option to toggle foldinginwit2023-11-021-10/+25
| | | | | | | | | | Add a toggle option (-t) to :fold/:unfold commands to allow for switching the folding status of a thread. Changelog-Added: Toggle folding with `:fold -t`. Signed-Off-By: inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Jason Cox <me@jasoncarloscox.com>
* fold: allow for multiple folding levelsinwit2023-11-021-2/+11
| | | | | | | Extend the :fold/:unfold behaviour to allow for multiple folding levels. Signed-Off-By: inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* search: use a common api for all workersRobin Jarry2023-10-281-15/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | Define a SearchCriteria structure. Update the FetchDirectoryContents, FetchDirectoryThreaded and SearchDirectory worker messages to include this SearchCriteria structure instead of a []string slice. Parse the search arguments in a single place into a SearchCriteria structure and use it to search/filter via the message store. Update all workers to use that new API. Clarify the man page indicating that notmuch supports searching with aerc's syntax and also with notmuch specific syntax. getopt is no longer needed, remove it from go.mod. NB: to support more complex search filters in JMAP, we need to use an email.Filter interface. Since GOB does not support encoding/decoding interfaces, store the raw SearchCriteria and []SortCriterion values in the cached FolderContents. Translate them to JMAP API objects when sending an email.Query request to the server. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Koni Marti <koni.marti@gmail.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Tested-by: Inwit <inwit@sindominio.net>
* commands: add :toggle-thread-context commandTim Culverhouse2023-09-271-0/+8
| | | | | | | | | Add a command to toggle the display of an thread-context. Update CHANGELOG. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* ui: enable showing of thread-contextTim Culverhouse2023-09-271-0/+4
| | | | | | | | | | | | | | | Add a UI config value to enable showing of "thread-context", similar to `notmuch show --entire-thread=true`. Add an associated style called "msglist_thread_context" which can be used to style such messages. Currently this feature is only supported by notmuch. It would be possible for maildir to implement as well, IMAP with gmail custom extensions, and JMAP. This patch merely implements the notmuch version and puts the groundwork in for handling these sorts of displays. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: ensure selection when calling sortTim Culverhouse2023-08-311-0/+5
| | | | | | | | | | | | | | | When using notmuch and changing labels, there is no reselection logic as there is when using a :mv command for other backends. This results in any label change that removes the message from the current query in having no selection. Add some simple reselection logic in the Sort callback so any call to Sort (which will refresh the message list) ensures the previously selected message is still selected, and if it isn't in the store anymore we select the same index of message as was previously selected. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* msglist: fetch headers even when not focusedRobin Jarry2023-08-041-7/+28
| | | | | | | | | | | | | | Do not rely on MessageList.Draw only to fetch missing headers. In Draw, report the current scroll offset and length to the message store and use them to determine if a new message UID should be candidate for fetching headers. This allows the mail-received hook to work even when the message list is not focused. Fixes: https://todo.sr.ht/~rjarry/aerc/147 Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tristan Partin <tristan@partin.io>
* store: implement thread foldingKoni Marti2023-07-161-0/+32
| | | | | | | | Implement thread folding on the message store level. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: inwit <inwit@sindominio.net>
* threadbuilder: store uid/thread associationKoni Marti2023-07-161-35/+23
| | | | | | | | | | | | | | Store the association between uids and threads in a map instead of just having the threads in a slice. This simplifies the lookup of a thread when we have an uid and we can avoid computationally expensive tree walks. The threadbuilder will rebuild the uids from the given thread structure. Hence there is no need now to keep a threads slice around. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: inwit <inwit@sindominio.net>
* msgstore: delete pending headers when done or cancelledTim Culverhouse2023-06-201-1/+2
| | | | | | | | | | | | | | The msgstore keeps a map of UIDs it has requested headers for. The map is only cleared of pending headers when either an error or a valid header is received. This can lead to pending headers not being removed from the list (and therefore never re-requested) if a user has navigated away from the directory before the response is received. Delete the pending headers list if the request is finished or cancelled. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* worker: add context to cancellable requestsTim Culverhouse2023-06-201-11/+19
| | | | | | | | | | | | | Add a Context field to requests which we may want to cancel when changing directories. Add a Cancelled meta-message to inform the UI that a request was cancelled (as opposed to Done or Error). Delete callbacks when a request is Cancelled. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: pass context from dirlist to msgstoreTim Culverhouse2023-06-201-0/+8
| | | | | | | | | | | | | Most, if not all, requests to the worker that may need cancellation are sent by the msgstore. These requests are typically only relevant when the msgstore is the selected one. Pass a context from the dirlister to the msgstore when it is selected. This context will be passed in future commits to worker requests. The context is cancelled when a new directory is selected. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: allocate properly sized mapsTim Culverhouse2023-06-201-3/+2
| | | | | | | | Allocate properly sized maps when receiving a DirectoryContents or DirectoryThreaded message Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* logging: remove ultra verbose trace logsRobin Jarry2023-06-121-3/+1
| | | | | | | | | | | | | | | | | Every message exchanged between the UI and the worker(s) is logged at least twice with some obscure IDs and struct pointer names. When enabling trace logging, this floods the files for very little or no benefit and makes the meaningful logging message hard to catch. Also, other messages tend to flood the output for no specific reason. These are most of the time leftovers from the development process and are not useful for tracking potential issues. Remove these. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* ui: fix deadlocks in message channelRobin Jarry2023-05-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are several ways the ui message channel can fill up leading to deadlocks. 1) Invalidate() changes the value of uiState to DIRTY. The following call sequence: QueueRedraw() Invalidate() QueueRedraw() Leads to multiple nil messages being queued in the message channel whereas one could assume that the second QueueRedraw() would do nothing. This is caused by the tri-state nature of uiState. 2) We use the same channel to convey state change, keyboard events and redraw requests. Since a keyboard event almost always triggers a redraw, we end up trying to append a redraw message in the same goroutine that reads from the channel. This triggers a deadlock when there are more than 50 pending messages. Solve the issue by using multiple channels, one per type of message that needs to be sent to the main ui thread. Remove QueueRedraw() and merge its functionality in Invalidate(). Only use a DIRTY/CLEAN state to determine if something needs to be queued in the redraw channel. Use a channel for quitting instead of an atomic. Restructure some code functions to have a cleaner API. Use a for loop in the main thread and select from all channels. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Koni Marti <koni.marti@gmail.com> Tested-by: Maarten van Gompel <proycon@anaproy.nl>
* msgstore: fix handling of deleted messagesTim Culverhouse2023-05-111-5/+4
| | | | | | | | | | | | | | | | | | The msgstore trims the uid list when a message was deleted. It does so whether the message is in the message store or not. If the message was already deleted and a MessagesDeleted is received, the store will be trimmed regardless. This can cause spurious emails to be removed from the msgstore due to a race condition with the fs watcher / imap update channel. When a message is deleted, the UI will received two MessagesDeleted and in some cases trim the list, removing too many emails. Fix the handling of deleted messages so that the uid list is rebuilt of all messages except the deleted ones specifically. Reported-by: Drew Devault <sir@cmpwn.com> Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Inwit <inwit@sindominio.net>
* directory: use directory to store rue countsTim Culverhouse2023-04-221-7/+0
| | | | | | | | | | | | Store the Directory RUE counts on the Directory data model. Use DirectoryInfo messages to update the Directory model. Access Directories via the dirlist instead of via the msgstore. Remove unused fields on DirectoryInfo, all backends now give accurate counts. Move refetch logic into dirlist Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry<robin@jarry.cc>
* msgstore: create from types.Directory messageTim Culverhouse2023-04-221-2/+0
| | | | | | | | | | | | | | | Create msgstores when a types.Directory message is received. This removes a quirk from the IMAP worker that msgstores are created on the first DirectoryInfo, and updated on the second. This path requires three messages in order to get an updated message store. By creating from types.Directory, we ensure that any subsequent DirectoryInfo can be routed to a msgstore. Remove the field DirInfo from the msgstore initializer, it isn't needed at initialization and isn't available with this refactor. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* capabilities: report capabilities from backendTim Culverhouse2023-04-221-2/+2
| | | | | | | | | | | | | Use the Backend interface to report Backend capabilities. Previously, these were reported via a DirectoryInfo message, however they have nothing to do with a directory and should be reported directly by the backend. Add Capabilities method to Backend interface, satisfy this in each backend, and use it on the UI side. Remove Caps field from DirectoryInfo Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry<robin@jarry.cc>
* msgstore: fetch message list based on OpenDirectory msgTim Culverhouse2023-04-221-2/+5
| | | | | | | | | | | | | | | Fetching the message list is done in a convoluted way. The UI receives a DirectoryInfo message, which creates a message store. It then receives a second DirectoryInfo (an oddity from the IMAP worker), and this DirectoryInfo is passed to the message store which then requests a fetch of the message list via store.Sort. Use the OpenDirectory done response to tell the message store to fetch messages. This makes the code easier to follow, and does not rely on quirks from the IMAP worker. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* config: replace triggers with hooksMoritz Poldrack2023-04-011-1/+1
| | | | | | | | | | | | | Deprecate triggers and replace them with hooks. Now that aerc supports running arbitrary ex commands over IPC, it is possible to run internal aerc commands *and* shell commands via external shell scripts. Hooks only allow running shell commands. Hooks info is passed via environment variables. Implements: https://todo.sr.ht/~rjarry/aerc/136 Signed-off-by: Moritz Poldrack <git@moritz.sh> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* msgstore: fix new-email trigger firing for all unread messagesRobin Jarry2023-01-241-2/+2
| | | | | | | | Unfortunate typo. Fixes: 5677f93ff8e0 ("model: change flags array to bitmask") Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Ben Cohen <ben@bencohen.net>
* model: change flags array to bitmaskRobin Jarry2023-01-041-11/+4
| | | | | | | Using a list of integers is not optimal. Use a bit mask instead. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
* msgstore: fix deadlock in thread builderRobin Jarry2023-01-031-1/+5
| | | | | | | | | | | | | | | | | | When scrolling while the thread builder is running, aerc freezes. This issue can be easily reproduced by keeping the down arrow pressed while a folder is loading with local threading enabled. This is caused by the threadCallback function calling store.Select which acquires threadsMutex. However, threadCallback is already called with threadsMutex acquired, causing a deadlock. Fix the issue by adding a new selectPriv function that does not acquire the lock and call this one in threadCallback *and* store.Select. Do not reset threadCallback to nil as it was before. Fixes: 6b8e0b19d35a ("split: refactor to prevent stuck splits") Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Thomas Vigouroux <me@vigoux.giize.com>
* split: refactor to prevent stuck splitsTim Culverhouse2022-12-251-3/+11
| | | | | | | | | | Refactor split logic (again...) to prevent stuck splits. Use callback from msgstore.Select to tell the split which message to display. This keeps the account from having to track displayed messages, which prevents race conditions in certain situations. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* threads: rebuild server threads when updating threadsTim Culverhouse2022-12-141-2/+10
| | | | | | | | | | | | | | | | | The addition of the iterator factory added a thread builder when using server side threads. A conditional for returning UIDs when selecting messages would check for a not-nil store.builder, and return UIDs from the thread builder. When using server side threads, there was no mechanism to update the threads after a message deletion or move, so store.Uids() would return a stale set of UIDs. This would allow the user to "select" a deleted email (the cursor would disappear). Add an update mechanism for the threads if server side threads are enabled. When building thread UIDs, check for deleted or hidden threads. Fixes: https://todo.sr.ht/~rjarry/aerc/123 Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Inwit <inwit@sindominio.net>
* split: refactor split update logicTim Culverhouse2022-12-141-0/+3
| | | | | | | | | | | | | | | | | | | | | | Refactor split update logic to more simply update the split. Through the evolution of the split logic, additional variables were stored within the account which allows for cleaner updating of the split. Compare selected UID instead of pointer to message when deciding not to update split. Allow splits to be created and closed when no message is selected. The split will be filled with a ui.Fill (blank). The user will only see a border at the split location when no message is selected. Rename clearSplit to closeSplit, as it is only used in the case when the user doesn't want a split anymore. Ensure that the selected UID is reset to the magic UID when there are no messages left in the message store. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* msgstore: set store.uids in threaded directoriesTim Culverhouse2022-12-071-0/+1
| | | | | | | | | | | | | | | Commit b46e57324394 ("store: fix server-side threads toggling") introduced a regression where the uids of the store were not set after rebuilding the threads. This would result in a flash of pending messages as they were repopulated. This also would not properly remove messages which were moved out of the store (deleted, moved, archived) with server side threading. Re-add the line that sets the store.uids. Fixes: b46e57324394 ("store: fix server-side threads toggling") Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Bence Ferdinandy <bence@ferdinandy.com>
* store: fix server-side threads togglingKoni Marti2022-12-021-3/+2
| | | | | | | | | | | Fix server-side threads toggling that can sometimes cause the uids to be out-of-sync with the threads. This patch ensures a consistent way of handling the uids and threads in the store. Fixes: https://todo.sr.ht/~rjarry/aerc/102 Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* logging: rename package to logRobin Jarry2022-12-021-3/+3
| | | | | | | | | | Use the same name than the builtin "log" package. That way, we do not risk logging in the wrong place. Suggested-by: Tim Culverhouse <tim@timculverhouse.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
* logging: homogenize levelsRobin Jarry2022-12-021-1/+1
| | | | | | | | | | | | | | | | | | The main goal is to ensure that by default, the log file (if configured) does not grow out of proportions. Most of the logging messages in aerc are actually for debugging and/or trace purposes. Define clear rules for logging levels. Enforce these rules everywhere. After this patch, here is what the log file looks like after starting up with a single account: INFO 2022/11/24 20:26:16.147164 aerc.go:176: Starting up version 0.13.0-100-g683981479c60 (go1.18.7 amd64 linux) INFO 2022/11/24 20:26:17.546448 account.go:254: [work] connected. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
* msglist: style search resultsTim Culverhouse2022-11-061-0/+10
| | | | | | | | Add option to style search results in the message list. Set default style for results. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: use default sort when applying ClearTim Culverhouse2022-11-061-1/+3
| | | | | | | | | | The :clear command clears any sorting, filtering, or marking of messages within the message store. Respect the user's default sort order by storing this in the store and re-applying the default sort when using clear. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* threadbuilder: sort siblings by sort criteriaKoni Marti2022-11-061-2/+5
| | | | | | | | | | | | | | Sort the client-side thread siblings according to the sort criteria. Activate this option by setting "sort-thread-siblings" to true in the ui section of aerc.conf. "sort-thread-siblings" is false by default and the siblings will be sorted based on their uid number. Note that this options will only work with client-side threading and when the backend supports sorting. Also, it comes with a slight performance penalty. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
* threads: reverse thread orderingKoni Marti2022-10-271-8/+18
| | | | | | | | | | | Add reverse-thread-order option to the ui config to enable reverse display of the mesage threads. Default order is the the intial message is on the top with all the replies being displayed below. The reverse options will put the initial message at the bottom with the replies on top. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* store: implement the simplified index handlingKoni Marti2022-10-271-33/+33
| | | | | | | | | | Simplify the index handling for moving to the next or previous message. Same for moving to the next or previous search results. Moving of the index variable relies on the iterator package's StartIndex and EndIndex functions. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* store: reverse message list order with iteratorsKoni Marti2022-10-271-22/+49
| | | | | | | | | | | | | | | | | Reverse the order of the messages in the message list. The complexity of reversing the order is abstracted away by the iterators. To reverse the message list, add the following to your aerc.conf: [ui] reverse-msglist-order=true Thanks to |cos| for sharing his initial implementation of reversing the order in the message list [0]. [0]: https://git.netizen.se/aerc/commit/?h=topic/asc_sort_imap Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* aerc: use single event loopTim Culverhouse2022-10-071-0/+2
| | | | | | | | | Combine tcell events with WorkerMessages to better synchronize state with IO and UI. Remove Tick loop for rendering. Use events to trigger renders. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: fix data race on access to store.needsFlagsTim Culverhouse2022-10-021-0/+5
| | | | | | | | | Flag fetching is debounced in the UI, creating a race condition where fields are accessed in the AfterFunc. Protect the needsFlags field with a mutex. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* logging: substitute %w for %vKoni Marti2022-10-021-1/+1
| | | | | | | | | | | | | | | | Subsitute the format specifier %w for %v in the logging facility. The logging functions use a fmt.Sprintf call behind the scene which does not recognize %w. %w should be used in fmt.Errorf when you want to wrap errors. Hence, the log entries that use %w are improperly formatted like this: ERROR 2022/10/02 09:13:57.724529 worker.go:439: could not get message info %!w(*fmt.wrapError=&{could not get structure: [snip] }) ^ Links: https://go.dev/blog/go1.13-errors Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* msgstore: revert 9fdc7acf5b48 "post messageInfo on erroneous fetch"Tim Culverhouse2022-09-251-13/+1
| | | | | | | | | | Commit 9fdc7acf5b48 ("cache: fetch flags from UI") introduced a regression where all messages were marked as erroneous if a single one in the fetch request had an error. Reported-by: Jose Lombera <jose@lombera.dev> Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* cache: fetch flags from UITim Culverhouse2022-09-201-0/+23
| | | | | | | | | | | | | | | When cached headers are fetched, an action is posted back to the Worker to immediately fetch the flags for the message from the server (we can't know the flags state, therefore it's not cached). When scrolling, a lag occurs when loading cached headers because the n+1 message has to wait for the flag request to return before the cached headers are retrieved. Collect the message UIDs in the UI that need flags, and fetch them based off a debounce timer in a single request. Post the action from the UI to eliminate an (ugly) go routine in the worker. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: post MessageInfo on erroneous fetchTim Culverhouse2022-09-201-1/+13
| | | | | | | | | | | | | | When errors occur during a fetch header request, the requested headers are deleted from pending and no information is given to the UI. Spinners keep spinning, and ultimately as the view is refreshed, the headers are fetched again. This can lead to infinite loops, and extremely long logs. Update the store with a MessageInfo message when an error is received. Have the UI display that the header couldn't be fetched in the message list. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: do not run threadbuilder unless in threaded viewTim Culverhouse2022-08-311-1/+3
| | | | | | | | | | | | | Commit 380cf13cff8e ("msgstore: run threadBuilder with no debounce on DirectoryContents msg") fixed an issue related to running the threadbuilder with a debounce. This fix causes the thread builder to run for any DirectoryContents message, even if the view is not threaded. Don't call runThreadBuilderNow unless in a threaded view. Fixes: 380cf13cff8e ("msgstore: run threadBuilder with no debounce on DirectoryContents msg") Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: enable granularity in updating of threadbuilderTim Culverhouse2022-08-301-4/+7
| | | | | | | | | | | Enable the msgstore to specify if an update should also update the threadbuilder. Certain calls to msgstore.update() did not require the threadbuilder to run, as it was either called implicitly through other means (nextPrev during a search) OR it was not needed (IE in the case of a DirectoryInfo message). Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: run threadBuilder with no debounce on DirectoryContents msgTim Culverhouse2022-08-301-21/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 54a0a377e030 ("threads: debounce client-side thread building") introduced the option to debounce threadbuilding to improve performance of client side threads. This caused a UI regression during filtering of mailboxes: 1. The mailbox contains the full set of message UIDs 2. User filters mailbox 3. A DirectoryContents message is received from worker with the proper UIDs to display 4. Debounce is started (in a separate go routine) 5. The value of msgStore.Uids() is used to show pending headers, but is not updated until the threadbuilder runs. The full set of UIDs is shown briefly 6. Debounce is over, threadbuilder runs, updates msgStore.Uids(), proper messages show. Run the thread builder immediately upon receipt of a DirectoryContents message, bypassing any debounce. Performance will remain the same: the debounce is meant to prevent multiple sequential calls to the thread builder during scrolling. This is unlikely to occur in rapid succession from filtering or sorting. Fixes: https://todo.sr.ht/~rjarry/aerc/76 Fixes: 54a0a377e030 ("threads: debounce client-side thread building") Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>