Escape all the possible special characters.
We replaced \b with (?:^|\s) since it matches word boundries including
special characters.
Pasted relevant stackoverflow links which expain them properly.
This commit removes unnecessary code for adding and removing
"can_edit" class from emoji-settings element. This class is
unnecessary and is not used for styling or for any other purpose.
This commit removes the ".not(can-edit)" selector filter from
insert_tip_box. We do not require this selector filter because
this class is only used for emoji-settings and we already do not
prepend tip in emoji-settings page from this function and we handle
it separately.
As this class is only used for this purpose we can also remove this
class from emoji_settings_admin.hbs.
The organization_settings_tip is not visible if organization settings
overlay is opened with any section other than organization profile,
settings and permissions. This is because insert_tip_box is called from
settings_org.build_page, which is called only when we open any of the
above three sections after opening the overlay and not others.
We should call insert_tip_box function from admin.build_page instead
of settings_org.build_page because we need to insert the admin tips
each time the organization settings overlay is opened, irrespective
of the section which opens first.
The function insert_tip_box is moved to admin.js from settings_org.js,
because settings_org.js file handles the organization profile,
settings and permissions page only, while we display the tips in many
other sections including bots, custom emoji, etc.
Thus, it makes sense to move insert_tip_box function to admin.js, which
renders the complete organization settings overlay using render_admin_tab.
We send user_id of the referrer instead of email in the invites dict.
Sending user_ids is more robust, as those are an immutable reference
to a user, rather than something that can change with time.
Updates to the webapp UI to display the inviters for more convenient
inspection will come in a future commit.
This commit removes "realm_message_retention_days === null" check from
the conditionals, as we had updated the backend to replace NULL value
with -1 in 7a03e2a.
This commit fixes the UI for stream message retention days to allow
only owners to set or update the setting.
We hide the setting for non-owners in the stream creation form and
disable it in the stream_privacy_modal.
Fixes a part of #15558.
* Don't annoyingly open the first section when switching
between the Settings and Organization tabs.
* Don't highlight currently active section in the settings list
(we don't display the currently active section in the mobile settings
list so it isn't actually active).
* Remove nearly invisible and buggy no-border logic.
This commit removes invited_as_values map in settings_invites.js.
This object has been removed to avoid duplication as we already
have role values in settings_config.js.
A similar map is created from settings_config.user_role_values
in settings_config.js and is used to populate invited_as_text
for invites.
This commit changes the PreregistrationUser.invite_as dict to have
same set of values as we have for UserProfile.role.
This also adds a data migration to update the already exisiting
PreregistrationUser and MultiuseInvite objects.
We leverage the composebox typeaheads to show flatpickr to pick dates
and times for the !time syntax.
We use moment.js to try and parse the time from current token. If we
are successful, we initialize flatpickr with the parsed time, else we
default to using the current time.
Currently we display -1 in input box of id_realm_message_retention_days
when realm_message_retention_days is -1, which isn't user friendly.
Displaying the input box as empty is more intuitive.
And if the user tries to submit an empty input box we throw invalid JSON
error that isn't user friendly either, so fixed that too. In the ideal
case, we shouldn't send the request at first place to the backend when we
don't have any input.
Currently, we use -1 as the Realm.message_retention_days value to retain
message forever unless specified at stream level for a particular stream,
that is, no policy set at the realm level. But this is incoherent with what
we use for Stream.message_retention_days where -1 means
> disable retention policy for this stream unconditionally
that can be confusing from an API standpoint.
So instead of trying some hack to reset the value to NULL or using some
other value like -2 for RETAIN_MESSAGE_FOREVER and use that for API. It is
much more intuitive to use a string like 'forever' that can be mapped to
RETAIN_MESSAGE_FOREVER at the backend. And this is similar to what we use
for streams settings as well.
`get_input_element_value()` function is more reliable to detect the input
element type and extract it's value. But the current way of setting the
value of input elements relies on first checking the `property_value` type.
Which is fine, but for the cases when the property value is null, and we
want to set element value as empty, this method will throw an error as it's
unable to detect the appropriate element type. This new function
`set_input_element_value` first rely on property value and then use
`setting-widget-type` as a fallback.
This fixes the change detection of org settings input elements. Luckily,
this regression didn't break our populate_data_for_request and that's also
why this didn't come to notice.
In 5200598a31, we introduced a new
client capability that can be used to avoid unreasonable network
bandwidth consumed sending avatar URLs of long term idle users in
organizations with 10,000s members.
This commit enables this feature and adds support for it to the web
client.
If the `load_messages_for_narrow` function tried to fetch messages with
a floating point anchor (locally echoed message id) we get a 400 error.
The logic to remove the rounding of the anchor parameter was done in
commit bf2f36e6b4, as it would always be
an integer in all incoming code paths.
However, since then we have updated the GET /messages API, to also allow
strings as the anchor parameter and this value's parsing is done in the
backend.
Fixes#15497.
We update the logic for displaying the "message is outside current
narrow" notice, by comparing whether the message the client sent can
be appended to the current narrow's filter or not (this results in us
correctly falling through to reporting the user needs to scroll down).
This commit changes stream_data.create_sub_from_server_data to use
stream id, instead of stream name, for checking whether subscription
already exists or not. We are using stream ids so that we can avoid
bugs related to live update after stream rename.
This commit changes would_receive_message and want_normal_display
functions in compose_fade.js to use stream id, instead of stream
name, to get sub object. We are using stream ids so that we can
avoid bugs related to live update after stream rename.
This commit changes populate_group_for_message_container function to
use stream id to get sub object, instead of stream name.
We already have stream id from message object, so we can easily
use it to fetch sub. We are using stream ids so that we can
avoid bugs related to live update after stream rename.
This commit changes stream_data.remove_subscriber to use stream id
instead of stream name. We are using stream ids so that we can
avoid bugs related to live update after stream rename.
Thsi commit changes stream_data.add_subscriber to use stream_id
instead of stream name. We are using stream ids so that we can
avoid bugs related to live update after stream rename.
This commit removes stream_edit.rerender function. We directly
call subs.rerender_subscriptions_settings directly from
server_events_dispatch.js, which was the only caller of rerender
function, as we already have sub object.
We are using stream ids so that we can avoid bugs related to live
update after stream rename.
We can use get_sub_by_id instead of get_sub to get the stream info,
as we already have stream id from the message object. We are using
stream ids so that we can avoid bugs related to live update after
stream rename.
This commit changes receives_notifications function to use
stream_ids instead of stream names. We are using stream ids so
that we can avoid bugs related to live update after stream rename.
Prior to this commit has:link, has:attachment, has:image
filter couldn't be applied locally and deferred filtering to
web server. This commits make sure client filters all messages
it can instead of completely deferring to the server and hence
improve speed.
A tradeoff is also made to turn off local echo for has: narrows
as messages with link sent to has:link narrow were locally echoing
to another narrow and not appearing in the active has:link narrow.
Fixes: #6186.
With this implementation of the feature of the automatic theme
detection, we make the following changes in the backend, frontend and
documentation.
This replaces the previous night_mode boolean with an enum, with the
default value being to use the prefers-color-scheme feature of the
operating system to determine which theme to use.
Fixes: #14451.
Co-authored-by: @kPerikou <44238834+kPerikou@users.noreply.github.com>
We can now invite new users as realm owners. We restrict only
owners to invite new users as owners both for single invite
and multiuse invite link. Also, only owners can revoke or resend
owner invitations.
Add arrow key navigation support for recent topics.
Simple jquery is used to allow navigation for filter buttons,
a grid system is used for navigation inside table.
This commit corrects the message shown when we click the add button
for subscribing users to stream with empty input.
We show 'No user to subscribe.' as the message when trying to add
subscribers with empty input.
Fixes#15450.
This improves the logic and fixes the bug where the href was calculated
based on the current URL and not the filter of the current message list.
We now add the '/streams/public/' operator at the start of the operators,
similar to how it is represented in all other cases.
Fixes#15405
This commit removes the click handler used for
'empty_feed_sub_unsub' class.
This class was used only in home.html and was replaced
by 'stream_sub_unsub_button' in 576be51.
This reverts part of b0d632577f.
The problem was that multiple queries were combined as a single
search pill. And since we create the pills then narrow / search,
we added a comma seperator between them for the typeahead lookups
as required by the logic in `input_pill.js`.
This however introduced a new bug where the search suggestions
were incorrect as the typeahead lookup table wasn't updated, so
every time an item from the type ahead was selected it updated
the input string with an invalid operator.
Thus to resolve the first problem, we follow a simpler approach
by extracting all operators from the search string using our
`Filter.parse` logic and next add the pills, one by one.
Whenever a search pill is selected or deleted by a click the navbar
gets rendered as the searchbox loses focus. This allows the user to
be able to continue editing the search query without having to refocus
the searchbox.
A main change is that we now display the navbar if the search box
is not focused. This was already present in the search pills version
but adding it to the legacy version is an improvement.
We sufficiently increase the timeout so that the pills are actually
deleted. This was required when `filter.is_common_narrow()` is true,
as then only we render the narrow description and close the search bar.
This commit also matches another behaviour of the legacy search.
i.e. We narrow every time a search suggestion is clicked.
The now redundant "focusin" and "focusout" event handler tests are
also removed.
Two things were broken here:
* we were using name(s) instead of id(s)
* we were always sending lists that only
had one element
Now we just send "stream_id" instead of "subscriptions".
If anything, we should start sending a list of users
instead of a list of streams. For example, see
the code below:
if peer_user_ids:
for new_user_id in new_user_ids:
event = dict(type="subscription", op="peer_add",
stream_id=stream.id,
user_id=new_user_id)
send_event(realm, event, peer_user_ids)
Note that this only affects the webapp, as mobile/ZT
don't use this.
We recently removed an API call for fetching user list for our
Settings>Users/Deactivated panels, which introduced a bug where
we rendered the users table before last active information is
processed by the frontend.
This commit makes us process presence before rendering our settings
panels. We move the presence init above because we need to initialize
settings_sections before hashchange.
Fixes#15453.
When the user clicks a button that opens a modal, and if we don't break off
the corresponding click event. This condition in the global click handler
will become true and enables all mouse events outside modal.
```js
$(document).on('click', function (e) {
...
// If user clicks outside an active modal
if ($('.modal.in').has(e.target).length === 0) {
// Enable mouse events for the background as the modal closes
$('.overlay.show').attr("style", null);
}
```
Related to #12369.
This commit adds message retention policy details in the subscription_type
text below the stream description.
We do not show any text when realm-level settings is set to forever and
stream-level is set to either forever or realm_default.
This commit adds frontend support for setting and updating message
retention days of a stream from stream settings.
Message retention days can be changed from stream privacy modal of the
stream and can be set from stream_creation_form while creating streams.
Only admins can create streams with message_retention_days value other
than realm_default.
This commit also contains relevant changes to docs.
This commits adds the code for live update of stream_post_policy in
subscription_type text in stream settings.
This is done by passing stream_data.stream_post_policy_values to the
template data, which were not passed previously and the if conditions
were not evaluated correctly.
Previously, we had implemented:
<span class="timestamp" data-timestamp="unix time">Original text</span>
The new syntax is:
<time timestamp="ISO 8601 string">Original text</time>
<span class="timestamp-error">Invalid time format: Original text</span>
Since python and JS interpretations of the ISO format are very
slightly different, we force both of them to drop milliseconds
and use 'Z' instead of '+00:00' to represent that the string is
in UTC. The resultant strings look like: 2011-04-11T10:20:30Z.
Fixes#15431.
There is apparently some way to have two instances
of `.emoji-popover-emoji-map`, although I can't
reproduce it.
This causes an `expectOne` check to fail fairly
deep in the stack.
Now we report it more directly.
This commit and a few previous ones mostly
address #15348 by trying to either a) not
depending on having a single instance of
the popover or b) making it more explicit
in cases where do expect that invariant.
Fixes#15348
This is just a pure refactor for now, but
we may want to modify this to more precisely
determine the active map (in case multiple
pickers are open for some reason).
This is clearly a better home for it, since message_scroll.js is the
only place that reads it, and also lets us provide a clearer name for
the functionality.
Since we are no longer using the "pointer" value sent in
page_params.pointer for anything, there's no value in continuing to
send it from the server to the client.
The remaining code in pointer.js is logic managing state for the
currently selected message.
Since the pointer is no longer used to set the browser's position, we
no longer need this complex code to send updates to the server during
the bankruptcy flow.
It's crazy that we need to do this; one would think that Electron apps
whose sole purpose is to be used with multiple team chat tools would
at least implement the standard desktop notification API correctly.
But it seems worth making this tactical change to prevent every
desktop notification throwing a traceback on those platforms, which if
nothing else results in a lot of error spam.
Fixes#15103.
This was broken when moving the code being called to another file.
This exception caused a pretty weird/nasty bug by interrupting the
message_fetch response handler before it finished updating the
fetch_status data strutures. The end result was that in views where
the "history limited notice" was displayed, local echo would be broken
a confusing notice would be displayed.
In rare situations we would get tracebacks from
list_cursor on the line that I changed here. We
went the entire month of May without a traceback
here, and I can't reproduce the problem.
This is a pretty clear fix, though, and it will
hopefully lead to a more enlightening symptom.
The likely scenario here is that you use `q` to
navigate the stream list and then unsubscribe.
I tested that and couldn't get a traceback,
but I do think the traceback indicates some
possible issues.
The behavior I saw when I did this
appeared to be mostly harmless.
When I deleted a row (by unsubscribing), the code
seemed to effectively disable the cursor. It's
possible we should go to the next row or fully disable
the search.
I opened #15439 to follow up on this and other
cursor-related issues.
The stream_events tests were kinda messy, but
I mostly just consolidated a few sections of
code so that we didn't have to keep
re-stubbing the same functions.
For the actual code, I extracted add_sidebar_row
and then removed the unnecessarily complicated
jQuery trigger mechanisms.
This merges the `exports.get_search_result_legacy` and
`exports.get_search_result` function.
The key differences between the two code paths are as follows:
* We only want to generate suggestions for the queries which
the user is typing or can edit.
For the legacy version, suggestions are displayed for the
entire search string in the searchbox. (`all_operators`)
For the pills enabled version, suggestions are displayed
only for the input which hasn't been converted to pills.
(`query_operators`)
`all_operators` = `base_query_operators` + " " + `query_operators`.
trim is added at the end just to handle the legacy case
where we pass the `base_query` as ''.
* It is not possible to detect whether the user wants to
continue typing in the legacy version. However if the
the searchbox is still focused even after pill creation
we can assume the user still wants to continue typing.
To handle this we push an empty term as the `last` operator.
This is possible since the previous queries have been
completely entered as evident from it's generated pill.
* When using the legacy version, `search_operators` are
the same as `all_operators`, as mentioned in point 1.
In the pills enabled version we perform most of the
computations from the `query_operators`, but we do
require all `all_operators`, only for filtering the last
query's suggestion.
* And there is just one block unique to the legacy search
system. More details are mentioned in the comments of that
block.
We also refactor both the search suggestions node tests,
mainly to make them similar and easier to detect differences
when we switch over to the new version.
Previously we narrowed every time a search pill was created or deleted.
This commit allows the user to be able to continue typing without the
lag of narrowing.
This behaviour matches with the legacy version, whose code path remains
unchanged.
Under the search pills paradigm it is more natural for the
user to add pills and still continue typing.
Previously everytime a pills gets added the narrow activates
(this is still the case) and then the user had to refocus the
searchbox the continue typing the remaining search query.
The 2 function calls of `open_search_bar_and_close_narrow_description`
was removed from the 2 event handlers since it was called again, from
the `search.initiate_search`.
The "focusin" event was redundant since there are multiple other event
handlers (like the `tab_bar` or `hotkeys`) for this purpose, and all
of them call the `search.initiate_search` function.
The only change made here is the renaming of `operators` variable
to `search_operators`.
That is mostly evident from the fact that we do not need to
make any changes to `node_tests/search_suggestion_legacy.js`.
As mentioned in the previous commit, we make this change
to get a minimal diff between the legacy and search pills
enabled version.
The only changes made here is the renaming of `query_operators`
variable to `search_operators`.
That is mostly evident from the fact that we do not need to
make any changes to `node_tests/search_suggestion.js`.
This will be helpful when we combine this function with it's
legacy function. As most of the logical decisions to generate
the result is based on the `query_operators` variable for the
search pills enabled version and the `operators` variable for
the legacy search version.
This fixes one of our oldest important user experience issues, namely
that if you never visit the home view, the Zulip webapp would often
load "deep in the past" because the pointer had not advanced.
Fixes#1529.
When fetching older/new messages, we used to resort to the pointer
to act as anchor when message list was empty.
This appears to be an impossible case, as
`fetch_status.can_load_newer_messages`
should be false in this case and user cannot be scrolling an
empty message_list in the first case.
Hence, we raise a fatal error to inform user of the same.
Now we can use common HTML image upload widget template
`image_upload_widget.hbs` for realm day/night logo and
we should access those day/night logo elements using
e.g., "#realm-day/night-logo-upload-widget .realm-logo-elements".
since we use image_upload_widget.hbs for realm day/night logo upload
widget we need to extract CSS for realm day/night logo and
place them separately under `#realm-day-logo-upload-widget`
and `#realm-day-logo-upload-widget` css id.
Now we can use common HTML image upload widget template
`image_upload_widget.hbs` for realm icon. we can access icon
element using "#realm-icon-upload-widget .realm-icon-elements".
also we need to extract CSS for realm icon and place them
separately under `#realm-icon-upload-widget` css id.
Messages are automatically marked read when all the messages in
the current narrow are visible. While this is handy, this is
should not happen when any of the overlays are open.
Previously, in `make_tab_data()` we were using the stream name,
which we got from the filter, to call `stream_data.get_sub_by_name()`.
This commit switches to just using `filter._sub`, which is simpler and
better.
Previously, this function relied on the return value of
`filter.get_icon()` which made it brittle.
Directly using the properties of the filter and sub object makes this
more explicit about the intentions and robust.
In commit 4f6377d493 we added
`_stream_params` as a way of storing attributes such as stream name
and stream privacy, this involved adding a few calls within functions
that updated these values (in order to maintain consistency).
This commit replaces `_stream_params` with an always consistent `_sub`
object and removes unnecessary `_stream_params` related code. Once the
`_sub` object is available, calls to `stream_data` may be considered
suspicious as they can often be avoided by just picking the desired
attribute off of the `_sub` object.
Previously, this bit of code was looking for specific icons on the
navbar, but it's more semantic to just look for the `.fa` which is a
direct child of `.stream`. It also makes the code cleaner, to have a
single call here.
This commit removes a redundant line of code which was converting from
hex to RGB rounding off and then converting from RGB to hex again.
This line was (mistakenly) introduced in
eb4a2b9d4e while removing a hover effect
that had become irrelevant.