This commit was automatically generated by `tools/lint --only=eslint
--fix`, after an `.eslintrc.json` change.
A half dozen files were removed from the changes by tabbott pending
further work to ensure we avoid breaking valuable PRs with merge
conflicts.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Hovering over user names (and user circles for PM List) now displays
Name, Status Message and Last online time in a js tooltip.
Hovering over group names displays the names of all group members.
Unavailable users are shown as "Last active: Today".
Hovering on a user circle in the Buddy List results in a js tooltip
with Active/Idle/Offline/Unavailable for
green/orange/white/white-with-line.
Resolves#11607.
When strings are tagged for translation using `tr this`, the strings
were passed into the frontend i18n as-is (including new line and tab
characters that are not functional in the text, existing just to
format the HTML files reasonably).
This did not match the algorithm used in `manage.py makemessages` for
extracting strings for translation, which (correctly) removed that
whitespace to provide a good experience for translators. The fix is
for the `tr this` implementation to use that same whitespace-stripping
algorithm.
Tested manually by checking if those strings that were not translated
earlier were translated, and also fixed an automated test that had the
wrong result, which should help prevent regressions.
Fixes#13389.
ES6 and TS modules don’t insert themselves into `window`, so our tests
shouldn’t insert them either. Since the test `window` behaves like
`global` now, we can rely on legacy modules that do insert themselves
to do it themselves.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
These should work consistently with how the individual user setting
works; see the last commit.
With changes from tabbott to fix real-time sync.
Fixes#12553.
This commit was originally automatically generated using `tools/lint
--only=eslint --fix`. It was then modified by tabbott to contain only
changes to a set of files that are unlikely to result in significant
merge conflicts with any open pull request, excluding about 20 files.
His plan is to merge the remaining changes with more precise care,
potentially involving merging parts of conflicting pull requests
before running the `eslint --fix` operation.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Because of the separate declarations, ESLint would convert them to
`let` and then trigger the `prefer-const` error.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Even though this variable was only assigned once, it was accessed
before its initialization, so it couldn’t be converted directly to
`let` or `const`. Use `let` with an explicit `null` to make it
clearer what’s going on and satisfy ESLint. (Why not `undefined`?
There’s an ESLint rule against that too.)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This feels a bit more semantically appropriate: it more clearly says
"here's some information: there is no (relevant) recipient", rather
than "no information available". (Both `null` and `undefined` in JS
can have either meaning, but `undefined` especially commonly means
the latter.)
Concretely, it ensures a bit more explicitness where the value
originates: a bare `return;` becomes `return null;`, reflecting the
fact that it is returning a quite informative value.
Also make the implementation more explicit about what's expected here,
replacing truthiness tests with `!== null`. (A bit more idiomatic
would be `!= null`, which is equivalent when the value is well-typed
and a bit more robust to ill-typing bugs. But lint complains about
that version.)
It'd already been the case for some while that calling `stop` had the
same effect as calling `update` (previously `handle_text_input`) with
a falsy recipient. With the API changes in the previous few commits,
this becomes quite natural to make explicit in the API.
This was named after when it gets called from the UI, rather than
after what it can be expected to do.
Naming it after what it's meant to do -- and giving a summary line to
expand on that -- provides a more helpful semantic idea for reasoning
about the function. Doubly so for using the function in a different
client with its own UI, like the mobile app.
The main motivation for this change is to simplify this interface
and make it easier to reason about.
The case where it affects the behavior is when
is_valid_conversation() returns false, while current_recipient
and get_recipient() agree on some truthy value.
This means the message-content textarea is empty -- in fact the
user just cleared it, because we got here from an input event on
it -- but the compose box is still open to some PM thread that we
have a typing notification still outstanding for.
The old behavior is that in this situation we would ignore the
fact that the content was empty, and go ahead and prolong the
typing notification, by updating our timer and possibly sending a
"still typing" notice.
This contrasts with the behavior (both old and new) in the case
where the content is empty and we *don't* already have an
outstanding typing notification, or we have one to some other
thread. In that case, we cancel any existing notification and
don't start a new one, exactly as if `stop` were called
(e.g. because the user closed the compose box.)
The new behavior is that we always treat clearing the input as
"stopped typing": not only in those cases where we already did,
but also in the case where we still have the same recipients.
(Which seems like probably the common case.)
That seems like the preferable behavior; indeed it's hard to see
the point of the "compose_empty" logic if restricted to the other
cases. It also makes the interface simpler.
Those two properties don't seem like a coincidence, either: the
complicated interface made it difficult to unpack exactly what
logic we actually had, which made it easy for surprising wrinkles
to hang out indefinitely.
All these cases are meant to simulate having a user actually typing a
message to some actual recipients, so the `conversation_is_valid`
parameter would be true.
We make this change so that in an upcoming change that eliminates this
parameter, the adjustments to the test cases can be highly regular and
we don't have to introduce a new wrinkle to correspond to these values
being false.
The real purpose these two callbacks serve is exactly what an ordinary
parameter is perfect for:
* Each has just one call site, at the top of the function.
* They're not done for side effects; the point is what they return.
* The function doesn't pass them any arguments of its own, or
otherwise express any internal knowledge that doesn't just as
properly belong to its caller.
So, push the calls to these callbacks up into the function's caller,
and pass in the data they return instead.
This greatly simplifies the interface of `handle_text_input` and of
`typing_status` in general.
Users generally don't expect wildcard mentions in muted streams and
topics to be treated as a mention, either for the purposes of desktop
notifications or the unread mention counts.
This fixes the unread mention counts part of the issue.
Fixes part of #13073.
This adds the general machinery required, and sets it up for the file
`typing_status.js` as a first use case.
Co-authored-by: Anders Kaseorg <anders@zulipchat.com>
When a user performs a search that might contain historical public
streams messages that the user has access to (but doesn't because
we're searching the user's own personal history), we add a notice
above the first search result to let the user know that not all
messages may have been searched.
Fixes#12036.
This ensures that typing '```java' and pressing enter would result in
getting dropped into a java codeblock instead of javascript codeblock.
We implement this by pushing the exact match of a query to be pushed to
the top of the returned matches in `sort_languages`.
With some comments added by tabbott in the tests explaining the
current reasoning.
Fixes#13109.
This changes the availability icon for bot users to user_circle_green;
previously it was accidentally defaulting to user_circle_empty, making
it appear that bots were never available.
Fixes#13149.
As it turns out, our rerender_the_whole_thing function (used whenever
we were adding messages and discovered that the resulting message list
would be out-of-order) was just broken and scrolled the browser to a
random location.
This caused two user-facing bugs:
* On very fast networks, if two users sent messages at very close to
the same time, we could end up with out-of-order message deliveries,
triggering this code path, which was intended to silently correct
the situation, but failed.
* In some narrows to streams with muted topics in the history but some
recent traffic, the user's browser-cached history might have some
gaps that mean the server fetch we do after narrowing discovers the
history is out-of-order, again triggering the
rerender_the_whole_thing code path.
The fix is to just remove that function, adding a new option to the
well-tested rerender_preserving_scrolltop (which has explicit logic to
preserve the scroll position) instead.
Fixes#12067. Likely also fixes#12498.
This brings us in line, and also allows us to style these more like
unordered lists, which is visually more appealing.
On the backend, we now use the default list blockprocessor + sane list
extension of python-markdown to get proper list markup; on the
frontend, we mostly return to upstream's code as they have followed
CommonMark on this issue.
Using <ol> here necessarily removes the behaviour of not renumbering
on lists written like 3, 4, 7; hopefully users will be OK with the
change.
Fixes#12822.
Fixes#13134 as the last commit in the series for this issue.
Solves the "The (?) should just be a target=_blank link to
/help/message-a-stream-by-email." part of the issue.
As a result, a bunch code managing the email hint popup can be deleted,
together with a node test for that.
There was a bug where the success banner stuck
around even after the export completed. We now
nicely fade and remove the banner upon a successful
population of the export in the table.
Fixes: #13045
Add ability to search entire message history of all public streams at
once. It includes all subscibed, non subscribed public streams messages
and even historical public stream messages sent before user had joined
an organization or stream.
Fixes#8859.
If a user was active within the last 90 days,
show number of days (23 Days ago).
If the user was active more than 90 days ago and in the same year,
then show MMM DD (Mar 15).
In any other case show MMM DD YYYY (Nov 10 2018),
Change timerender.js test to accomodate changes.
Delete trailing newlines from all files, except
tools/ci/success-http-headers.txt and tools/setup/dev-motd, where they
are significant, and static/third, where we want to stay close to
upstream.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This reverts commit 76e50af78e.
Empirically, this caused weird issues with the cursor jumping around,
so more investigation is required into the right way to fix it.
Although SimpleBar automatically sets itself up on elements with a
`data-simplebar` attribute, sometimes we try to set event listeners
before that happens. Create the SimpleBar early in that case.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
When you press enter on a typeahead and start typing, your cursor is
placed at the end of the textbox, whereas we want it to be placed at
the end of the typeahead immediately. This causes some characters to
appear at the end of the message before you again get to typing from
where you left off.
To fix, we use the change event triggered on typeahead completion to
reposition the cursor instead of using a setTimeout().
Fixes#12621.
We implement 3 changes:
1. Partial Stream Typeahead
In addition to regular stream completion, we do partial completion
of stream typeahead on pressing '>'. We use our custom addition to
typeahead.js: this.trigger_selection to start topic_list typeahead.
Implements: `#stream na|` (press >) => `#**stream name>|`.
2. Topic Jump Typeahead
'topic_jump' typeahead moves the cursor from just ahead of a
completed stream-mention to just after the end of the mention
text and is triggered by typing '>' after the stream mention.
This typeahead merely uses the regex matching and event hooks of
the typeahead library instead of displaying any text completions.
Implements: `#**stream name** >|` => `#**stream name>|`.
3. Topic List Typeahead
'topic_list' typeahead shows the list of recent topics of a stream
and if your current text doesn't match one of them, also shows you
the current query text, allowing you to create mentions for topics
that do not exist yet.
Implements: `#**stream name>someth|` => `#**stream name>something** |`.
At the end of this commit, we support the following mechanisms to
complete the stream-topic mention:
1. Type "#denmar|".
2. Press Enter to get "#**Denmark** |".
3. Press > to get "#**Denmark>|".
4. Type topic name and press enter.
OR
1. Type "#denmar|".
2. Type > to get "#**Denmark>|".
3. Type topic name and press enter.
Both result in the final inserted syntax: "#**Denmark>topic name**".
Documentation is still pending.
Fixes#4836.
In this refactor, we extract two functions in unread.js. Which one to
use depends on whether res has already been fetched or not.
This also adds node tests to maintain coverage of unread.js.
Tweaked by tabbott for cleaner variable names and tests.
This change is long overdue. After implementing this much more robust
system and deploying it on chat.zulip.org, we hesitated to make
load_server_counts the default behavior in master, because of data
anomalies present for many existing users (basically messages far back
in their history that they had never read, on streams they believed
themselves caught up on), which would have been confusing for many
users.
However, because the mobile apps have been using this data set for a
long time, we've likely cleared out the anomalies from active users'
data set. And for older users, they're going to come back to
approximately infinite unread messages anyway, so the data anomalies
are unlikely to be important.
Fixes#7096.
This icon should only show when the user is not an admin and either the
realm or server settings have disabled name changes. Previously the icon
always showed for admin users.
The count_span element is parented by a .selectable_sidebar_block element
which is parented by the li element that the class is supposed to be added
to. Thus, use the parents() jQuery method for locating the li parent so
that the class gets added to the correct element.
This commit adds a new setting to the user's notification settings that
will change the behaviour of the unread count in the title bar and
desktop application.
When enabled, the title bar will show the count of unread private messages
and mentions. When disabled, the title bar will act as before, showing
the total number of unread messages.
Fixes#1736.
The approach taken here is basically use user IDs in operator that
support it when sending the request for fetching the messages
(see comments in code for more details).
Combined with work in the desktop app, this makes it possible for the
desktop app to clearly indicate to other users whether the current
user is active on the system and thus would see a desktop
notification, not just whether they are active in the current Zulip
window.
Essentially rewritten by tabbott to add unit tests and consider the
desktop app data authoritative.
Add new custom profile field type, External account.
External account field links user's social media
profile with account. e.g. GitHub, Twitter, etc.
Fixes part of #12302
Not all our errors actually happen in the contexts we were
wrapping (e.g. `setTimeout` and `_.throttle`). Also this fixes the
neat Firefox inspector feature that shows you where your event
handlers for a given DOM element actually live.
Using this "semi-modern" browser event means that Safari 9 and older
and IE10 and older may not have our browser error reporting active;
that seems fine giving the vanishing market share of those browsers.
https://blog.sentry.io/2016/01/04/client-javascript-reporting-window-onerror
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
The comment that jQuery “doesn’t have” this was nonsense: jQuery
supports every event the browser does.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
After migration to an ES6 module, `suppress_unread_counts` would no
longer be mutable from outside the module.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
After migration to an ES6 module, `server_furthest_read` would no
longer be mutable from outside the module.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Fix the .get_suggestions and .get_suggestions_legacy
to correctly handle search terms in group PM and treat
it as search term by not concatenating it at end of pm-with
email list operand.
We reuse the link regexes we use elsewhere inn markdown
for parsing links in topic names and add a button to open
them in new tabs similar to our behavior with linkifiers
in topic names.
Fixes#12391.
Right now we have buttons for "New conversation" and "New private message"
in different views, but both buttons do the same thing.
The current state is confusing for new users, since there is already a lot
of terminology one needs to learn in order to understand the Zulip
conversation model. It's very plausible a user would think a "conversation"
is something different from a "private message" or a "topic".
With the help of `check_property_changed` function now we collect the data
whose values are changed from the current one. Currently this optimizes
only for those elements whose values are collected by
`populate_data_for_request` function i.e. it doesn't optimize data
collected by `get_complete_data_for_subsection`.
This is a preliminary commit which refactors `populate_data_for_request`
function, now this function traverse on all "property elements" of a given
subsection, but get the data only of those properties which have
`setting-widget-type` data attribute. Therefore, it doesn't change the
functionality of this function and overall changes don't make any
difference. In upcoming commits, we're going to use `input_elem` as an
argument to `check_property_changed` function, so that only those elements
whose values are changed are sent to the backend.
This commit disables "Mobile notifications" if `push_notifications` are not
enabled. It also adds a tooltip explaining why this is disabled.
Fixes#12208
Add `name` attribute to stream settings `input` elements
and change `id` attribute corresponding to name.
`name` attribute stores value of settings name which is
stored in frontend data sets.
Some search queries always return empty because of how we handle search,
this adds text that ensures users trying bad searches realize that they
are doing so.
This fixes an issue where one could end up with a `(` in the markdown
syntax for a link after copy-pasting this, which doesn't work in
markdown.
Fixes#12579.
Rename notification property `enable_stream_sounds` to
`enable_stream_audible_notifications` to match with other
notification property patterns.
Fixes part of #12304
Prior to this commit, we'd put up the green "Enable desktop
notifications" bar on page load AND the first time a desktop
notification worthy message was received, it would attempt to notify,
automatically triggering a browser permission popup (the same one as
clicking the green bar results in).
Now, desktop notifications are not attempted at all until the green
bar is clicked. Additionally Firefox and Webkit browser-specific
checks are made more uniform and done at the same point.
Tested written by YashRE42.
Fixes#11504.
This tests was added to make sure we catch subtle bug related to
comparing new_recipient and current_recipient. When we changed the
recipient to use arrays instead of string to use new user IDs based
api we encoured this bug and out testing suite couldn't detect this.
API changes:
* The behaviour of Date.toLocaleTimeString() reverts to pre 8.0.0,
this only affects automated tests. Lots of other API changes but
we didn't use any of those.
* The internal sorting algorithm changed which causes one of our own
compare function to miss coverage.
This adds a setting to control Zulip's default behavior of sorting to
bottom and graying out inactive streams. The previous logic is still
the default "automatic", but this gives users more control. See the
models.py comment for details.
Fixes#11524.
We have had a longtime bug where the state of pinned streams would not
update properly from the greyed out/inactive state to the active state
when a first message arrived to them.
After some discussion, we determined that likely the right fix for
this is to simply configure pinned streams to never be marked as
inactive; that's more in line with the intended user experience.
Fixes#8201.
Lightbox previews for youtube playlists use the "current" video in the playlist
for the preview. The open link for such previews is incorrectly set to the first
video alone, and not the playlist. This commit fixes the bug by linking to the
original URL for lightbox preview is being shown, instead of computing the URL.
This commit separates the `waiting_period_threshold` setting from
the `create_stream_policy` setting, adding a new setting that the user
can use to select a waiting period threshold.
Both the invite to stream policy and create stream policy now have
three options: admins only, members and admins, or members after
waiting period/admins.
In email hidden case (that is when `email_address_visibilty` is set to
everyone), for "non admins", this commit hides emails from:
- compose box user typeahead.
- PM user typeahead
In email hidden case, for admins, email is shown in user typeaheads.
In email hidden case (that is when `email_address_visibilty` is set to
everyone), for "non admins", this commit hides emails from:
- user popover
- custom profile popover
In email hidden case, for admins, email is shown in both user popovers and
custom profile popovers.
Along with this, we refactored settings_org.populate_auth_methods to use
HTML function after rendering all auth methods rows rather than appending
each row individually, which actually is a good practice.
Also in this commit, to compare `current_val` and `changed_val` in
`check_property_changed` function of the property
`realm_authentication_methods`, which are objects, and we found here
https://stackoverflow.com/a/1144249 that there is no easy way to do so. So
I followed this approach,
```js
JSON.stringify(obj1) === JSON.stringify(obj2)
```
but before converting them to string we want the same order of keys, so we
used `sort_object_by_key` to sort `current_val` by keys and
`get_auth_method_table_data` always return `changed_val` having keys
sorted.
Since these refactor were closely related we kept them as a single commit
here.
Fixes: #11954.
We now use a Proxy to wrap zjquery elements, so
that we can detect callers trying to invoke methods
(or access attributes) that do not exist. We try
to give useful error messages in those cases.
The main impact here is that we force lots of tests
to explicitly stub `length`.
Also, we can't do equality checks on zjquery
objects any more due to the proxy object, but the
easy workaround is to compare selectors. (This
is generally an unnecessary technique, anyway.)
The proxy wrapper is fairly straightforward, and
we just have a few special cases for things like
"inspect" that happen when you try to print out
objects.
With perfectScrollbar, we needed to call a function from JavaScript to
enable a scrollbar on a new element, but simplebar has a much simpler
default API one can do by using data-simplebar attributes in the HTML.
So we can delete all the scrollbar creation/deletion code.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Instead of deleting and rebuilding #private-container every time its
contents need to be updated, just replace its contents. This
eliminates some scrollbar flashing.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
perfect-scrollbar replaces both the appearance and the behavior of the
scrollbar, and its emulated behavior will never feel native on most
platforms. SimpleBar customizes the appearance while preserving the
native behavior.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Send at most 1k message ids in a single read flag request to avoid locking
large number of rows in server database in a single request and avoid long
processing time.
Fixes#11956.
This commit migrates the Subscription's notification fields from a
BooleanField to a NullBooleanField where a value of None means to
inherit the value from user's profile.
Also includes a migrations to set the corresponding settings to None
if they match the user profile's values. This migration helps us in
getting rid of the weird "Apply to all" widget that we offered on
subscription settings page.
The mobile apps can't handle None appearing as the stream-level
notification settings, so for backwards-compatibility we arrange to
only send True/False to the mobile apps by applying those defaults
server-side. We introduce a notification_settings_null value within a
client_capabilities structure that newer versions of the mobile apps
can use to request the new model.
This mobile compatibility code is pretty effectively tested by the
existing test_events tests for the subscriptions subsystem.
If MAX_FILE_UPLOAD_SIZE is set to 0, then UI elements like the upload
icon in the compose and message edit UI and "Attachments" menu in
"/#settings" are not displayed.
A different error message is also displayed if a user tries to drag and
drop or paste a file into the compose message box.
Fixes#12152.
This adds three bools to message_container object which calculate bools
where the "(EDITED)" label should appear:
* `edited_in_left_col` -- when label appears in left column.
* `edited_alongside_sender` -- when label appears alongside sender info.
* `edited_status_msg` -- when label appears for a "/me" message.
We use the new bools and remove the complicated if else statements
from the templates for the "(EDITED)" label.
This also allows us to add a unit test to verify the logic.
This commit renames the `create_stream_permission` field in the
templates to `create_stream_policy`, matching the field used in the
database model. This matches what `invite_to_stream_policy` does and
will be clearer when the `waiting_period_threshold` is split into its
own field.
This commit replaces the `create_stream_by_admins_only` setting with a
new `create_stream_policy` setting, which mirroring the structure of
the existing `invite_to_stream_policy`.
This is important preparation for migrating the waiting period feature
to be its own independent setting.
Fixes#12236.
Fixes#12251.
Previously when disabling name changes in server settings, instead
of realm settings, the name edit button did not get disabled.
Changing name resulted in a message stating `no changes made`.
Fixes#12132.
Realm setting to disable avatar changes is already present.
The `AVATAR_CHANGES_DISABLED` setting now follows the same
2-setting model as `NAME_CHANGES_DISABLED`.
This is useful when syncing avatars from an integrated LDAP/active
directory.
The upload avatar and delete avatar buttons are hidden if avatar
changes are disabled and the user is a non-admin.
If the user has a gravatar set, then the user will not be able to
upload an image as their avatar if avatar changes are disabled.
Part of #12132.
This commit creates a new organization setting that determines whether
a user can invite other users to streams. Previously this was linked
to the waiting period threshold, but this was both not documented and
overly limiting.
With significant tweaks by tabbott to change the database model to not
involve two threshhold fields, edit the tests, etc.
This requires follow-up work to make the create stream policy setting
work how this code implies it should.
Fixes#12042.
In handlebars and settings_org.js, the subsection in which
`realm_message_retention_days` property lies doesn't agree, and this wasn't
observed for a long time as it's disabled, still to make things right, in
this commit we have moved the logic which handles the collection of data
from `other_permission` to `other_settings` as it makes more sense there.
This is a small patch to fix the error message an admin would receive if
they tried to change bot info and owner from the "bots" setting of the
organization settings panel.
The alphabetic sorting of lists in the User/Organization settings was
changed in fa0a5ec to be case insensitive.
This commit makes changes to the list_render.js test to verify that the
sorting of these lists is indeed case insensitive.
We no longer store handlers as an array of functions,
and instead we assume that code will only ever set up
one handler per sel/event or sel/event/child. This is
almost always a sane policy for the app itself.
We also try to improve error handling when devs write
incorrect tests.
The only tests that required changes here are the
activity tests, which were a little careless about how
data got reset between tests.
Apparently, our use of JavaScript string `.replace()` here was buggy,
because replace() has several special escape sequences starting with
`$` if they appear in the replacement content string. We can work
around this through something of a hack, which is to pass a function
as the second argument to replace, which seems cleaner than replacing
all $s with $$s.
Thanks to Shreya for the report.
Now that we have a scroll container for the PM list,
it doesn't make much sense to limit the number to
five.
We may resurrect this feature if "more conversations"
actually fetches more conversations, but it doesn't
currently.
We also may soon make it easy to limit PMs to just
unread messages, which will make the max-5 feature
perhaps less necessary, and we don't want to make
the UI overly complicated.
This is the follow-up of PR #10267.
Here, we add typeahead for slash commands `/me` and `/poll` in compose box.
The slash typeahead will open only when `/` is the first character and all
slash commands will be displayed when one types `/`, as this helps a lot in
discoverability. This also adds a description of what the slash command
does in the typeahead.
When new PMs came in, we would do a little
animation to show you the incoming message.
Unfortunately, it was broken and would animate
too many things. (The code looks at a single
var to see if PM counts changed, but there are
actually mulitple PM counts. We could fix that,
but we decided that this feature just isn't
worth the complexity.)
We still animate incoming mentions.
Fixes#11868.
This makes the "more topics" option which appears below the list of
known topics in the left sidebar appear only when it's possible there
are actually more topics to be displayed. Two specific cases it
resolves completely include:
* Newly created realms; this widget was a common source of confusion
for new organization administrators.
* Newly created streams.
There are still some corner cases this doesn't handle, e.g. if you
just joined a private stream with protected history, but there isn't
as easy a fix for those.
Essentially rewritten by tabbott to fix code duplication and comment
extensively.
Fixes#10265.
As a follow up of commit (bf1c9420df), this
commit removes the `build_realm_day_mode_logo_widget` and
`build_realm_night_mode_logo_widget` function , and changes
`build_realm_logo_widget` to take single argument `is_night` and depending
on this argument, corresponding `day mode` or `night_mode` widget is
handled.
This changes the "new private message" button to be instead "new
conversation" when looking at PMs, to avoid confusion that the button
was the right thing to do to reply to the current private message
conversation.
Fixes#11679.
Even though there are only ever zero or one active
topic widgets in our current sidebar, it's almost the
same amount of code to just manage them with a Dict.
Also, we can more easily do possible future features
like setting streams to be always-open.
This moves the configuration of widget type from settings_org to instead
live in respective HTML templates, via `data-widget-setting-type` and we
also remove `get_subsection_property_types` and refactor function
`populate_data_for_request` accordingly.
Fixes: #11708.
This fixes the bug where the `Saved` state button faded out almost
instantly (that is actually 300 ms) and `Discard` button fades out
along with `Saved` state button; the key problem here was that the
setTimeout intended to fade was actually delaying the transition from
"saving" to "saved".
Now, first of all, we use `setTimeOut` function to fadeout elements giving
fadeout_delay time as `800 ms` and we hide discard button during `saving`
state. Also, when `Discard` button is selected, `Save changes` and `Dicard`
fade out simultaneously.
Fixes: #11737.
If you click on the avatar, we now show the menu
right next to the avatar. The current behavior
is particularly funny for long names. (I confirmed
this with Rishi.)
Adds possibility for users to use | as an OR-operator (besides ,)
when searching for other users.
This is a thing reasonable folks might try, and | in the thing to
search for isn't a realisitic possibility, so there's no real downside
to adding this.
Fixes#4109.
In this commit, I've added a feature to unstar all the starred
messages. This is useful, e.g., for folks who are using starred
messages to keep track of things they should come back when next at
their desktop.
The event flow is the standard one for a feature with a confirmation modal:
(1) User clicks on unstar all messages.
(2) We display a confirmation modal; if the user confirms, we send a
request to the backend to clear all starred messages.
(3) The events system sends that UI update back to us, removing the
stars from the UI.
Fixes#11401.
This commit deduplicates the code for `build_realm_logo_widget` and
`build_realm_night_logo_widget`. It deduplicates the common code for
`build_realm_day_mode_logo_widget` & `build_realm_night_mode_logo_widget`
into tthe function `build_realm_logo_widget`.
Add a background highlight to vote count button if currently
logged in user votes on that option.
Tweaked by tabbott to use better variable names and Rishi for better
styling.
This is a pure data function, so it shouldn't be in popovers.js file
(Steve Howell added test coverage here, and tabbott removed an
accidental functional change.)
The correct behavior here is that we want to ensure there is
whitespace in between the syntax being added and the content on either
side. Our smart_insert logic handled this for the cases that were
common with inserting emoji (etc.), but didn't handle the more complex
cases with "quote and reply".
Fixes#11702.
This new helper allows us to do the same operation
on every message in our message_store. We will
use this in a future commit to clear the `is_tall`
flags on all messages, after a resize.
We should be somewhat cautious about using this,
but simple operations should be really fast, even
if you have lots of messages in the store.
Previously, if you were in the process of editing the last message in
a narrow and a new message came in, we'd rerender that second-to-last
message, causing your editing widget to lose focus (and thus the next
few keys you typed to be interpreted as keyboard shortcuts, which
had a good chance of resulting in your navigating somewhere random).
This rerendering was essentially unnecessary; the only change to state
going into the rendering process was the next_is_same_sender CSS class
being toggled on the messagebox in the message. So, at most, we
should have been just toggling that CSS class (and this commit makes
us do precisely that).
It seems like we could further improve this code by just removing the
next_is_same_sender CSS class entirely and removing this block, but
I'm leaving that for follow-up work.
Fixes#11656.
This fixes an issue where closing stream search was not working if
user had not entered a search term and tried to close the search box
by clicking on the close icon; the problem was that we'd end up
re-opening the widget immediately after through event propagation.
Fixes: #11636.
Also adds tests to ensure that we do not accidentally overwrite
the 'beginning' variable that contains the message content upto
that point. These should prevent similar errors in the future.
The bug was added in 8119258c4d.
The bug here was that when we rerendered messages following local echo
through the echo.process_from_server code path, the eventual call to
_rerender_header() made the implicit assumption that all messages in a
message group had the same date. As a result, it created a totally
new/fake message group and called the rendering logic on that group
without calling the functions for setting up recipient row dates,
which would always result in no recipient bar date being added. This
bug was latent/invisible before, because when introduced, the locally
echoed messages were always being added to a recipient group from
today, where the recipient bar's date area was by default empty anyway.
This latent bug was revealed when we modified the structure of the app
to do date dividers between individual messages within a message
group, rather than strictly between message groups.
For consistency, we should keep all the code that works with
@mentions in markdown.js. In this case, message_list_view was
rewriting the contents of the mentions in cases where users'
names had been changed since we rendered their mention.
This change should help people discover to distinguish
silent mentions in text as a part of Zulip syntax while
differentiating them from regular mentions.
To test formatting we want a hard coded date, so we
can verify the date arithmetic with stable dates.
To make the test less brittle, we disable the
feature to remove old drafts.
This was an emergency fix. We should probably just
remove the last N drafts instead of having the 30-day
limit. Or we should have a better way to stub the cutoff
date.
This is mostly adding markup, calling some convenient
functions in buddy_data.js, and adjusting CSS.
To make the circles update dynamically, I mostly
orchestrate this though activity.js for now. It's
possible we'll want to adjust that eventually to
happen through something like a `presence_events`
dispatcher, but that's essentially what
a good part of `activity.js` does now.
We now have a function get_user_circle_class
that returns one of these values:
"user_circle_green"
"user_circle_orange"
"user_circle_empty"
And we put that in the templates.
And then CSS renders the circle of the appropriate
color.
The unit tests now explicitly capture whether
we are rendering the correct kind of circle.
This fixes a longstanding UI issue when you have way too many recent
private message conversations, as you can now scroll down the list to
find what you're looking for.
Fixes#5384.
This removes the left border extending the stream label from the
recipient bar in from the drafts in drafts modal. Those borders are
important in the message feed for containing several messages, but
here we're only ever going to show individual drafts, and this change
avoids potential color clashes with the blue box surrounding the
recipient blocks.
Show "sent to different narrow" notification and other such notification by
notifications.notify_local_mixes for non locally echoed message sent by
current client.
With significant new comments added by tabbott.
Fixes: #11488.
We swallow the error if our python_to_js_filter code is
unable to parse some python regex properly. This ensures
that the web app stays responsive.
We would fail to show an accurate local echo for these
regexes, however, the backend would act as the final
authority for handling the realm pattern conversion.
Since on replacing the first 'P<>' group, we remove this text from
the string, we have to make the RegExp start looking from index 0
again to properly convert later 'P<>' groups to JS regex syntax.
We want the search widget, when visible, to be
outside the scroll container for the stream list.
One obvious use case is if you start scrolling, and
then realize it might be less effort to search.
Also, for user search, it already worked this way.
We have to add a couple resizing hooks here, but
it's not necessary to change the actual resize
calculation, since we move the section inside
of #streams_header, which is already accounted
for.
The only markup change here is to add
a `stream_search_section` class. I don't
know why we use `notdisplayed` here instead of
jQuery, or what `input-append` is for, but I
considered them outside the scope of this change.
We can also remove some crufty CSS that was
compensating for it being inside the container.
This adds date dividers within a single message group when the only
reason we had previously been splitting apart two message groups is a
change of date. The overall effect is a cleaner message list user
experience.
The downside of this change would be that the recipient bars no longer
will always show a new date for date changes; to fix that, we rewrite
how the floating recipient bars both set the date field on the
floating recipient bar itself, as well as ensure that non-floating
recipient bars don't show duplicate dates.
In a future design update where we modify how message recipient bars
look, we may very well be able to simplify this logic by removing some
of the dynamic nature of the recipient bar calculations. But this is
a good implementation of what remains.
Tweaked significantly by tabbott from Steve Howell's original, both to
extract these changes from a larger PR as well as to modify the
first_visible_message logic to handle some tricky corner cases.
Fixes#10171.
Use the results of commit #73d26c8 to remove the method
`render_stream_description` in static/js/stream_data.js and instead
use the rendered_description attribute now being sent by the backend.
This will be a valuable optimization and a step towards removing the
need for the marked.js markdown parser and speeding up the client end.
In small screen sizes, when the user presses shortcut `w` to search
for another user, the hide_all function calls in the search code path
would hide the right sidebar, immediately after opening it, making the
hotkey basically unusable.
We fix this by extracting a separate hide method that hides all true
popovers, but not the user list sidebar.
Fixes#11463.
This code will correctly add video call link to the message
textarea based on whether 'Add video call' was selected from
message composition form or message edit form.
The implementation was semi-rewritten by tabbott to remove an
unnecessary global variable, with fixes for the unit tests from
showell.
Fixes#11188.
This is primarily a feature for onboarding, where an organization
administrator might send a bunch of random test messages as part of
joining, but then want a pristine organization when their users later
join.
But it can theoretically be used for other use cases (e.g. for
moderation or removing threads that are problematic in some way).
Tweaked by tabbott to handle corner cases with
is_history_public_to_subscribers.
Fixes#10912.
This function unlike `invite_streams()` returns an array of objects having
various info (name, stream_id, invite_only, default_stream) related to
streams rather than an array of names of streams.
We now compute the class that drives the tiny
green/orange/empty dot in the user popover using
the same logic as the buddy list.
This was broken in the early implementation of
set/clear-away, but it was never released.
Fixes#11413
This makes it possible to mention a user with a name like Gaël that
contains diacritics by typing e.g. "Gael", significantly reducing the
need to use a special keyboard to mention other users.
Fixes#11183.
The following elements in the top left corner
are major components of our app:
All messages
Private messages
Starred messages
Mentions
We can now find them directly:
$('.top_left_all_messages')
$('.top_left_private_messages')
$('.top_left_starred_messages')
$('.top_left_mentions')
Before this, we had to build up complicated selectors
like below:
exports.get_global_filter_li = function (filter_name) {
var selector = "#global_filters li[data-name='"
+ filter_name + "']";
return $(selector);
};
I don't think any newbie would know to grep for "global_filter",
and I've seen a PR where somebody added specific markup here
to "Private messages" because they couldn't grok the old scheme.
Another thing to note is that we still have a "home-link"
class for "All messages", which overlapped with portico
code that had the same name. (There were some inaccurate
comments in the code relating to the tab bar, but we don't
actually have a way to click to the home view in the tab
bar any more.) I'll eliminate that cruft in another commit.
For this commit the four elements still have the
"global-filter" class, since there's some benefit to being
able to style them all as a group, although we should give
it a nicer name in a subsequent commit.
Most of this PR is basic search/replace, but I did add a
two-line helper: `top_left_corner.update_starred_count`
We had initially designed the poll widget like a blog
post with comments beneath it but it makes more sense
to think of it as just a simple poll with options.
Instead of custom stubs, we now use zjquery. We also
limit a couple checks to the first call to
`show_empty_narrow_messages`, since it's the same
logic every time.
When you hover over a user that has set a user
status, we now show something like "out to lunch."
You can test this in the console by doing:
user_status.server_update({status_text: 'out to lunch'})
And then hover over your name in the buddy list.
The stubs here were kind of unnecessary, as the
real people module is lightweight and data setup
is pretty easy.
In passing I also removed the unnecessary `sed`
abbreviation.
The name `insert_user_into_list` is sort of misleading,
since we are often just redrawing the user's existing
item in the buddy list.
I chose `redraw_user` over `update_user` to emphasize
that we're just going to redraw it with whatever data
has been updated by the callers.
This adds a setting under "Notification" section of
"Organization settings" tab, which enables Organization administrator to
control whether the missed message emails include the message content or
not.
Fixes: #11123.
The commit f863a9b567 had modified
jquery.filedrop's paste method to exit early if any of the items in the
clipboardData is of the string kind. The early exit was added to prevent pasting
an image thumbnail for text copied from software like MS Word, instead of
pasting the actual copied text content. When copying an image in a (modern?)
Browser, though, the clipboard seems to contain a html `img` tag item, along
with the actual image file. This resulted in pastes being broken.
This commit modifies the condition checked for the early exit. We now actually
look at the html content in the clipboard to see if it is an `img` tag, in which
case we upload the image, instead of exiting early.
Closes#7130.
This commit takes away the ability for non-admin members to create
streams where only admins can post messages by hiding the option from
them.
Fixes#11290.
You can now pass in an info field with a value
like "out to lunch" to the /users/me/status,
and the server will include that in its outbound
events.
The semantics here are that both "away" and
"status_text" have to have defined values in order
to cause changes. You can omit the keys or
pass in None when values don't change.
The way you clear info is to pass the empty
string.
We also change page_params to have a dictionary
called "user_status" instead of a set of user
ids. This requires a few small changes on the
frontend. (We will add "status_text" support in
subsequent commits; the changes here just keep
the "away" feature working correctly.)
We had a bug where if you started typing a message
and then used quote/reply (after the fact), we
would overwrite the user's original message.
The bug was kind of subtle--the internal call
to "respond" to the message would select the message
text, and then `smart_insert` would replace the
selection, unless it was Firefox.
Note that we now also allow you to cross-post
replies, which is a plausible scenario, although
possibly unintentional at times, too. I'm erring
on the side of giving the user control here, but
I'll add a warning in the next commit. Our compose
fade feature should also prevent unintentional
mixes here, too.
NOTE: If you revert this commit, you want to revert
the immediately prior commit as well. The history
is that Ishan made some improvements to the widget,
but there were some minor bugs. I decided not
to squash the commits together so that the git
history is clear who did what. (In particular, I
want questions about the JS code to come to me if
somebody does `git blame`.)
Anyway...
This is a fairly significant rewrite of the polling
widget, where I clean up the overall structure of
the code (including things from before the prior
fix) and try to polish the prior commit a bit as
well.
There are a few new features:
* We tell "other" users to wait for the poll
to start (if there's no question yet).
* We tip the author to say "/poll foo" (as
needed).
* We add edit controls for the question.
* We don't allow new choices until there's
a question.
On the backend, we extend the BlockQuoteProcessor's clean function that
just removes '>' from the start of each line to convert each mention to
have the silent mention syntax, before UserMentionPattern is invoked.
The frontend, however, has an edge case where if you are mentioned in
some message and you quote it while having mentioned yourself above
the quoted message, you wouldn't see the red highlight till we get the
final rendered message from the backend.
This is such a subtle glitch that it's likely not worth worrying about.
Fixes#8025.
These mentions look like regular mentions except they do not
trigger any notification for the person mentioned. These are
primarily to be used when you make a bot take an action and
the bot mentions you, or when you quote a message that mentions
you.
Fixes#11221.
AFAIK I should this never fail, hence the blueslip.error line. But it
is failing in practice when rendering user groups after looking them
up by ID, and the error handling should definitely be softer.
In between releases, the following commit introduced
a bug where we agressively scroll to the top every
place we call `ui.update_scrollbar`:
092b73d0b7
The main symptoms were that the left and right sidebars
would go to the top for things like selecting a topic,
getting activity updates from the server, and resizing
the window. It was very jarring.
The recent commit looked innocuous--the root of the problem
was the original API expressed an intent to scroll to the
top, but didn't actually do it, so it was a bug in hiding.
There are **some** occasions where it's actually appropriate
to scroll to the top, mostly around search filtering, and
in those places we now call the new `ui.reset_scrollbar`
function.
This is a bit of an emergency fix, so particularly with
the settings stuff, we may get more reports of glitches here.
The important thing here is that you almost never want to
reset the scrollTop for sidebars.
This seems like a small change (apart from all the
test changes), but it fundamentally changes how
the app finds "topic" on message objects. Now
all code that used to set "subject" now sets "topic"
on message-like objects. We convert incoming messages
to have topic, and we write to "topic" all the way up
to hitting the server (which now accepts "topic" on
incoming endpoints).
We fall back to subject as needed, but the code will
emit a warning that should be heeded--the "subject"
field is prone to becoming stale for things like
topic changes.
We now have two functions:
add_new_messages
add_old_messages
This is a lot easier on the eyes, and it will also
prevent us from exceeding line length in future commits.
We also remove an unneeded stub in the narrow_activate
tests.
This is the preferred way to check that a user
id belongs to the current user.
We have a recent bug where the current user's
circle doesn't turn green right away. It's not
clear this is the fix, though. (It's hard to
repro locally.)
This is mostly for testing purposes. The code
structure here is pretty stable--we will probably
always use level() here to either sort or
group users, and being able to test it directly
is nice, rather than bringing in all the other
machinery.
This makes it possible it include our standard markdown formatting in
one's custom profile fields, allowing for links, emphasis, emoji, etc.
Fixes#10131.
While we're at it, we remove the JSON parsing that was part of the
user field code path, since this function isn't responsible for
rendering user fields.
Previously, messages with more than one line did not parse '/me' at
the beginning of the message. Since there's a reasonable way to
render multi-line messages, this commit adds support for doing so.
This change does potentially break with the expected behavior of other
slash commands, but it seems worth providing useful functionality over
a blind focus on consistency.
Fixes#11025.
We instead get the specific fields from message
that we use. This is particularly helpful
for subject -> topic migration; we no longer
have to account for "subject" fields in
client-side templates.
This continues the effort to isolate "subject" references
to util calls.
Also, we fix a comment.
Finally, we use canonicalized operators in a switch
statement.
The `assert_message_groups_list_equal` and
`assert_message_list_equal` helpers were
always returning `true`, as they were doing
a bogus traversal of the data structures and
always comparing empty arrays, even when there
was real data.
To prevent this pitfall in the future, we assert
that the extracted data is truth-y, and for the
empty cases we just directly assert deep equality
to `[]`.
As part of giving the stream/topic fields in the
compose box longer ids, I broke the autocomplete
code that handles re-focusing the cursor after
a user hits enter. The worst symptom of this was
that we tried to send a message before compose
finished (although it wouldn't fully deliver the
message).
The new code should be a bit easier to grep for
if we rename these fields again, as we explicitly
use selector syntax.
This adds a new realm_logo field, which is a horizontal-format logo to
be displayed in the top-left corner of the webapp, and any other
places where we might want a wide-format branding of the organization.
Tweaked significantly by tabbott to rebase, fix styling, etc.
Fixing the styling of this feature's loading indicator caused me to
notice the loading indicator for the realm_icon feature was also ugly,
so I fixed that too.
Fixes#7995.
We are trying to carve room for a more specific
"user_status" concept, which refers to statuses
that users specifically set, like "I'm away".
So we call this function "update_presence_info",
which reflects that it's more about actual
"presence"--i.e. the user really is present
in the browser, even though the actual human
may not want to be disturbed.
The current user gets excluded from all non-empty
searches, even ones that match the user, since
it can look funny when the user's at the top of a
search, and you'd never need to search for yourself
(again, since the current user is at the top of
the buddy list).
Apparently, we didn't have one of these, and thus had a moderate
number of generally very old violations in the codebase. Fix this and
clear the ones that exist..
We now rely on set_up() methods to call their
own module-specific versions of maybe_disable_widgets()
in the codepath for admin_sections.load_admin_section().
And then for live updates, we just explicitly call
all four modules that support maybe_disable_widgets().
This should make switching between sections slightly faster,
and it also reduces the risk of module A messing with
module B's state. (Granted, we have lots of other ways
that modules can mess with each other's state.)
We had an anonymous callback for drafts that was
hard to read. It's much easier to flatten the code,
give functions actual names, and stub them as needed
in the unit tests.
The first bug fixed here has been around for a long
time--we were redundantly updating unread counts
indirectly via muting_ui.initialize(). The
unread counts also get updated in
unread_ui.initialize(), when we have more valid
state. (And it's worth noting here that the unread
counts get updated yet again once message fetches
complete.)
The second bug was a very recent regression from
my recent stream name -> stream id cleanup in the
muting system. We now depend on stream_data to
initialize muting data, so we need to initialize
muting.js slightly later in the process.
These fixes are intertwined, because they were both
somewhat caused by the anti-pattern of having
muting_ui.js initialize unread_ui.js and muting.js,
instead of doing more direct, fine-grained initialization
from ui_init.js.
Essentially we replace this code:
exports.update_muted_topics = function (muted_topics) {
muting.set_muted_topics(muted_topics);
unread_ui.update_unread_counts();
};
with this:
exports.initialize = function () {
exports.set_muted_topics(page_params.muted_topics);
};
And the modules load like this:
stream_data
...
muting
...
unread_ui
And we don't need any page-load initialization for muting_ui,
which is mostly used for Settings/Muted topics.
This function used to be called initialize_from_page_params(),
and we called it indirectly through `subs.js`.
Now we call it directly from `ui_init.js`, which gives us a
bit more control over how things are initialized. In fact,
this sets us up for the next commit, where I fix a recent
regression I introduced.
This is mostly about cleaning up the naming convention
for streams and topics, but it also adds a test that
specifically tests the muted-topic case (without any
other factors that would prevent a notification).
Before this commit, it was possible to change the
API for muting topics and get false positives, even
when the test setup was clearly broken.
The stream_list test that was fixed here was sort of
broken. It accomplished the main goal of verifying
what gets rendered, but now the data setup part is
more like the actual app code (and simpler, too).
This fixes the most core data structures inside of
muting.js. We still use stream names for incoming
data to set_muted_topics and outgoing data from
get_muted_topics.
This will make us more resilient to stream name changes.
Before, if you were logged on when a stream rename
occured, topics that were muted under that stream would
appear to be unmuted. (You could fix it with a reload,
but it can be jarring to have a bunch of unread messages
appear in your feed suddenly.)
Fixes#11033
Like the other similar commits, we were doing the same work in all
code paths, just with a much more error-prone approach.
We can also now remove the now-unused finish_initial_narrow function.
Like the other commits in this series, we were already doing this in
all of the callers of load_messages; this centralizes that logic in a
less ad-hoc feeling way.
We no longer use or need the start_initial_narrow function.
Previously, each individual caller of load_messages that passed
num_before > 0 would do its own manual management of fetch_status;
now, we just do it inside load_messages.
The stream/topic edit areas now have these ids:
#stream_message_recipient_stream
#stream_message_recipient_topic
They are pretty verbose, but being able to grep
for these without noise does have some value.
We can eliminate the janky `setup_page` methods
and just pass in section from `hashchanged`.
This sets us up to handle browser history more
nicely when you load '#settings' and we could essentially
redirect you to '#settings/your-account' (or similar
things). A future commit will address that.
We also use `launch` as the new entry point, which
is more consistent with other modules.
The prior name of this was a bit inaccurate, as we no
longer ever hide the menu item for non-admins. Also,
it belongs more naturally in `gear_menu.js` at this point.
Also, we remove one call to this, which was in a place
where it was no longer necessary.
We now run the code to disable widgets every time
we reload a section, which was the original intention
of the code, but the call to it only happened when
you first launched the page.
We also continue to run this logic for live updates
of is_admin, although it's worth noting that the
code still only handles the "demotion" case of going
from admin to non-admin. (If somebody makes you an
admin, you continue to need to reload to get
widgets enabled.)
This ensures the "account settings" UI for managing a user's own email
address uses the delivery email, since that's what users care most about.
Eventually, we'll need to add support for at least viewing both email
addresses in "account settings", but this is the right long-term
behavior.
This new setting is still hidden in the UI when not in the development
environment, because the feature isn't ready for production, but
merging this will help simplify future work on the feature.
Previously, Topic editing was offered in the UI even to message
senders and organizations admins only if the message was no more than
one day old. This was correct for the "community topic editing" case,
but not for message senders and organization admins.
While we're at it, this also centralizes some previously haphazard
logic to always call message_edit.is_topic_editable().
Tweaked significantly by tabbott to fix the logic.
Closes#10568.
The goal here was to enforce 100% coverage on
parse_narrow, but the code has an unreachable line
and is overly tolerant of bogus urls. This will
be fixed in the next commit.
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.
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.
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.