The fix works by having build_stream_sidebar_row()
automatically update its own unread count when we
build a sidebar row. Currently we rebuild sidebar
rows when we pin/unpin rows.
As an aside, we currently don't really need to rebuild
the sidebar row when we pin, since we're only moving
the DOM, not altering it. But this may change in the
future, so I decided to leave that code path in place.
We may decide to do things in the future like showing
pinned streams with bolder fonts or special icons or
whatever.
Fixes#2902
Due to the fact that getComputedValue is called when using filter and
opacity attributes, it is much more efficient to use an SVG that has a
changing fill color rather than something that may be interpreted by
browsers as a layout change that requires layout recalculation.
This should result in noticeably smoother and more responsive :hover
events for the streams with greyed checkmarks.
Pass down 'local_id' through functions that handle notifications for messages
that are sent locally. If 'local_id' is undefined, the message was not sent in
the respective tab, so no "outside_viewport" notification should be displayed.
This fixes#1783.
When user list displays on the left, the maximum height of the
<code>stream-filters-container</code> is determined by the function
<code>confine_to_range(lo,val,high)</code>. By changing the value of
<code>lo</code> to 80, the <code>stream-filters-container</code>
resizes to 80 px instead of 40 px.
Fixes#2510.
This adds styling such that when you hover over a stream in the streams
list and you are not subscribed, you will see a faint grey checkmark
that serves as a target of where to click so you can subscribe to a
stream.
This adds a deep link behind a “+” icon above the streams list on the
left-sidebar which opens the subscriptions page and then also toggles
the tabs to go to the unsubscribed stream list.
- Change `stream_name` into `stream_id` on some API endpoints that use
`stream_name` in their URLs to prevent confusion of `views` selection.
For example:
If the stream name is "foo/members", the URL would be trigger
"^streams/(?P<stream_name>.*)/members$" and it would be confusing because
we intend to use the endpoint with "^streams/(?P<stream_name>.*)$" regex.
All stream-related endpoints now use stream id instead of stream name,
except for a single endpoint that lets you convert stream names to stream ids.
See https://github.com/zulip/zulip/issues/2930#issuecomment-269576231
- Add `get_stream_id()` method to Zulip API client, and change
`get_subscribers()` method to comply with the new stream API
(replace `stream_name` with `stream_id`).
Fixes#2930.
Fixes the leaked popover issue where a popover for a dead element was
unable to be removed because it wasn’t connected to a parent that
existed in the DOM. Now they are cleaned up on every call to
popovers.hide_all().
Fixes: #3077.
When filtering users in the new stream form, check all
and uncheck all will only effect those users who are filtered,
visible in the dom.
Includes a Casper test for the new condition.
This changes the logo that sits at the top of the messages to an SVG
rather than a PNG used as the current navbar logo that is filtered to
be grayscale.
This fixes a significant performance regression that had been caused
by adding that logo to the top of the feed.
Thanks to @rishig for generating the SVG!
This fixes the user’s name to not fall on the next line. Instead it
appears on the same line and overflows properly into an ellipsis so it
theoretically should never overflow on to the next line.
This reverts commit 7bf10ec74f.
Apparently, SockJS 1.1.1 is broken with the browser used in our legacy
desktop app, resulting in messages being silently not sent.
This adds some configuration options to settings.py, namely
PASSWORD_MIN_LENGTH and PASSWORD_MIN_QUALITY, which control
when the frontend validator invalidates the password.
Closes#2628
Emoji styling was broken in Firefox browser due to its lack of support
for the zoom property.
This replaces the zoom property with the transform property that now
scales the emojis down to 70% of their original size.
This reverts commit e4761782e0.
This caused performance problems and jolting of the main UI, because
it broke the important invariant that the height of a Zulip message
should not depend on the content of slow-to-load assets such as
images.
This fixes two issues:
* If you had around 10 distinct emoji reactions on a message (enough
to force a line wrap if the add-your-emoji button was visible),
Zulip would add that button into a new row on hover, jolting the
message feed. This fixes that problem by leaving a blank last line
for the add-your-emoji button.
* We were incorrectly showing the padding for the emoji reactions
region even if there were no emoji reactions, causing messages to
have too much padding.
Add the Zulip logo to the top of the messages feed to show that there
are no more messages to load, or that it is loading more (if the
spinner is still around).
This shows a date on a message header whenever the date of that
message is different than the date of the previous message.
The previous logic was bugged and didn't display dates in headers at
date transition points.
When we change a stream name, we now use the stream id as the
key to find messages we need to live update. This eliminates
some possible race conditions from two users renaming a stream.
This commit introduces message_live_update.js.
The new call stack is this:
subs.update_subscription_properties
subs.update_stream_name
message_live_update.update_stream_name
message_list.update_stream_name
The issue is that we were trying to validate the mentions before
checking that the recipient stream was valid, leading to problems
checking the membership of the stream.
Fixes#3040.
Stream descriptions are now displayed along with the name. The
autocomplete results include streams with matches in the stream
descriptions. Added styling for description in compose.css.
Fixes#2398.
When somebody changes their name, we will now update
the buddy list right away. The old code was trying
to do this through a code path that was designed for
true presence updates, but it was also passing in an
empty array, instead of undefined, which caused it to
fail to invoke the intended part of the codepath to
redraw the buddy list.
Now we just call the new activity.redraw() function,
which does the right thing for the buddy list.
The group PM list was live-updating before this change,
and it continues to live-update as part of the new
activity.redraw() function.
Using the offsetHeight getter is ~2.5x faster than
getBoundingClientRect() on what can be an expensive operation to do in
the hundreds of times.
Note: Tim thinks that this may have been different a few years ago,
since we tested fairly carefully before settling on
getBoundingClientRect, but benchmarks pretty clearly show offsetHeight
is faster today, so we should use that.
The escape key used to be intercepted if the subscription pay display
was set to “block”, but now since we use the class “show” and lack to
hide and show the overlay, the query needs to change.
We attempted a number of different approaches to solving this problem:
First, we tried using HTML5 local storage to keep track of which
browser should have created the desktop notification. This failed
because one needs locking, and it doesn't appear there is an working
locking implementation for HTML5 local storage that could allow us to
do this across tabs. See #2936 for details.
Ultimately we went with setting the message ID as a tag. Tags are
intended to be used for updating existing desktop notifications, which
means this implementation causes new notifications to flicker in and
out sometimes when multiple tabs are open, but that certainly beats
having duplicates.
Fixes#99.
Previously, the emoji reactions popovers were keyed off the
edit_content area, which is problematic because that area was
created/deleted on hover, resulting in orphaned popovers (which
wouldn't close properly normally). That had been hackishly addressed
in the original PR with the overbroad `$('.popover').remove();`. To
remove that, we fix the actions popover to always be based on an
element that exists in the page.
There probably more to do here, but this is good enough to merge emoji
reactions and iterate from here.
This commit replaces the placeholder "clipboard" button with a reaction button.
This is done on any message that can't be edited. Also, on messages sent by
the user the actions popover (toggled by the down chevron icon) contains
an option to add a reaction.
When clicked, a popover with a search bar and a list of emojis is displayed.
If the right sidebar is collapsed (the viewport is small), the popover is placed
to the left of the button.
Focus is set to the search bar. Typing in the search bar filters emojis.
Emojis with which the user has reacted to this message are highlighted.
Clicking them sends an API request to remove that reaction.
Clicking on non-highlighted emojis sends an API request to add a reaction.
When the popover loses focus it is closed.
The frontend listens for reaction events. When an add-reaction event is
received, the emoji is displayed at the bottom of the message with a
count initialized to 1. If there was an existing reaction to the message with
the same emoji, the count is incremented.
Old messages fetched from the server contain reactions.
They are displayed (along with title and count) at the bottom
of each message.
When clicking the emoji reaction at the bottom of the message, if the
user has already reacted with that emoji to this message, the reaction
is removed and the count is decremented. Otherwise, a reaction is added
and the count is incremented.
Hovering over the emoji reaction at the bottom of the message displays
a list of users who have reacted with this emoji along with the
emoji name.
Hovering over the emoji reactions at the bottom of the message displays
a button to add a reaction.
Fixes#541.
Update integration to use the latest Google API client.
Move Google Account authorization code to a separate file.
Move relevant files from 'bots/' to 'api/integrations/google/'.
Add documentation for integration.
There was a duplicate #full_name ID being added many times in tables.
They should be removed because they are not being called anywhere and
should not exist in multiples.
When editing a message changes the current narrow, we rerender the
narrowed view earlier in the function, so we don't need to do it here.
But we still need to rerender the home view, or the messages will be
displayed incorrectly once the user unnarrows!
Tweaked by tabbott for clarity and simplicity.
Fixes#2464.
docs: Add user guide for reply to a message
docs: Add user guide for reply to a message
docs: Add user guide for reply to a message
docs: Add user guide for reply to a message
docs: Add user guide for reply to a message
In 06615bee00, we accidentally
introduced a duplicate HTML ID for #stream-checkboxes, which in turn
caused the "invite users" page to no longer work. This fixes that
problem.
Some of the work here was done Tomasz Kolek.
When we click on "more conversations" in "Private Messages,"
we call it being "zoomed in." Before this change, when
new PMs arrived, we would rebuild the list and zoom out
again. Now we track the zoomed_in state with a variable.
Also, if you are zoomed in and switch from one PM narrow
to another, we also keep you zoomed in.
This fix also removes some extraneous/redundant code.
Fixes: #2561
This was intercepting pointer events even though the lightbox was
closed. This fixes the issue with the streams exit not working in some
responsive cases.
Fixes: #2818.
An exception in the webapp was trown when an empty mention was sent.
Examples of problematic messages are "@" or "@****".
In order to fix this, the regex that identifies mentions has been
modified, so it now requires the mention to have a "content" (by
replacing the ? quantifier by +).
A test case has been added to `frontend_tests/node_tests/echo.js` to
check that this works properly in the future.
* Doesn't pop up the warning until you actually try to send the message
* Eliminates the red warning.
* Changes confirm text to "Yes, send".
* Adds a stream size threshhold of 15 people; smaller streams don't
prompt about this.
Fixes#2257.
The image that we are using can be found in the zulip repository
in the directory`static/images/help` named as chat-with-zulip-button.
We use the new button in the readme, and we also provide instructions
on how to embed the button in other sites in the help docs.
Fixes: #2270
In the new stream creation modal, added checkboxes for each stream
and a toggle to see or hide the checkboxes. Altered filtering to
filter streams and users. Added corresponding casper tests.
When a stream is checked/unchecked, it does not affect the state
of any user checkbox. This may be visually unclear as users can be
added even if their checkboxes are empty.
Fixes#2448
This causes Zulip to correctly handle clicks on announcements for
renamed streams.
The stream name that the user typed will still be displayed, which
isn't ideal, but is probably the best we can do without more invasive
rerendering of old messages.
Fixes#426.
This styles inline images, the markdown page as a whole, and the
notification buttons to be CSS rather than images.
[Tweaked by tabbott to temporarily remove the Yantramanov font, since
we should be committing that to the repo so Zulip works correctly without
Internet access]
Previously, this would create a weird blue banner across the top of
the gear menu.
We can't remove it, since it’s required for the gear menu navigation.
Description edited by tabbott.
This commit extracts people.extract_people_from_message()
from message_store.add_message_metadata(), and now
add_message_metadata() extract people before it calls
process_message_for_recent_private_messages(), which
fixes a bug where we are trying to look up an email
for a deactivated user who was in the message but not
in the pre-loaded list of people.
Fixes#2701
This commit changes people.remove() to be people.deactivate(),
and it fixes a bug where deactivating users was causing tracebacks
in the PM list if somebody had PM'ed the deactivated user
recently.
We need this for node tests, so that you don't have to explicitly
remove every user between tests. (Also, people.remove() is about
to have different semantics.)
This adds support for only allowing normal users with account age
equal or greater than a "waiting period" threshold to create streams;
this is useful for open organizations that want new members to
understand the community before creating streams.
If create_stream_by_admins_only setting is set to True, only admin users
were able to create streams. Now normal users with account age greater
or equal than waiting period threshold can also create streams.
Account age is defined as number of days passed since the user had
created his account.
Fixes: #2308.
Tweaked by tabbott to clean up the actual can_create_streams logic and
the tests.
Updated `get_editable()` so that organization admins only see their
own bots in their personal settings page; this removes a lot of
unnecessary clutter.
Fixes#2657.
Before this change, we passed in a hash to get_counts() to
mutate, but now we make the caller responsible for splicing
results into a bigger data structure.
The function now involves no mutation.
This change introduces an unread_topic_counter object
that manages unread counts for streams and topics. Consolidating
all the logic into a single class will set us up to add
logic for dealing with topic counts that includes provisional
counts of unread messages from the server. It also makes
the current code a little easier to reason about.
Most of this change was simply extracting functions, but
I also removed a few unnecessary and inconsistent calls to
`stream_data.canonicalized_name` that preceded our use of
Dict with a fold_case argument.
Django 1.10 uses the correct locales for simplified and traditional
Chinese languages. Previous versions used 'zh_CN' and 'zh_TW'
respectively while now the locales are 'zh_Hans' and 'zh_Hant'. This
commit takes care of this transition by doing the following:
- Add a missing translation zh-hans locale so that our tests pass.
- Add zh_Hans locale directory under 'static'. Case of the local name
is important, if we use 'zh_HANS' then the compiled translations
do not work under certain conditions.
There is a case with browser zoom that the inline-block split view
breaks down and the two 50% tabs fall below each other. This prevents
that issue from happening.
On hover, the transparency of muted stream/topic groups should turn up
to 0.6 so that they are easily readable by people looking to find a
particular stream/topic, but not completely opaque as to be confused
with a non-muted item.
Fixes: #2487.
This is a major change to the /#subscriptions page, converting it to
by a side-by-side list of streams and their settings in an overlay.
There are no new features added/removed, but it's a huge changeset,
because it replaces the old navigation logic and moves the stream
creation modal to appear in the right side of this overlay.
Added new option to download .zuliprc file directly from settings
page. This should help reduce friction when setting up new
bots/integrations. This new feature is available in the bot cards and
the 'show your API key' section. One caveat is that the filename is
automatically set to 'zuliprc' instead of '.zuliprc', since as most
browsers do not allow filenames to start with a dot.
Fixes#2327.
This change adds support for displaying inline open graph previews for
links posted into Zulip.
It is designed to interact correctly with message editing.
This adds the new settings.INLINE_URL_EMBED_PREVIEW setting to control
whether this feature is enabled.
By default, this setting is currently disabled, so that we can burn it
in for a bit before it impacts users more broadly.
Eventually, we may want to make this manageable via a (set of?)
per-realm settings. E.g. I can imagine a realm wanting to be able to
enable/disable it for certain URLs.
- Replace download-zxcvbn with downloading it from npm.
- Change zxcvbn.js path to node_modules (because npm put it to
`node_modules` directory.
- Bump `PROVISION_VERSION` in `version.py` to 2.4.
Fixes#2423.
This can be useful in scenarios where the network doesn't support
websockets. We don't include it in prod_settings_template.py since
it's a very rare setting to need.
Fixes#1528.
The left sidebar will overflow its bounds (even when set to overflow:
hidden) and go behind other text on the sidebar above. By setting the
z-index to 0 we seem to solve the problem.
This is probably actually a webkit bug, but this makes it no longer
affect us.
Fixes#1899.
We now sort users by the lower case value of their
full names in each of the links in the "GROUP PMs"
section of the right sidebar. We still use "+n others"
for big huddles.
We now sort lists of users ids deterministically, and we also
sort list of emails deterministically and without regard to case.
This probably fixes the bug #2343, although I never got a great
repro on that.
The one error that needed to be fixed was in static/js/echo.js.
The function in the loop was being used by _.each(). This has been
replaced by iterating through the array using a while loop instead.
This commit adds a basic eslintrc that emulates jslint defaults.
Rules that conflict with our existing code have been switched to
warnings instead of errors. Globals have been added to the eslintrc. The
bundled js file (generated by webpack) and blueslip.js are ignored with
.eslintignore.
To display warnings, run npm run lint-loud. This runs eslint without the
--quiet option on static/js and frontend_tests.
npm run --silent lint is run by tools/lint-all (in addition to jslint).
The --silent option is used to suppress the default output from npm run.
Fixes#535.
When we filtered buddy lists, a recent change introduced some
bugs related to case-insensitive emails. We now circumvent the
bug by indexing presence_info with user_ids.
If you narrowed to a topic that was not one of the most recent 5
topics and had uppercase characters, it would disappear from the
topic list as soon as all of its messages were read.
If stream names weren't entirely lowercase, then our function
topic_list.is_for_stream() was improperly reporting false and
failing to update unread counts for the active topic widget.
This regression was probably introduced in the fairly recent
53eea250d0 commit.
Fixes#2330.
We now use comma-delimited lists of user_ids for the following
data structures in unread.js:
- unread_privates[<user_ids_string>]
- get_counts.pm_count[<user_ids_string>]
This is more performant, along with accepting a parameter for
filtering only streams that are subscribed to if the toggle is set to
subscribed only.
Also, it now does substring matches, rather than just matching if an
entire word matches the search query.
Fixes#2141.
Previously, this would incorrectly include a user with name and email
"" in the recipients list shown in the local echo code path.
We fix this and add a test for the issue.
This function does the "heavy" lifting of updating an unread
count. (It's not exactly heavy lifting, but it makes it so
the parent just needs to find the outer element of the unread
div, using whatever method makes sense for the parent.)
I forgot to remove this code in a recent refactoring that copied
this code into activity.js. It should not have caused any errors,
but it's no longer needed.
Updates the HTML docs to match changes to the Desk.com website,
including all new screenshots for the custom action workflow.
Tests four types of messages that could be sent as notifications from
Desk.com. Desk.com allows an account administrator to send any text
in a custom action, so there isn't a standard format.
Custom actions send URL-encoded POST data, the test fixtures contain
URL-encoded text like what could be sent by a custom action configured
as described in the Zulip Integrations documentation to post a new
message to a stream. (See also #2169, errors in this documentation.)
New zerver.tests.webhooks.test_deskdotcom.DeskDotComHookTests:
* Static text: minimal plain text string
* Case updated: activity alert with link to a Desk.com case and message
* Unicode text Italian: activity alert with message in Italian
* Unicode text Japanese: activity alert with message in Japanese
Each posts a new message in the deskdotcom stream.
Tested on Ubuntu 14.04. I created the fixtures with Emacs, I would
appreciate if someone can check that the Italian and Japanese messages
look ok. I used the same text for a live test and it displayed correctly.
Fixes#2031
From subs.js we don't redundantly try to remove an element
from ths sidebar; we just trigger the event.
In stream_list.js we continue to remove the element from
the DOM, and we also remove the widget from our internal
Dict of sidebar rows, so that if we re-subscribe, we know
we'll automatically re-build the widget from the template
and the latest data from stream_data.js.
We used to have hacky code where various functions would call
build_stream_sidebar_row() to get a jQuery object, and then they
would attach the jQuery object to the "sub" object from stream_data.js.
Now build_stream_sidebar_row() localizes the hack of attaching
a UI object to the "sub" object to just one function (and we can
clean this up in a follow-up commit).
Also, the UI object is now a JS object that can close on some useful
state information like the stream name and encapsulate how we
toggle the inactive_stream class.
Finally, we don't have build_stream_sidebar_row() needlessly append
list items to $('#stream_filters') when we know that our callers are
going to re-build the list anyway.
The code removed in this commit added pinned streams to a list
of elems, only to have them added again by the next block of code
(but more concisely). Through some strange quirk of appendTo() this
never created user-facing bugs, but you could clearly see in the console
that it was doing double work.
It used to be the case that you would get new messages for a
huddle, but the huddle wouldn't show up on your buddy list until
the every-50-seconds mass update of the buddy list.
Now we make sure to work with non-stale jQuery objects, and,
more importantly, we resize ourselves if we add new huddles.
(The resize issue arises due to some complicated heuristics
where we don't want group PMs to take up too much of the buddy
list for users who don't have many in their history.)
This fixes a bug with the group pm section of our
buddy list. It wasn't updating when you fetched
old private messages.
We had been calling activity.process_loaded_messages() as
part of message_store.do_unread_count_updates(), which was
called sometimes unnecessarily and sometime not called when
we needed to get huddle info.
Now we call it when we need it most, which is when you
click on "Private Messages".
This restyles the message_controls options to center them horizontally
while fixing them closer to the right side of the edge, along with just
replacing the edit button with a preview source button once editing is
disabled.
This moves the edit button to underneath the timestamp such that when
you hover over a message now the timestamp hides itself and the edit
button appears (if editing is allowed).
Fixes#1733 and other annoying issues with this field.
* Fixes handling of multiple stream links and invalid stream names.
* Fixes text regex so it handle hash sign the right way.
* Adds tests for these stream link cases.
Changes editibility type from NONE to FULL, and makes Save and Cancel
buttons work. Exposes a new bug, which is that changing the topic changes
the topic for the recipient row, rather than the message. See #2278.
The widget that gets built in topic_list.build_widget()
now knows how to add itself to its parent element and expose
an interface to retrieve the parent.
For cases where we are zoomed in to a stream and then go
to a different narrow (Home, PMs, etc.), we now let
topic_list.zoom_out orchestrate the removal of the topic list
instead of stream_list.zoom_out.
This will help us when we move to a world where topic_list
redraws topic lists on zoom-in/zoom-out, because we won't
waste effort rebuilding lists that are about to be removed.
The flow for topic list zooming is kind of complicated now, but
it's mostly a consequence of the way the UI works.
* stream_list tells topic_list to set up the topic list
click handlers to have callbacks to stream_list
* topic_list click handlers call to stream_list zoom methods
to hide/show all the other streams
* stream_list zoom methods call back to topic_list methods to
redraw topics as needed (this isn't happening yet, but allowing
topic_list.js to know that it's zoomed will set the stage for
this to happen in a more controlled manner)
We no longer use active_stream_name(), which was mostly a
duplicate of narrow.stream(). For nonsensical queries like
"stream:foo stream:bar" the behavior may change slightly here.
We know that we don't handle non-sensical queries particularly
well, but at least if we always go through narrow.stream(),
the behavior will be consistent.
I did test this with some sensible compound narrows, like searching
for a keyword within a stream.
In 25b28bf82c and then
cb1bc70ab0, we attempted to make long
code blocks scroll in a reasonable fashion, without much success.
This change causes code blocks to be line-wrapped, without needing to
set `overflow-y: hidden` for paragraphs (which cause problems with
taller elements like emoji that overlfowed wrong). Our octopi finally
have legs again.
It's not clear that this is the final answer, but it's the best
version we've found so far.
After adding the ability to add stream links to messages using
the following pattern '#**stream_name**' there was a problem
with rendering this using our markdown engine because '**' means
bold text so that would render just to bold text.
To solve this I had to add regular expression in marked.js to match
that pattern and when it matches I call handleStreamLinks in echo.js
which will correctly render it to HTML.
Fixes#2218.
[tweaked by tabbott to url-encode the stream name in the URL and
adding the missing "#" in the display].