Also adds relevant tests and documentation. We currently
do not narrow to a new topic, and instead just narrow to
the stream. Similarly, we do not narrow to a PM if any of
the recipients are invalid.
We ignore keystrokes like alt-left-arrow and alt-right-arrow,
so that the browser can do back/forward.
We may need to refine the handling of ctrl/alt/shift in the
future, but now we only support single-key operations.
This change removes all the complexity around
get_hash_group(), and we now only go into the
"same overlay" logic within Settings or within
Manage Organization, but not between them.
This means if you're in Settings but hit the back
button to something under "#organization" we now
do "more stuff", since we want to err on the side
of reloading sections, etc.
There's not much flicker in my testing, and
this is not a super common transition, anyway.
Fixes part of #10026.
Adds additional option to typeahead:
`tabOpensEmptyTypeahead`(default: false):
tabOpensEmptyTypeahead overrides helpOnEmptyStrings.
This commit sets helpOnEmptyStrings to false and
tabOpensEmptyTypeahead to true. Now typeahead will
open on an empty string only if Tab has been pressed.
This fixes a bug where hitting the "n" hotkey was
causing double work related to the hashchange system.
The code is now organized like this:
do_open_create_stream() does the GUI piece
We call the above directly for hash changes.
For in-app actions, whether clicks or hotkeys,
we call open_create_stream(), which delegates
most of the work to do_open_create_stream() but
also updates the hash.
We now let color_data keep its own state for
unused_colors, so that we longer have to pass in
a large list of unused_colors every time we want
to assign a new stream color.
This mostly matters at startup, where we might
be cycling through 5000 streams. We claim all
the unused colors up front.
Each operation now has an upper bound of expensiveness,
where the worst case scenario is basically popping
off the first element of a list of <= 24 colors.
The algorithm is now deterministic, too, to make
it easier to test. It's unclear whether random color
assignment ever had much benefit, and it made unit
testing the algorithm difficult. Now we have 100%
line coverage.
Fixes part of #10902.
When there is some error in connecting to server(more specifically to the
tornado server) the "Unable to connect to Zulip" connection error message
gets cleared as Django server could send the response of "get" request of
old messages and hence get_old_messages_success hides the error message
even though the connection is not properly established.
Fixes: #5599.
This commit fixes bug: When user clicks on remove-user-pill-btn,
it closes the parent modal instead of removing user pill from input.
This happens because button has class `exit` and there is click
event listener on all `exit` class buttons, which closes modal.
Fix this by adding `e.stopPropogation` to remove-user-pill listener.
I think this will fix a Casper flake where there was a race
window with multiple temp DOM elements holding copied text.
I also add a comment to the code I think causes this race
for the tests.
For many years we have been excluding the current user
from the buddy list, since their presence is kind
of implicit, and it saves a line of real estate.
This commit removes various user-is-me checks
and puts the user back for the following reasons:
* explicit is better
* newbies will be less confused when they
can see they're actually online
* even long-time users like myself will
feel more comfortable if it's just there
* having yourself in the buddy list facilitates
things like checking your presence or sending
yourself a message
* showing "me" reinforces the meaning of the
green circle (if my circle is green and I'm
active, then others with green circles must
be active too)
* If you're literally the first user in the
realm, you can now see what the buddy list
looks like and try out the chevron menu.
The biggest tradeoff here is the opportunity cost.
For an org with more people than fit on the screen,
we put the Nth person below the fold to show "me".
I think that's fine--users can still scroll or
search.
This commit doesn't do anything special with the
current user in terms of sorting them higher in the
list or giving specific styling.
Fixes#10476
We reduce nesting of code by just early-exiting
for the `is_current_user` check.
This also forces us to be a bit more thorough
with our tests if we want to maintain line
coverage.
For message groups, I just changed the internal name
to "topic_links".
For uses of "subject_links" that are tied to how the
server names fields, I introduced these wrappers:
* util.set_topic_links(obj, topic_links)
* util.get_topic_links(obj)
These can be used for either messages or events.
Previously, when a new stream was created on a client other than the
current one, the browser would first receive the "stream_created"
event, and make up a client-side display color at that time to use in
the "stream settings" view (it doesn't yet know the color that was
selected when the user was actually subscribed, because it doesn't
even know yet that the user is being subscribed to this stream), and
then moments after it'll receive a "susbcribe" event letting the
client know that the user is subscribed (and specifying the color to
use).
However, due to an argument not being passed through properly and a
missing rerender, we were not properly updating either the data
structures or doing a stream colors rerender in order to show the new
color.
This fixes the issue reported in
https://chat.zulip.org/#narrow/stream/48-mobile/subject/stream.20colors/near/660170
Use the placeholder `[Quoting…]` when quoting and replying before the
quote has been added to the message. Also, add tests to the
`compose_actions` Node tests for the new behavior.
Fix#10705.
The "notification settings" page previously advertised support for
mobile push notifications via checkboxes, even if the server hadn't
yet been registered for push notifications. This was a frequent
source of onboarding pain for new Zulip organizations.
We fix this by providing a clear warning and disabling the relevant
inputs on the settings pages.
Modified significantly by tabbott to correct some tricky logic errors
as well as some copy-paste bugs.
Fixes#10331.
This test started failing recently; the apparent cause is that
sometimes, zerver/lib/generate_test_data.py generates messages
containing bulleted lists, and those don't end with a `</p>` tag since
they end with `</ul>` instead; the result is that this test failed
nondeterministically in CI.
There isn't really a useful version of this check to do that would
cover that case (as well as the entire message body being a bulleted
list), so we just remove the check; I don't think it's ever caught any
actual bugs.
We want to avoid `blueslip.error` in cases where
the root cause could just be bad data that is
human-entered.
There are a few callers here who **should** be
sending good data all the time, but hopefully
they either have good test coverage, other
obvious failure symptoms, or, ideally, just
do what the user would mostly expect in the
face of bad data.
Before this change, if you hit ESC, then hotkey
code would call search.clear_search, which would
call narrow.deactivate(), which would then use
`$('#search_query')` to clear a value, but then
let search.clear_search blur the input and
disable the exit button. It was all confusing.
Things are a bit more organized now.
Now the code works like this:
hotkey.process_escape_key
Just call narrow.deactivate.
$('#search_exit').on('click', ...):
Just call narrow.deactivate.
narrow.deactivate:
Just call search.clear_search_form
search.clear_search_form:
Just do simple jquery stuff. Don't
change the entire user's narrow, not
even indirectly!
There's still a two-way interaction between
the narrow.js module and the search.js module,
but in each direction it's a one-liner.
The guiding principle here is that we only
want one top-level API, which is narrow.deactivate,
and that does the whole "kitchen sink" of
clearing searches, closing popovers, switching
in views, etc. And then all the functions it
calls out to tend to have much smaller jobs to
do.
This commit can mostly be considered a refactoring, but the
order of operations changes slightly. Basically, as
soon as you hit ESC or click on the search "X", we
clear the search widget. Most users won't notice
any difference, because we don't have to hit the
server to populate the home view. And it's arguably
an improvement to give more immediate feedback.
If you zoom into "more topics" for a stream that has
a LOT of topics, and then scroll down to the bottom,
and then zoom out by selecting "All messages" or
similar upper-left-sidebar options, we now try to scroll
the more recently active stream back into place after we scroll
out.
Before this change, it was possible for your lower left
sidebar to appear empty, as it would keep the
scroll offset from "more topics".
If our topic list isn't zoomed in, avoid calling
stream_list.zoom_out_topics().
This commit also introduces `zoomed_in` to track
our topic zooming state.
This small modules nicely breaks down the
responsibilities of topic_list and stream_list
when it comes to zooming in and out of topics
(also known as hitting "more topics" or "All
Streams).
Before this, neither module was clearly in
charge, and there were kind of complicated
callback mechanisms. The stream_list code
was asking topic_list to create click handlers
that called back into stream_list.
Now we just topic_zoom set up its own click
handlers and delegate out to the other two
modules.
This fixes a regression from here:
88b4a9f2d7
The fix didn't account for how huddles are
represented as comma-delimited strings.
We also simplify the logic by extracting a
function and doing early-exit for simple
cases.
Internally we generally omit our own id and email
in data structures related to PMs, except when we
are the sender, but if we receive "perma links"
we will need to filter out our id.
This commit exposes the function is_duplicate_full_name()
that can be used to discern if we cannot identify a user
just by their full name in the interface and have to use
his user id as well to distinguish them from other users.
Use the placeholder `[uploading file]()` when uploading before the
upload has completed. This behavior prevents an image from being
improperly placed when typing after starting an upload. This is based
on GitHub's handling of image uploading.
Also, add tests to the `upload` Node tests and update existing tests to
account for the new behavior.
Fix#10305.
Also use name for selecting form in casper tests
as form with action=new is present in both /new
and /accounts/new/send_confirm/ which breaks
test in CircleCI as
waitWhileVisible('form[action^="/new/"]) never stops
waiting.
In commit c293bb82c4 we changed
id_realm_invite_by_admins_only and realm_invite_required checkboxes to a
single dropdown so these lines are redundant now.
This commit add FIELD_TYPE_CHOICES_DICT to page_params and replace
FIELD_TYPE_CHOICES.
FIELD_TYPE_CHOICES_DICT includes all field types with keyword, id
and display name. Using this field-type-dict, we can access field
type information by it's keyword, and remove all static use of
field-type'a name or id in frontend.
This commit also modifies functions in js where this page_params
field-types is used.
Hide `delete-btn` of first choice in create-new-custom-field and
edit-choice-type-field form, so user can not delete all choices
and have to submit at least one choice.
This commit remove this logic of choice-field-delete-btn from
both settings.
This is preparatory commit of adding new logic in `delete-btn`.
Fixes#10124.
Users in the waiting period category cannot subscribe other users to
a stream. When a user tries to mention another unsubscribed user, a
warning message appears with a subscribe button on it to subscribe
the other user.
This commit removes the subscribe button and changes the warning text
for users in the waiting period category.
Instead of displaying a fixed error message inside the yellow bar itself,
now the yellow bar disappears on error and a red compose_error is shown.
The error message is the one returned from the server.
If a user is narrowed by `is:private`, `pm-with`, or `group-pm-with`,
change the `New topic` button to say `New stream message` instead for
added clarity.
Also, add to the Casper and Node tests for this behavior.
Fix#9072.
This commit fixes two issues with the previous implementation:
1. JavaScript's replace replaces only the first instance,
thus we need to use a regex.
2. Handlebars was setting the id of the HTML elements with
spaces in between which broke the delete button; now a
new variable display_name is passed to the template.
This also makes changes to the casper tests to have an emoji
name with multiple spaces in it to ensure this bug doesn't
appear again.
When visiting a narrow like
https://chat.zulip.org/#narrow/stream/doesnotexist, grey-out the reply
button and add the title `There are no messages to reply to.`
Also, add to the tests for `narrow.js` with
`#left_bar_compose_reply_button_big`.
Fix#8547.
We move remove_deactivated_user_from_all_streams
into stream_events.js. There were some minor changes
to rename variables and also to not rely on using
`stream_info`.
This allows several modules to no longer need
to import `narrow` (or, in our current pre-import
world, to not have to use that global).
The broken dependencies are reflected in the node
tests, which should now run slightly faster.
All of our data related to emojis is in emoji.js.
Now typeahead_helper no longer depends on emoji_picker.
Generally we want typeahead_helper to only depend
on data modules to avoid complicated circular
dependencies (or at least mitigate them).
This is part of work to break some of our
nastier circular dependencies in preparation
for our es6 migration.
This commit should facilitate loading leaf-like
modules such as people.js before all of the things
that reload.js depends on.
When you unsubscribe a stream by clicking on the
checkmark, we don't want it to disappear right
away, but we also don't need it to stay around
once you start searching for new streams.
Note from Tim: This commit removes some complex code that was just a
workaround for the fact that this widget used to automatically
re-filter immediately after clicking to unsubscribe a user.
Since we've since fixed that original issue, we don't need this.
We add a padded div to our container for the buddy
list to give scrolling the illusion that we've
rendered every list item, while still letting
the browser do the heavy lifting instead of trying
to fake it out too much.
This new div allows us to split out two concerns:
semantic list of items - remains in #user_presences
widget real estate - controlled by new #buddy_list_wrapper
We will use this for progressive rendering. We want to add
padding to the buddy list without messing with the integrity
of the actual HTML '<ul>' list. (One ugly alternative would
have been to add a dummy list item, which be a pitfall for
any code traversing the list.)
Basically, all the code relating to click handlers and similar
things was left alone. We only change js/css related to
scrolling, resizing, and overflow.
This version of progressive scrolling lazily
renders buddy list items, but it doesn't
provide the browser with any notion of upcoming
list items, so as you scroll down and the size
of the rendered list grows, the scrollbar shows
you being too close to the bottom.
This maintains 100% coverage on buddy_list.js.
In 47aaa73f96, we fixed one issue, which
is that server_events_dispatch.js was calling `update_starred` with
the wrong arguments, but created a new one (toggle_starred wasn't
updated) and missed another (which is that we weren't ever updating
message.starred, and thus if you toggle a message's star-state in one
browser, and then tried to toggle it back in a second, it would feel
like the click didn't work, because it was trying to toggle
e.g. off->on a second time).
This was supposed to be suppressed when a reload is in progress,
however, the logic was accidentally checking that
reload.is_in_progress was a defined function, not whether a reload was
actually in progress.
There was previously a race condition where reload.is_in_progress was
set after `activity.js` sent the presence request to the server, but
before we process the response; in that race condition, we still
shouldn't send blueslip errors to the server.
This renames Realm.restricted_to_domain field to
emails_restricted_to_domains, for greater clarity as to what it does
just from seeing the setting name, without having to look it up.
Fixes part of #10042.
We probably should have done this a while ago, even
though these functions are pretty tiny. The goal here
is to make it easier to have more consistent search
semantics.
Our first use case is subs.js. In this case we
are able to decouple a bit of generic string
matching from the subs-specific code.
We move some data code from subs.js to stream_data.js.
It's not clear we have been using the optimal sort for
dealing with locales, but this change preserves the
current behavior. The only subtle change here is that
we look up subs using a Dict now instead of a plain
JS object.
We now render the "skin" part of "Stream Settings" before
adding in the actual streams. The new function
populate_stream_settings_left_panel() takes care of adding
the streams. It uses a new template called
`subscriptions.handlebars`.
Splitting out this function will give us more flexibility
for various improvements.
First, we can decide to render the list after we open the
overlay, just to avoid the problem that users don't know why
the modal's opening. (And we could add a loader spinner as
needed.)
Second, we can improve our filter features so that we do
filtering in the data instead of moving DOM rows around,
which is expensive.
Third, we can eventually introduce progressive rendering.
Finally, having the function broken out will make profiling
more precise about where bottlenecks exist.
We were passing this in before, but having it as
a data member reinforces the idea that we'll want
this to be a first-class concept in the list, since
we depend on ordering for various things.
We now keep track of keys in buddy_list.js, so that
when we insert/remove items, we no longer need to
traverse all the DOM. Instead, we just find out
which position in the list we need to insert the
key in (where "key" is "user_id") and then find
the relevant DOM node directly and insert the new
HTML before that node. (And of course we still
account for the "append" case.)
There's a little more bookkeeping to make this
happen, but it should help reduce some code in
upcoming commits and pave the way toward
progressive rendering optimizations.
This commit should produce a minor speedup
for activity-related events that go through
buddy_list.insert_or_move(), since we are
not traversing the DOM to find insertion points
any more.
Typing "tim " did not did not produce any match when suggesting person
in composebox typeahead or user group typeahead as the space at the
end of the "tim " string passed by the browser was a
`no break-space (U+00A0)` instead of `space (U+0020)`.
Although there are unicode characters other than `no break-space` which
represent spaces, only U+00A0 is replaced as it was the only space
character encountered when testing this issue manually.
Fixes#10039.
To reduce code duplication when creating hotkey deprecation notices,
create the `get_hotkey_deprecation_notice` function. Also, create a
`ui` testing file with a test for the new function.
Fix#10004.
This replaces some old code with calls to topic_data.js.
Now our topic typeahead uses the same data as our
sidebar, stream suggestions, and the "n" key, so any
future improvements to that data will benefit all
features the same.
This is an important piece of #9857.
Now that `emoji_collection` and `emojis_by_name` are global
datasources in the webapp we need to rename things carefully
to reflect their actual meaning. The fact that emoji code is
used as a css class for unicode emoji is one thing but it is
not its sole use so renaming it seems a good idea.
This commit moves the `emoji_collection` datasource in the emoji
picker to emoji.js and renames it to `emojis_by_name`. It is a
mapping from emoji name to object where each object describes an
emoji. This is an effort in the direction of de-duplicating and
unifying the datasets being used by various our widgets(like
emoji picker and composebox typeahead) in the webapp. Migrating
all the widgets to a single datasource will help us in removing
the whole class of annoying bugs which causes some emojis to be
missing from some widgets.
This commit closes a long pending issue which involved moving the
`EMOTICON_CONVERSION` mapping to build_emoji infrastructure so
that there is only one source of truth. This was pending from the
time when this feature was implemented.
If search pills are not enabled, the text present in the search bar
will be selected on pressing '/' and writing someting without deselecting
the text will clear the search text. Since selecting the pills would
not make sense in this context, the search box is focused instead.
Adds box-shadow to `#searchbox` when either `#search_query` or any
of the pills have focus. Uses jquery instead of pure css as the
`:focus` event occurs on `#search_query`, while we want to add
box-shadow to `#searchbox`. This could have been done with
`:focus-within` CSS selector, but it is not supported in IE or Opera.
`#search_query` already had an onfocus/focusout listener, adding
listeners to `#searchbox.pills` for those events wouldn't have worked
as you don't want the focusout event to fire when the focus shifts
from input to pill.
Also adds `focusin`, `focusout` and `css()` to zjquery. `css` is
same as `val`, except it returns an empty object in case of no value
instead of an empty string. I don't think `css()` is valid syntax
in actual jquery.
After adding search pills, suggestions were based only on the
current input and no validation against the existing pills was done.
operator_subset_suggestions have been removed. Default suggestions
for base_operators have also been removed.
Handle multiple operators:
if `is:starred stream:Ver` was typed without selecting the typeahead
or pressing enter in between i.e search pill for is:starred has not yet
been added, then the description of `is:starred` will act as a prefix
in every suggestion.
Also makes changes re-enabling person suggestions for names with spaces.
This large function will need to be modified significantly as part of
the pills effort, and copying it lets us preserve behavior in
production until we're ready to cut things over.
tab_bar.js becomes redundant after implementation of search pills.
This commit adds a comment to tab_bar.initiliaze, so the event
listeners related to it do not get initiated. This does not remove
any code related to tab_bar.js.
Also adds left and right border around the search icon.
Following points have been implemented in this commit:
1.) Add search pill on selecting typeahead.
2.) Re-narrow after removing a search pill.
3.) Add quiet optional parameter to removeLastPill.
4.) Pre populate search pills in narrow.activate.
5.) Clear existing search pills on narrow.deactivate.
Description of above points:
1.) I tried out using the description from suggestions.lookup_table
to append a pill using appendValidatedData so that the description
had not to be calculated again. But the description in the suggestions
lookup contains html due to highlighting. This html is escaped when
inputed in a pill. An attempt was also made to remove the higlighting
by replacing the tags. But other espaced characters like < also
popped up, so it was better to use append_search_string.
3.) If one wants to refresh the pill using pill.clear and wants to
repopulate them, evaluating the event_handler associated with the
action of removing the pill may not be desired.
4.) Pill population code is added to narrow.activate. Pills are not
populated if the narrow was triggered by search as search handles the
addition and removal of pill by itself. The reason for not handling
search too in narrow.activate is to avoid clearing the pills and
repopulating them. Example of some of the triggers for narrow.activate
include `restore draft`, `topic change`,`sidebar`.
Also modifies tests for search.js
This forks off search_legacy.js and search_suggestion_legacy.js so
that we can continue running automated tests against the legacy search
code while we develop the input pills feature.
This commit updates the `emoji-datasource` packages to version 4.0.4.
This update brings following changes to emoji infra:
1: Fix for the bleeding sprite sheets.
2: The category of some emojis has been changed. Categorywise breakup of
net gain or loss is as follows:
Travel & Places: 58 (gain)
Symbols: 47 (loss)
Smileys & People: 52 (gain)
Objects: 11 (loss)
Food & Drink: 3 (gain)
Animals and Nature: 46 (gain)
Activities: 9 (loss)
3: There were some changes in the image farm of the package which were
breaking our old emoji farm. I fixed them by modifying the remapped
emoji map.
Fixes: #8235.
Previous commits have fully implemented the logic for stream email
notifications; this final commit adds support for configuring it to
the UI.
Fixes#6511.
This migrates Zulip to use a dramatically better set of names and
aliases for our emoji set, defined in emoji_names.py (which is in turn
manually generated from our hand-curated CSV file).
This should significantly improve the experience of using Zulip's
emoji picker and emoji typeahead for finding what one is looking for.
These were resulting in inadvertant calls to blueslip.fatal but
the code continued beyond that point, since in our testing environment
we do not stop executing when fatal is called.
This commit also adds checks to ensure that the subs were created.
Fixes#9842.
Enables avatar images in pills wherever user_pill.js is used.
(e.g composebox, user group settings)
Changes to search_pill.js are not made as search pills haven't been
added yet completely and search_pill.js just contains the preparatory
code right now.
No change to compose_pm_pill.js is not required as it uses
`user_pill.create_item_from_text` in its `create` function.
Allow passing image link in the item passed to appendValidatedData.
When passing image link via any of the append* functions, make sure
that create_item_from_text for that pill also adds the image link to
the item created.
This commit does not make any visual change to the current app.
Changes to user_pill.js are necessary to enable user avatars for
pills.
We now use narrow_state.filter() everywhere. The
two functions did the same thing, and I slightly
prefer the concise name, which was already in use
in lots of places.
This implements right-to-left message automatic detection support in
the compose box as well as the message feed. Full unit tests and
support in the message-editing UI are for future work (as are
potentially more fancy things like supporting things like
right-to-left multi-word names for users/streams/etc.).
Fixes#3123.
The reason to add this api is that many times some elements are
already used/cached and then their value interfere/exists in
other tests which gives false results.
This was killed when the "Deleted Streams" feature was dropped
in commit 7bbe44d7 but we forgot to deal with it at the time.
squash to admin_streams_list
Fixes#9797.
Clicking on the unread count badge on the right sidebar did not
narrow the selected pm/group-pm. This commit moves the count div
inside selectable_sidebar_block. Also uses flexbox instead of
inline-blocks for user presences selectable_sidebar_block.
This disables `ctrl + shift + [`, while `ctrl + [` will still trigger
an action.
Also, add a test for ensuring that the `ctrl + shift` combinations fall
through.
This disables `cmd-or-ctrl + shift + k` and `cmd-or-ctrl + shift + s`,
while `cmd-or-ctrl + k` and `cmd-or-ctrl + s` will still trigger
actions.
Also, add tests for ensuring that the `cmd-or-ctrl + shift`
combinations fall through.
Fix#9779.
Adds search_pill.js to the static asset pipeline. The items
for search pill contain 2 keys, display_value and search_string.
Adding all the operator information i.e the operator, operand and
negated fields along with the search_string and description was tried out.
It was dropped because it didn't provide any advantage as one had to
always calculate the search_string and the description from the operator.
This makes sure that CSRF token is available while initializing
Socket, irrespective of the order of execution of deferred callbacks
after document becomes ready.
This is part of #9416.