IMHO, having the full name of the sender is more important than the
email in the message list. However, we can use the new free screen
realestate to display the new subject line if it has changed
Besides the obvious tree-like thing, this has for consequences that the
ordering of messages is slightly different, as they are now
topologically sorted rather than through purely chronological order.
It avoids parallel refreshes, which can happen if the refresh triggers a
secondary data update, e.g. via automatic mark as read on thread
opening.
It means we trigger our own has_refreshed signal, but that's OK, the
effects should only be a top-level view refresh.
This is a good old breaking change. Now, `current_message` will actually
yield the current message object rather than its index, while said index
is available at `current_index`. All the model APIs are changed to
consume and emit QModelIndex, and said indices are attached the message
they represent at creation, making it easier.
The goal long-term is to be able to move away from the ListView to use a
TreeView instead.
show_message has a weird API that deals in integer indices, and is also
used to refresh the UI. The indices are annoying because they're an
implementation detail, and the refresh part is a bit surprising when you
come across it in the code.
Removing it leaves only `current_message` as the remaining "integer" API
from ThreadPanel.
Rather than explicitly refreshing the data *then* the UI, let's just use
the default model signals to trigger the UI refreshes
This actually saves us a full refresh when first opening a thread.
Irrelevant in the sense that they didn't match the origin search query.
Not all themes have been tested, the values were determined by looking
for the recommended value for code comments on the various colorscheme
homepages.
Any thread opening is normally done from a search query. That search
query might have nothing to do with the unread status, and could only
match a handful of messages in the thread. So, rather than jumping to
the first unread message, we keep the search query as context when
opening the thread and use it to jump to the first message matching it.
When tagging a single message in a thread, only refresh that message
rather than the entire thread.
This is again due to some threads being *very* big, which when combined
with crypto signatures make the UI feel sluggish when changing the state
of a message, e.g. when reading it for the first time.
The computing time now doesn't scale with the size of the thread. It's
at similar levels from before on small threads, and is an order of
magnitude better on the recent tmpfs thread on debian-devel.
Note that right now we go through the entire list to get the index of a
given message. This could easily be optimized later on.
This has a really noticeable cost when reading monster threads, e.g. if
you're reading Debian mailing lists. It gets even worse when there's
crypto involved! OTOH, it's fairly unlikely that the data changes
underneath our feet if we're using Dodo to drive the "notmuch new"
calls, as it would trigger a refresh when done (or mark the panel as
dirty).
This allows collating multiple events on the same threads, e.g. reading
a long unread thread in a Thread panel. The previous approach would
trigger a full refresh if reading more than one message.
Updating the entire search panel when touching any piece of data is
really costly, which is presumably why we only do it on the currently
active one and will only refresh the other ones when we focus them.
This patch allows for a more granular approach to refreshes, with an API
that specifies which thread has been updated. Each panel can then either
update their own data model (if known to be relevant, e.g. the thread is
already in the search results, and it is cheap enough to do it right
away), mark itself as dirty to fall back on the previous global
behaviour, or ignore the update entirely (relevant for Thread panels).
When line wrapping in a folded content-disposition header occurs within
its filename parameter value, then the get_filename() method of the
(legacy) email.message.Message object returns a string containing a
newline character at the position where the filename parameter value
wraps. An attachment filename containing a newline character may result
in undefined behaviour with file management tools or scripts and may
have security implication. It also prevents forwarding mail in dodo by
throwing the exception 'Header values may not contain linefeed or
carriage return characters', because the filename is copied in the A:
pseudo-header.
This bug is not present in the email.message.EmailMessage class, which is
used when specifying the policy email.policy.default.
Additionally, the legacy method get_payload() is replaced by
get_content().
Signing and encryption is done on a copy of the original message. When
this original message contained non-ASCII characters, the copy process
introduced encoded words with the unknown-8bit charset.
This simplifies the code as we don't have to copy the data over from the
temporary Message object. The header copying in particular was failing
when using multiline headers as allowed by RFC 822.
I'm guessing we *could* get into trouble with encoding though? Since I'm
using UTF-8 everywhere it works fine for me.