Both request drivers assume $extra_headers is a flat list of
"Name: value" strings, but callers pass an associative array. The most
visible case is the CardDAV provider, which sends
array('Content-Type' => 'text/vcard; charset=utf-8')
from RainLoop\Providers\AddressBook\CardDAV::davClientRequest().
curl: CURLOPT_HTTPHEADER receives the map as-is, so curl emits the bare
value "text/vcard; charset=utf-8" as a header line and discards it as
malformed.
socket: array_merge() then implode("\r\n", ...) keeps only the values,
producing the same malformed line.
In both drivers the header is therefore lost, and because a body is
present the request falls back to Content-Type:
application/x-www-form-urlencoded. A CardDAV server is entitled to reject
that: Cyrus IMAP answers PUT of a vCard with
403 <C:supported-address-data/>
so every contact upload fails while the download half of the sync works,
which makes the sync look silently one-way.
Normalise string keys to "Name: value" in both drivers and leave integer
keys untouched, so existing callers that already pass a flat list are
unaffected.
With many folders, the line-height is too large.
It is reduced to make the view more compact.
Also, the top margin for the number of unread-folder will
be adapted.
When composing a message in reply to an email, a colon is appended to
the message which is translated, in french colon should always be
prepended by an unbreakable space.
Add a space in the translation sentence to make sure the space appears
before the colon in the interface
Fix for https://github.com/the-djmaze/snappymail/issues/1860 to remove <x-html></x-html> tags that might be emitted by certain email clients.
Tested by modifying locally using JS debugger and Snappymail JS debug mode.