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.
Google has removed the Google Hangouts brand, thus we are removing
them as video chat provider option.
This commit removes Google Hangouts integration and make a migration
that sets all realms that are using Hangouts as their video chat
provider to the default, jitsi.
With changes by tabbott to improve the overall video call documentation.
Fixes: #15298.
This adds support for a "spoiler" syntax in Zulip's markdown, which
can be used to hide content that one doesn't want to be immediately
visible without a click.
We use our own spoiler block syntax inspired by Zulip's existing quote
and math block markdown extensions, rather than requiring a token on
every line, as is present in some other markdown spoiler
implementations.
Fixes#5802.
Co-authored-by: Dylan Nugent <dylnuge@gmail.com>
Now we can remove `user_avatar_file_input_error` id and added new class
`image_file_input_error`.we can access this class using
`#user-avatar-upload-widget .image_file_input` so that we can
have only one id at top-level and 'image_upload_widget.hbs`
can be more dynamic so we can use for other similar widgets also.
Now we can remove `user-avatar-block` id and added new class
'image_file_input'.we can access this class using
`#user-avatar-upload-widget .image_file_input` so that we can have
only one id at top-level and 'image_upload_widget.hbs`
can be more dynamic so we can use for other similar widgets also.
Now we can remove `user-avatar-block` id and add common class `image_block`.
we can access this class using `#user-avatar-upload-widget .image_block`
so that we can have only one id at top-level and 'image_upload_widget.hbs`
can be more dynamic so we can use for other similar widgets also.
Now we can remove the id `avatar-spinner-background` and access spinner
element from `#user-avatar-upload-widget .settings-page-upload-text` so
that we can have only one id at top-level and 'image_upload_widget.hbs` can
be more dynamic so we can use for other similar widgets also.
The upload text element is wrongly named as id=user_avatar_upload_button.
now we can remove that id and access upload text element from
`#user-avatar-upload-widget .settings-page-upload-text` so that we
can have only one id at top-level and 'image_upload_widget.hbs` can
be more dynamic so we can use for other similar widgets also.
we can remove `user_avatar_delete_button` id and access delete button
from `#user-avatar-upload-widget .settings-page-delete-button` so that
we can have only one id at top level and 'image_upload_widget.hbs`
can be more dynamic so we can use for other similar widgets also.
Renaming "user-settings-avatar" to "image_upload_button" since the
`user-settings-avatar` name is irrelevant/confusing for the upload
button, and converting the id into a class so that we could just have
only one outer id.
This changes the user avatar image display implementation to more
closely match how the realm icon and realm logo image features are
structured. This is early preparatory work towards sharing this code
between the various widgets.
The previous commit introduced a bug where it was not intuitive
for the user to scroll again.
For the current narrow, new messages were fetched again only when
scrolled to the bottom as usually there are many messages displayed.
However when the edge case mentioned in the previous commit
occured, it was not very obvious that a scroll should be done
or we could already be at the bottom and could not scroll again
to trigger a fetch.
`message_viewport.at_bottom` has a relevant comment explaining
this behaviour.
The previous commit handled the rare race condition. However,
there is a possibility that the rare race condition might occur
again while we are handling the previous condition.
This commit resolves these 2 problems by performing a re-fetch
while also resetting the `expected_max_message_id` and this
approach has two benefits:
1. The reset prevents an infinite loop, if somehow the expected
max message's id gets corrupted resulting in a situation
where the server can never send an id greater than that even
after fetching.
2. Even though we stop after just one re-fetch the race condition
might recursively occur while we handle the previous race
condition. And even though the reset prevents multiple re-fetches,
we don't have the missing message problem.
This is because we treat the next race condition as a new race
condition instead of it being a continuation of the previous.
The `expected_max_message_id` gets updated again, on receiving
a new message. Thus it can again enter the `fetch_status` block
as the reset value is updated again.
If a user sends a message while the latest batch of
messages are being fetched, the new message recieved
from `server_events` gets displayed temporarily out of
order (just after the the current batch of messages)
for the current narrow.
We could just discard the new message events if we havent
recieved the last message i.e. when `found_newest` = False,
since we would recieve them on furthur fetching of that
narrow.
But this would create another bug where the new messages
sent while fetching the last batch of messages would not
get rendered. Because, `found_newest` = True and we would
no longer fetch messages for that narrow, thus the new
messages would not get fetched and are also discarded from
the events codepath.
Thus to resolve both these bugs we use the following approach:
* We do not add the new batch of messages for the current narrow
while `has_found_newest` = False.
* We store the latest message id which should be displayed at the
bottom of the narrow in `fetch_status`.
* Ideally `expected_max_message_id`'s value should be equal to the
last item's id in `MessageListData`.
* So the messages received while `has_found_newest` = False,
will be fetched later and also the `expected_max_message_id`
value gets updated.
* And after fetching the last batch where `has_found_newest` = True,
we would again fetch messages if the `expected_max_message_id` is
greater than the last message's id found on fetching by refusing to
update the server provided `has_found_newest` = True in `fetch_status`.
Another benefit of not discarding the events is that the
message gets processed not rendered i.e. we still get desktop
notifications and unread count updates.
Fixes#14017
This commit removes is_old_stream property from the stream objects
returned by the API. This property was unnecessary and is essentially
equivalent to 'stream_weekly_traffic != null'.
We compute sub.is_old_stream in stream_data.update_calculated_fields
in frontend code and it is used to check whether we have a non-null
stream_weekly_traffic or not.
Fixes#15181.
We refactor these 2 notices to match with the loading indicators,
thus they have been moved to `message_scroll.js`.
After a successful message fetch, we have logic to decide whether
we want to display the notices and also whether we want to hide
the loading indicators (which are already displayed).
We also conservatively hide the notices similar to the indicators
every time we narrow.
The only exception is that we show the history limit notice on
deactivating the narrow (visiting `home_msg_list`).
Since on narrowing we call `load_messages_for_narrow`,
which fetches both top and bottom messages, two loading
indicators were temporarily displayed.
This was also the case for the `home_msg_list` when we
call `mesage_fetch.initialize` on startup.
To resolve this we do not display the bottom loading
indicator (for new messages), if the older messages
are being fetched too. This is only for the initial
narrow change, and the bottom loading indicator will
be displayed correctly when the user is at the bottom.
This fixes a regression introduced when we added bottom loading
indicators at all, which was temporarily reverted in
67053ff479 before being restored in the
last couple commits.
This commit makes the `loading_older_messages_indicator` similar
to the `loading_newer_messages_indicator`.
Now all the decisions about whether to show a loading indicator
will be made from the `fetch_status` API. We still hide the
indicators everytime the view is changed, as explained in the
previous commit.
As explained in 67053ff479,
multiple message fetches may be taking place at the same time.
So some other narrows / the home message list's indicator might
get shown for the current narrow.
This commit moves the updation of the indicators display logic
to the `fetch_status` API.
Now the `loading_newer_messages_indicator` gets displayed along
with the `loading_newer` = true updation for that narrow's message
list, i.e. just before we send the API request. But only if the
message list we are fetching matches with our current message list.
The same indicator is hidden similarly, along with the
`loading_older` = false updation for that narrow's message list,
i.e. just after the success response is recieved. But only if
the message list whose data we recieved matches with our current
message list.
Also the indicators are hidden everytime we activate narrow
or deactivate narrow (`home_msg_list`). And on entering
`narrow.activate` we fetch for it's messages so they get
displayed again, if need be.
This is the reason `message_scroll.hide_indicators();` was
moved to a location above `fetch_messages`.
Fixes#15374.
This commit actually just deletes the `get_default_suggestion`
function while the `get_default_suggestion_legacy` function's
logic remains the exact same, it is just renamed.
Since the operator can never be undefined as mentioned in the
previous commit, we do not require the check with undefined
and as a result the, `if (suggestion)` condition can be removed.
The 3 changes made here are as follows:
* The if block for both the functions is simplified as
`Filter.parse` will always return an array and also
[].slice(0, -1) === [] is true.
* The code where `base_operators` is declared is moved
to just before where it is actually used.
* The `base` variable declaration is changed to match
the pattern of that present in the non-legacy function.
Its value remains the same.
This is a prep commit for when we want to merge the
`get_search_result_legacy` and `get_search_result` functions.
This is the exact same bug as observed in
02ab48a61e.
The bug is in the way we invoke `Filter.parse`.
`Filter.parse` returns a list of operators which
can contain only one 'search' term at max.
All strings with the 'search' operator present
in the query are combined to form this 'search'
term.
However on concatenating two filters we may get
two terms containing the 'search' operator. This
will lead to the search suggestions getting
generated based on only the last 'search' operator
term instead of all the terms having the 'search'
operator.
This is evident from the test change as suggestions
should be based on "s stream:of" but instead they
were based on just the latest query.
In commit 35c8dcb599 we introduced the
`_stream_params` object within filter.js but we didn't correctly
handle cases where `_stream param`s is undefined within `get_title()`,
`generate_url()` and `get_icon()`, which cause the navbar to if eg a
guest user tries to access a stream they weren't subscribed to.
This commit fixes this by:
* Adding the relevant checks
* Adding node tests that include non-existent streams.
* Adds the 'question-circle-o' icon for non-existent stream narrows.
A side note here is that "non-existent streams" fall under
"common narrows" as per our current definitions, which doesn't really
make sense but shouldn't bother us.
Fixes: #15387.
This commit adds translation tags to a few user facing strings which
weren't translated prior:
- "Unknown streams" text and description.
- "All messages" heading.
- Tooltip text for precise count of subscribed users.
The numeric count itself is not translated, because we do not do
similar anywhere else in the UI.
We simply pass the visible message ids to remove_and_rerender
which supports bulk delete operation.
This helps us avoid deleting messages in a loop which freezes the
UI for the duration of the loop.
Fixes#15285
This event will be used more now for guest users when moving
topic between streams (See #15277). So, instead of deleting
messages in the topic as part of different events which is
very slow and a bad UX, we now handle the messages to delete in
bulk which is a much better UX.
This commits adds restriction on admins to set message retention policy.
We now only allow only organization owners to set message retention
policy.
Dropdown for changing retention policy is disabled in UI for admins also.
This commit adds the code to disable deactivate organization button
for admins. We now allow only owners to deactivate the organization.
The backend implementation for allowing only owners to deactivate
is already added in 81c28c1.
This commit adds the restriction of deactivating owners for admins
by disabling the deactivating button in the UI. Only owners are
allowed to deactivate other owners. The backend part of this is
already implemented in 86b52ef.
This commit adds the option of owner role in user role dropdown
and also takes care of the restrictions while adding/removing
owner status of the user.
This commit also handles the places where we dispaly role of
the user in UI.
The changes made here are as follows:
* We rename `show_history_limit_message` and `hide_history_limit_message`
to `show_history_limit_notice` and `hide_history_limit_notice`
respectively.
* We rename `hide_or_show_history_limit_message` to
`update_top_of_narrow_notices` as now this function is responsible
for updating the history limit notice as well the end of results
notice.
* We extract 2 functions responsible for hiding and showing the end
of results notice, similar to that of the history limit notice.
All instances of `$(".all-messages-search-caution").hide();` are
replaced with the call of `hide_end_of_results_notice` function.
The streams:all advertisement notice in search should only appear
after all results have been fetched to indicate we've gotten to the
beginning of the target feed.
The notice gets hidden at the start of `narrow.activate` and is
shown just after we've fetched an older batch of messages if the
"oldest" message has been found.
Previously it would get displayed after the first fetch which
takes place from `narrow.activate`. Thus we move this logic to
`notifications.hide_or_show_history_limit_message` which gets
called after a successful message fetch.
Since the home message view contains all the messages we are not
required to display this notice. However if it is already shown
we hide it as a part of `handle_post_narrow_deactivate_processes`.
To accomplish this we need to add `has_found_oldest` key to the
`fetch_status` API.
We also removed the `pre_scroll_cont` parameter as this was it's
only use case and is now redundant.
On update_message events, we were changing narrow before we
locally updated the data, this resulted in a weird mismatch
between locally available data and that fetched from the server.
Ideally, we should not be requesting any data from the server
in most scenarios since the messages for new narrow is
locally available.
As a result, the new narrow didn't have any messages other than
a breadcrumb message. To fix this, we change narrow post
locally updating the data.
The original bug was not exactly reproduced, but a similar version
of it was simulated and was found to be fixed.
Tweaked by tabbott to preserve an optimization.
This ensures that we do this fetch, which is intended to get data on
the pre-event state, before we start perturbing the message list data
structures via rerendering.
Apparently iamcal/emoji-data has a dedicated category for flag emojis.
And get_all_emoji_categories() in emoji_picker.js doesn't return the
Flags category, because we haven't declared that category in our emoji
data logic.
Note that the category looks quite sparse because it lacks country
flags, since we don't yet support emojis combined with a Zero Width
Joiner (ZWJ) (see #992 & #11767).
Fixes#15303.
In the very common event that one ends up looking at not the home view
while the browser is catching the home view up, this ended up
resulting in loading indicators being displayed at the bottom of
whatever narrowed view one was looking at incorrectly.
A proper fix for this will involve making these loading indicators
conditional on what view one is looking at. Since one can change
views rapidly from a narrowed message list to the home view (and in
the future, between narrows), probably the best approach would be to
move the state in `message_scroll.js` the state for whether a loading
indicator is expected to be shown into the `fetch_status` data
structures, and then make all decisions about whether to show/hide a
loading indicator be calls to a function with a name like:
current_msg_list.data.fetch_status.update_newer_loading_indicator()
At least, that's probably what we should call in places like
`narrow.deactivate()`.
Before 77a26d41ae, there was only one
loading indicator (at the top of the page), so the if/else logic for
hiding loading indicators was correct, if confusing. Since we've now
added a new bottom-of-page loading indicator, it's important to have
the logic correctly reset the state to hide all existing loading
indicators on narrowing, and then just render the ones needed/desired
by the current view.
Combined with similar code in `narrow.deactivate`, this achieves the
goal that we correctly update loading indicator state when switcing
views.
This deduplication helps with readability.
Pass get_topic_key in recent_topic_row instead of
computing it in DOM.
Fix broken test_update_unread_count
after this change. This was a regression
which went unnoticed.
We extract stream_edit.rerender to make
the live-update code easier to follow.
The function should eventually be inlined,
but I want to clean up some other stuff first.
These are basically shims for some deeper refactorings.
I basically just try to make the code express the
problems more clearly:
- use stream_name instead of sub
- make early-exit more explicit
- make it clear that add_subscriber needlessly
requires a name
- make it clear we have an unnecessary loop
I also fixed some phony data in the test.
We are trying to phase out the trigger-event way
of telling modules to do something.
In this case we not only remove the indirection
of the event handler, but we also get to remove
`compose_fade` from the `ui_init` startup sequence.
This also has us update `compose_fade` outside
the loop, although that's only a theoretical
improvement, since I don't think `peer_add` events
every actually include multiple streams.
To make the dispatch tests a little flatter, I
added a one-line change to zjsunit to add
`make_stub` to `global`.
To manually test:
* have Aaron reply to Denmark (keep compose box open)
* have Iago add Hamlet to Denmark
* have Hamlet unsubscribe
Previously, the navbar failed at managing the searchbox text state in
cases where, eg, the user performs navigation by browser history.
This commit resolves the issue by ensuring that the searchbox text is
only (and always) set when the searchbox is made visible, and as such
there is no "state" to manage and we will always display the correct
text.
It also adds a test in `search_legacy.js` to make sure that the search
text is placed as intended.
Fixes: #14771.
The navbar currently fails at managing the searchbox text state in
cases where, eg, the user performs navigation by browser history.
This is a prep commit that will help resolve the bug.
I tried to make the most minimal change here
possible, since I don't really know this module
well. Possible alternatives were:
* $('#tab_bar') everywhere
* elem
* tab_bar_elem
I don't feel strongly.
Long term I believe we intend to change the name
of this module to something more like `navbar.js`???
When we call functions inside our own modules that use
the `window.foo = exports` pattern, we have always had
a pretty strong preference to call `exports.internal_function`
instead of `foo.internal_functions`.
The stragglers here weren't violating this convention
for any intentional reason. Some of the places here
probably were part of code moves where somebody
(probably me) moved functions into the modules to avoid
unnecessary indirection, and I missed a spot where I
could change from `presence` to `exports` (or whatever).
And other places are probably just kinda arbitrary
decisions by the original developer, and we just haven't
bothered to clean it up until now.
This combines `upload_realm_logo` and `upload_realm_icon` into single
function called `upload_realm_logo_or_icon`. The functions wer near
duplicates.
Additional refactoring should be able to deduplicate the logic further.
Part of #14730.
We can remove a {{theme_mode}}-settings class on the upload button
and access day/night from `.closest("realm-logo-section")`
so that only the outer ID differs between the two widgets.
Part of #14730.
Previously, renaming the stream would cause `colorize_tab_bar` to fail
because the search filter would provide it the old stream name and the
look up for the stream color would fail.
A quirk of how this system currently works makes it so that even
though the filter is set to the old stream name (and so becomes
inconsistent with the stream_data state) the `_stream_params` object
is maintained to be consistent with stream_data and as such can be
relied upon to find the correct color of the icon.
Previously the navbar did not live update the stream name correctly.
The correct behaviour was blocked on the `_stream_name` prop on the
filter object. The original purpose for maintaining this prop was
convenience, to reduce calls to `subs`, however, it would become
inconsistent with the value from `subs` on stream rename.
In this commit we add a call to `filter.fix_stream_params` in
`subs.update_stream_name`. This fixes live rerendering in the navbar,
despite the fact that searchbox in the nav (and the filter object via
`filter.operands("stream")[0]`) will still have the old name.
This is a slightly hacky way of masking some of the problems in the
Filter object. However, it should make do until we migrate to a stream
ID based state there.
Fixes: #14728.
Prior to this commit the icon in the navbar didn't live update to
reflect changes in stream privacy.
Here, we add a call to `tab_bar.render_title_area` in
`subs.update_stream_privacy()`, to enable live updates on the icon.
Fixes#14728.
The navbar currently does not live update the stream icon correctly
for changes in stream privacy.
One place where the correct behaviour gets blocked is on the
`_is_stream_private` prop in the filter object. We keep props such as
this for convenience, to reduce calls to `subs`, however, this prop
becomes inconsistent with the value we get from `subs` when the stream
privacy is updated.
In this commit we add a call to `filter.fix_stream_params` in
`subs.update_stream_privacy`. This change does not fix the live
rerendering in the navbar because we don't call redraw yet, but
it's a prep commit to towards that goal
The navbar currently does not live update the stream name or the icon
for stream privacy correctly.
One place where the correct behaviour gets blocked is on the
`_stream_name` and `_is_stream_private` props on the filter object.
We keep these props for convenience, to reduce calls to `subs`,
however, these props become inconsistent with the values from `subs`
when the stream is renamed or stream privacy is changed.
This refactor extracts out `get_stream_params` and `fix_stream_params`
methods as a prep commit towards correcting the problem, but does not
make any behavioural changes.
This is a prep commit for solving #14728.
A comment about the difficulties relating to live updating stream
names in the navbar was incorrectly placed within the function for
live updating stream descriptions in
023187b3f1.
This moves the comment to the right place.
We store the relevant data to hide/show a topic in the row itself,
and use jquery to hide/show it on filter change.
This also fixes search breaking the set filters.
This fixes the bug that message was undefined since we used to store
locally echoed message id and were not updating it after new message
id for the same message was received from the server.
We remove all trace of the old topic and reprocess all the new
messages in old and new topics.
process_topic_edit function was moved since it needs to be below
get_topic_row function.
We reuse the existing logic for displaying and updating stream color
from the stream left sidebar.
Tests fixtures were extracted and updated for this commit.
The approach that supposed to use this data was not implemented
and hence this data will no longer be used.
If this feature is implemented in future,
this data will still not be used since we would depend upon
starred_messages.js library to provide us the required information.
* Add action to mute topics.
* We don't need to store muted data per topic as previously planned.
* Moved launch topic test to the top so that they run on non-modified
data.
* Show an empty overlay of recent topics.
* Register click event to open recent topics.
* Launch recent topics on "t" keypress.
This is based on the draft overlay.
This is part of a refactor that aimed to remove /json/users calls,
as we can get all the information needed on people API.
Now, the list render for $users_table and $deactivated_users_table
uses user_ids instead of user objects, as the people API give us
a filtered list of active_user_ids and non_active_user_ids.
The populate_users function doesn't need to sort the list of
active and non-active users, because the list_render is called
specifying to sort users by their full_name.
Author: Clara Moraes Dantas <clara.moraesd@gmail.com>