Investigation into #12876, a mysterious bug where users were seeing
messages reappear as unread, determined that the root cause was
missing headers to disable client-side caching for Zulip's REST API
endpoints.
This manifested, in particular, for `GET /messages`, which is
essentially the only API GET endpoint used by the webapp at all. When
using the `Ctrl+Shift+T` feature of browsers to restore a recently
closed tab (and potentially other code paths), the browser would
return from its disk cache a cached copy of the GET /messages results.
Because we include message flags on messages fetched from the server,
this in particular meant that those tabs would get a stale version of
the unread flag for the batches of the most recent ~1200 messages that
Zulip fetches upon opening a new browser tab.
The issue took same care to reproduce as well, in large part because
the arguments to those initial GET /messages requests will vary as one
reads messages (because the `pointer` moves forward) and then enters
the "All messages" view; the disk cache is only used for GET requests
with the exact same URL parameters.
We will probably still want to merge the events error-handling changes
we had previously proposed for this, but the conclusion of this being
a straightforward case of missing cache-control headers is much more
satisfying than the "badly behaving Chrome" theory discussed in the
issue thread.
Fixes#12876.
Django’s default FileSystemFinder disallows STATICFILES_DIRS from
containing STATIC_ROOT (by raising an ImproperlyConfigured exception),
because STATIC_ROOT is supposed to be the result of collecting all the
static files in the project, not one of the potentially many sources
of static files.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
In the rare case that Zulip receives an email with only an HTML
format, we originally (code dating to 2013) shelled out to
html2markdown/python-html2text in order to convert the HTML into
markdown.
We long since added html2text as a reasonably managed Python
dependency of Zulip; we should just use it here.
I noticed a super weird bug where the edit pencil would disappear on
hover inside the message feed (!). Investigation determined that what
was actually happening was that the Drafts overlay had been shown and
then hidden at a time when the mouse cursor was over the icons with
`data-toggle="tooltip"` configured, and the tooltip showing. The
result was that this tooltip object, if you mouse over it, would cause
us to no longer be hovering over the message (because your cursor was
actually over the invisible drafts widget's leaked tooltip).
Ideally, we'd have fixed this by making the drafts modal `display:
none`, but that would interfere with the modal's closing animation,
and there's no good way to have an event trigger on a CSS animation
finishing.
There's a second bug that makes this possible, however, which is that
the drafts modal is supposed to be `pointer-events: none` while
hidden, but some rogue CSS for `message_top_line *` set
`pointer-events: auto` to override `pointer-events: none` on
`message_top_line` was accidentally applying to things inside that
line in the drafts modal, and furthermore accidentally overriding the
`none` setting for the modal as a whole.
We fix that second bug here, which resolves the overall issue.
Otherwise python3 will be perpetually copied from virtualenv to
virtualenv and will never receive updates from the system.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
For .start-button, Bootstrap carousel already supports <button
data-target> as a valid alternative to <button href>. For
.call-to-action, the margin is decreased to exactly offset the lack of
margin collapsing with display: inline-block. There should be no
visual change.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Outgoing email documentation should mention that the SMTP server needs
to allow emails originating from ZULIP_ADMINISTRATOR as well as the
noreply email addresses; previously, one would typically find this out
using the test tool, which was not ideal.
Substantially tweaked by tabbott for organization and content.