* 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.
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 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.
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.
- 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.
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.
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.
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].
We now use stream_id as our key to rename streams, which
should prevent a few race conditions long term. (We are
still possibly contending with other events that use
stream_name as a key, so this is not perfect.)
If I try to send a message to an unknown user (which is possible
for some types of realms), then I simply ignore them during the
send codepath, so that I don't later need to patch up their attributes.
We no longer store pm_recipient_count on person objects, but we
instead use a Dict to store them. Then the new API is this:
people.get_recipient_count()
people.incr_recipient_count()
We now send dictionaries for cross-realm bots. This led to the
following changes:
* Create get_cross_realm_dicts() in actions.py.
* Rename the page_params field to cross_realm_bots.
* Fix some back end tests.
* Add cross_realm_dict to people.js.
* Call people.add for cross-realm bots (if they are not already part of the realm).
* Remove hack to add in feedback@zulip.com on the client side.
* Add people.is_cross_realm_email() and use it in compose.js.
* Remove util.string_in_list_case_insensitive().
This alert bar thing was buggy and didn't look that good, so let's
just remove it. We can always write a nicer thing advertising the
desktop app later.
Currently, message_edit.edit_message accesses elements of
message_edit_form.handlebars by a number of different means, and in a number
of different places. This commit is the first of two that standardizes it.
Previously we disabled fields in message_edit_form.handlebars that you
couldn't edit. This meant you could see the content of the field, but not
copy it. This commit marks those fields as readonly instead.
Previously,
* We displayed "(no topic)" in .message_edit_topic when there was no
topic;this commit changes that to a placeholder.
* We showed the .message_edit_topic_propagate dropdown when the user
cleared .message_edit_topic, despite the fact that one cannot save
or propagate an empty topic. This commit fixes the behavior.
Fixes#1273.
This change makes most of the logic on set_count() live
on our per-stream topic list widget. We can find the
jQuery object directly now rather than using the
complicated iterate_to_find() method.
We don't want to prepend new subscribers to our list of
subscribers in the settings page when they hit enter; we
want to wait till we get the event from the server.
This is a fairly new regression that was added when we
live-updated peer subscriber changes.
This fixes and issue where the change_stream_privacy template had its
own duplicate copy of the data-stream-name attribute, which wasn't
updated when streams were renamed.
Fixes#2016.
This also brought along:
iterate_to_find (copied, see large comment explaining why)
activate_topic (extracted from a one-liner)
set_count (formerly stream_list.set_subject_count)
For get_topic_filter_li, we now pass in stream_li instead of
stream to decouple parent/child responsibilities between the
components.
Also, I made some s/subject/topic/ fixes.
This creates the new topic_list.js module, and the first
function that we extract is topic_list.update_count_in_dom().
This function needed to be decoupled from some non-topic-list
stuff which was overly complicated.
I make server_events slimmer by not handling a specific
property when subs.update_subscription_properties() should
do all the dispatching (and mostly did).
And then since update_subscription_properties() has
a "sub" already, I can call directly to stream_list code
and remove a function from subs.js. Since I lose the
wrapper function in subs.js, I rename the stream_list
function as part of this commit.
The only code that gets slightly heavier here is that
we have two lines in the 'pin_to_top' case instead of one.
All of the eventual callers to prepend_subscribers()
and format_member_list_elem() call people.get_by_email()
anyway, so now we do it one place. The one exception
was using page_params.fullname, which is awkwardly
different than what we call that variable elsewhere
(fullname vs. full_name).
Previously, all of the callers of message_edit.save() would check if
it returned true, and if so, call message_edit.end(). This resulted
in various bugs in the past, so we switch to the much cleaner model of
just calling .end() inside .save().
message_edit_form.handlebars already has a message_edit_topic that
refers to the topic edit section of message editing, and this made
things very confusing.
This fixes the following issues:
1. Photos are no longer resized larger than their native resolution.
2. Photos with transparency now have a checkerboard behind them to
signal an alpha of less than one.