On clicking a notification, the web app was not being narrowed to the
message topic on firefox. We now narrow to the message topic if a user
clicks on a notification. It was working correctly on Google Chrome.
Fixes: #5220.
Given a stream id, we now find list items using the internal
data structures we created when we built the sidebar, rather than
using a jQuery selector.
In pm_conversations.js, added function to make a user a PM partner and
another function to check if a user is a PM partner. A PM partner is
someone with whom the user has been in a PM with.
In recent_senders module, added a data structure to hold timestamps of
users' latest message in a topic. Also added a function to compare 2
users based on above timestamp. Added a function to process messages for
the data structure and a call in add_message_metadata. Also added node
tests for insertion of data into recent_senders.senders.
Realm emojis uploaded before the migration to store the emoji author
information was done don't have any author information. Such emojis
if listed on the settings page caused a traceback.
Fixes: #5133.
This fixes a regression where we removed a call to
unread_ops.process_visible() inside of stream_list.js. Now
we call it from within narrow.activate() in the the
maybe_select_closest() callback.
When the emoji settings page was reopened after uploading a realm
emoji without doing a page refresh, the uploaded emoji disappeared
from the emoji list. This was so because the emoji settings page uses
`page_params.realm_emoji` to render the emojis which was not updated
when a emoji was added.
Fixes: #5130.
This change should lead to clearer tracebacks when our
assumption about the stream list's list items get
violated, and we also short circuit some code in the
caller that tries to scroll to the active stream.
In stream_list.js we have some code to handle narrow activations,
and we were calling unread_ops.process_visible() only for
stream activations, not for PM-related activations, etc., so
our approach was inconsistent.
It also turns out that the call is redundant, since we call
unread_ops.process_visible() when the message pane scrolls as
part of updating the content.
Ideally, we want a more rigorous approach where we make this
call precisely when the new messages become visible to the user,
but the purpose of this fix is to de-clutter the stream_list
logic.
This makes it possible for Zulip administrators to delete messages.
This is primarily intended for use in deleting early test messages,
but it can solve other problems as well.
Later we'll want to play with the permissions model for this, but for
now, the goal is just to integrate the feature.
Note that it saves the deleted messages for some time using the same
approach as Zulip's message retention policy feature.
Fixes#135.
If a realm is configured to allow any user to upload a realm emoji
then that user should also be allowed to delete the emoji in case
he feels it doesn't look good or if he uploaded a wrong emoji file.
This commit tweaks the realm emoji settings UI to allow an user who
uploaded an emoji to delete it.
Fixes: #4761.
This moves all the code dealing with emoji_picker
navigation and click/enter events to emoji_picker.js.
Some of the code still delegates back to reactions.js
in some way.
The navigate() code really does nothing reaction-specific,
nor does filter_emojis(), nor do some of their helpers.
This was mostly moving code, but I also did some
s/reaction// or s/reaction/emoji/ in names.
We now call the function toggle_selected_emoji(), and it
is simpler in these ways:
* We get the selected emoji more directly.
* We reuse code in toggle_emoji_reaction().
This change sets us up to de-duplicate some code. It
changes behavior for the edge case situation where
you had the reaction menu open but then decide to
click on one of the existing reactions. This change
closes the emoji popover, which is probably the
correct behavior.
This commit splits out some helper methods to make it easier
to test:
get_reaction_section
find_reaction
get_add_reaction_button
update_existing_reaction
insert_new_reaction
timerender.js render_now() will always include older
years when rendering the date stamp on the recipient bar
and the date rows above messages.
Fixes#4843.
The render_now() function in timerender.js will now return
an object instead of an array, which is then passed to the
functions render_date_span() and update_timestamps().
This should increase readability and extensibility.
Fixes#4820.
This commit de-couples the PM code from Group code. It also
simplified some code related to finding parent elements by
both introducing local variables and removing unnecessary
selectors.
Create property_types object for realm settings. In set_up function,
iterate over property_types to find settings that were updated, send those
new values to the server, and report that the changes were made.
This fixes the reactions to not break a new line by changing them from
a weird combination of “float: left” and “display: block” (inlined), to
just “display: inline-block”.
With fixes from Harshit Bansal for an issue with using the hotkeys in
a filtered popover.
Fixes: #4818.
Previously, the way the organization description textarea was
generated, there'd be a newline and ~12 spaces added each time on
reloaded the page and hit "save changes".
This change makes it so that the organization description only changes
when the user actually changes it.
Apparently, there were not correctly disabled if you clicked on
"authentication methods" after opening the settings UI another way.
Everything worked fine if you just clicked them, already.
Due to differences between the codepoints of flag emojis in
`emoji_map.json` and iamcal's dataset, we need to patch the
css classes for the flag emojis temporarily until the migration
to iamcal's dataset is complete inorder to render them properly.
There is a difference between the images of flag emojis in our
old emoji farm and iamcal's spritesheets and since we have not
yet switched to using spritesheets for displaying emojis in
messages, there is a difference between the flag emojis as
rendered in messages and in emoji pickers.
This reverts commit c7f710b8d4.
Because the back end still stores muted topics fundamentally using
stream name as a key, trying to cut over the client to use stream
id was just making things more brittle. Mutes would work after
renaming the stream, which was progress in the change that we
revert here, but only until page load. The other problem, which
is more severe, is that the order of page loading functions would
cause no mutes to happen at page load time. This could be fixed
to some degree, but we should do a deeper fix on the back end.
We should be able to eventually further clean this up to do nothing,
since we now don't have tabs over than the home tab. But I'm leaving
that for a future issue.
These date from long before the settings UI was restructured as an
overlay. Now, instead of ensuring that error messages are visible,
they just scroll the message feed incorrectly.
Fixes#4810.
There's no advantage to doing a small batch size towards current here,
since latency isn't an issue at this point, and performance on the
server side generally favors larger batch sizes.
This also will make it significantly harder to start getting 429 rate
limiting errors when loading when far behind current.
A formal date string will be assigned to the title attribute of the
recipient_row_date and date_row elements.
e.g. Wednesday, April 5, 2017.
Fixes#4663.
When you create a stream, there was always an "Announce stream"
option that would be enabled for public streams.
We are about to make it so that we never send PMs to announce
new streams to folks, so the only mechanism will be sending a message
to the realm's notification stream. If a realm has no notifications
stream, the decision is moot, so we hide the option.
If you were narrowed to an unpinned stream, and then pinned it,
we were mostly redrawing the sidebar correctly, but we weren't
setting the active-filter class. Now we accomplish this by
calling maybe_activate_stream_item(), which also reduces some
code duplication. (The new code introduces a bit of extra logic
to do `stream_li.addClass('active-filter')`.
This commit changes the key for recent_topics to be a
stream id. For streams that have been renamed, we will now
get accurate data on recent topics and active streams as
long as stream_data.get_stream_id(stream_name) returns a
valid value.
This commit changes stream_data.in_home_view() to
take a stream_id parameter, which will make it more
robust to stream name changes.
This fixes a bug. Now when an admin renames a stream
you are looking at, it will correctly show itself to
be un-muted. (Even with this fix, though, the stream
appears to be inactive.)
Some callers still do lookups by name, and they will
call name_in_home_view() for now, which we can
hopefully deprecate over time.
Rather than having get_stream_li() look up stream id using
stream name, we force the callers to pass in the stream id.
This adds an extra line to most of the callers for now, but
this will eventually change as we fix some of the callers to
have their callers pass in stream_id.
In places where we now call stream_data.get_stream_id() to
get the stream id, we will be more resilient toward stream
renamings, at least until the next reload, since
stream_data.get_stream_id() can resolve old names that
are stored when we process stream-rename events.
We no longer have get_stream_li() delegate to get_filter_li(),
which simplifies the logic in get_filter_li() and makes
get_stream_li() more direct.
We also move the two functions closer to each other in the file.
Using get_name() is more robust for stream name changes. This
fixes, for example, the situation where you narrow to a stream,
edit it via the sidebar, and then close the modal, and the message
redraw logic thinks you have unsubscribed.
Fixes#4686.
This change fixes a few small things related to stream
renames, such as what happens if you hit the back button
to go to a narrow where the stream had been renamed. You
will now get the correct behavior in terms of filtering
and searching. Unfortunately, this will only last until
you reload.
We now use stream ids to filter messages in narrowing
situations, instead of doing stream name comparisons.
This partially fixes certain stream-renaming scenarios, since
we will be able to match the stream id for an out-of-date
stream operand, but it doesn't fix some other stuff, such
as the query that the server gets.
This is not a user-facing change, but it starts us down the
path to having the JS client be able to look up old stream
names for situations like people clicking old external links
or for live-update scenarios.
The search bar for picking message reactions now is case-insensitive,
since that's a better user experience, and there isn't a clear use
case for capital letters in emoji names.
Fixes#4666.
This is a much less annoying behavior than the Chrome browser default.
Explanatory comment added by tabbott, thanks to Steve Howell for the
research.
Fixes#4604.
Both callers to get_user_list_for_message_reactions() already
had a message object, so there was no need to pass in an id
just to fetch it from message_store again, so now the first
parameter is message, not message_id.
This adds the current_user_has_reacted_to_emoji() helper.
This new helper is easier to use and slightly more efficient
than calling get_user_list_for_message_reaction() and then
indexOf().
This also replaces one call to get_user_list_for_message_reaction()
with a list of user_ids that we already had locally.
The node tests were improved a bit here, including a minor
whitespace fixup.
We used to render the subscriptions_settings template for every
stream when you loaded "Manage Streams," which can be very slow
for a big realm. Now we only render the right pane on demand.
The function stream_data.add_admin_options() got removed as
part of a somewhat recent fix. This caused a console error, and
the modal would not go away.
We now call the new stream_data.update_calculated_fields().
This commit only addresses the recent regression. We still have
the known issue that public/private changes do not get
live-updated for other users.
This is a follow-up to merging the compose and reactions emoji
pickers. The logic for what happens when the user picks an emoji via
the hotkeys (i.e. hits `enter`) was still attempting to add a reaction
to the currently selected message unconditionally.
This commit adds a check in the two `enter` key code paths, and does
the correct thing in each case.
Fixes#4736.
The click target was still for #hamburger even though it has since
been changed to .hamburger. This fixes the selectors to make it work
with the new className declaration over ID.
Rather than checking every modal individually in hotkey.js for
handing the escape key, we now use the modals API:
is_active: says whether any modal is open
close_active: closes the active modal
We were mapping the escape key to fake-click a redundant
click handler when the settings pages were open. This fix
lets the actual click handling work via modals.js, and it
lets keyboard handling directly calls modals.close_settings().
This is one of the last major endpoints that were still done in the
pre-REST style.
While we're at it, we change the endpoint to expect a stream ID, not a
stream name.
This commit removes all references to feature_flags.local_echo.
It's been a core feature for about four years, so I think we
can safely say the experiment was successful.:)
The function modals.is_active() can see if modals are open
without having to look at the DOM. This should make it snappier
to type in the compose box. Even if the speedup is pretty minor,
not having to worry about jQuery slowness should make it easier
to diagnose future compose box issues.
The new function gets used in other places, too, where performance
isn't so much an issue.
The list_render class "list" prop was immutable so when the
data prop would be updated it would not appropriately update
the data inside the primary list for filtering.
This commit also fixes an issue where if a jQuery selection was
passed in, all the nodes rather than just the first get copied over.
This doesn't completely fix settings responsiveness, but it's a big
step along the way. Outstanding issues include:
1. When switching tabs from settings to organization, it will launch
the first item which is more annoying in this view since it brings you
into that tab. Haven’t decided on an elegant solution to this yet.
2. Sidebar scrolling doesn’t work. I have to restructure how the top
section and bottom sections of content are displayed to fix this.
Likely by enforcing min-height of 100% - bottom height on the top piece.
3. Most of it is actually reasonably responsive but some isn’t, and
should be fixed on a case-by-case.
This focuses the body content of the informational overlay after
going to it from "?" so that you can use up and down arrows to then
scroll the content easily.
Fixes: #4480.
This was a regression introduced in ba7b7a9. The ID of the
edit boxes were changed in that commit, but this event
listener was not updated to reflect that.
This fixes an issue where browsers without local storage (aka the
Zulip ancient QT-based desktop app) would throw an exception trying to
reload in modern Zulip.
Previously, we'd log an exception whenever an invalid hashchange
reload token appeared, which is probably a bit excessive given that
this can happen without anything being wrong.
We instead just log something for debugging in the blueslip log and
make sure the #reload hash is cleared.
This is the first part of handling an annoying race that would cause
us to try drawing the right sidebar using (in part) users that we
haven't learned about yet (because we were offline/suspended when they
were created, and we haven't quite realized our event queue is gone yet).
Without changing how we render emoji in messages or changing the data
set used for emoji names, this switches us to the superior
percentage-based system for choosing which emoji from the spritesheet
to select and the iamcal sprite sheets.
It requires some small changes to CSS to ensure emoji are centered
properly in the new design.
Based on Harshit Gupta's work on "Interrelated emoji infrastructure changes".
If we pin a stream, we now scroll up as needed to make sure the
stream is still in view after pinning it. (Note that we don't do
this in the un-pinning case, since users un-pinning stuff may be
doing cleanup on pinned streams they no longer care about.)
Fixes#1714.
When we activate a stream (or one of its topics), we now scroll
the sidebar so that the stream comes into view. We scroll it
just enough to get it to the top or the bottom, depending on
where it had been offscreen before.
- Add file_name field to `RealmEmoji` model and migration.
- Add emoji upload supporting to Upload backends.
- Add uploaded file processing to emoji views.
- Use emoji source url as based for display url.
- Change emoji form for image uploading.
- Fix back-end tests.
- Fix front-end tests.
- Add tests for emoji uploading.
Fixes#1134
This removes the old compose emoji picker in its entirety, changing
the few callbacks needed to launch the reactions-style emoji picker
instead and hook it up properly.
Callbacks for reactions and composing messages are distinguished by
selecting for, respectively, the .reaction and .composition classes.
Fixes#4122.
This moves the avatar_ fields in page_params to come from
register_ret. Unlike many fields, changing this had a bit of
complexity, because the avatar update events didn't actually contain
some of the details required for moving these into register_ret to
work correctly without races.
We fix that as part of this change.
Modified significantly by tabbott.
We used to have code scattered in multiple places to
calculate things like admin options, preview urls,
subscriber counts, and rendered descriptions for
streams before we rendered templates in the "Manage
Stream" code.
These are all consolidated into a new function
called stream_data.update_calculated_fields().
This is mostly code cleanup, but it also fixes a bug where
the "View Stream" button would not work for a newly created
stream.
This doesn't quite complete the goals of #4650, which has a plan for
how to remove this entirely, but it causes this problematic code to
now be contained to a very rare case.
Refactored significantly by tabbott just due to rebase age.
Fixes#3629.
Modified composebox_typeahead.js to recognize the triple backtick
and tilde for code blocks, and added appropriate typeahead functions
in that file and in typeahead_helper.js.
Additionally, a new file pygments_data.js contains a dictionary of
the supported languages, mapping to relative popularity
rankings. These rankings determine the order of sort of the
languages in the typeahead.
This JavaScript file is actually in static/generated/pygments_data.js, as it
is generated by a Python script, tools/build_pymgents_data.py. This is
so that if Pygments adds support for new languages, the JavaScript file
will be updated appropriately. This python script uses a set of popularity
rankings defined in lang.json.
Corresponding unit tests were also added.
Fixes#4111.
The function check_stream_existence() temporarliy got moved
to stream_create.js, and our call from compose.js was still trying
to find it in subs.js. Now we move the function to compose.js,
since we no longer use it stream_create.js.
This function is pretty dubious, and we may want to only check
for duplicate stream names locally.
When the user creates a stream, we no longer do a synchronous
check on the back end to find if the stream name already exists.
Instead, we only check our local data, which will prevent many
typical errors, and then we let the back end capture duplicates for
stream names that the client doesn't know about.
We also tone down errors when the stream name is blank--we
only whine about empty streams right before submitting the form.
Also, since our check for duplicate streams is less expensive,
we now capture the "input" event instead of the "focusout" event,
so that if you fix up the name to avoid a collision, you get more
immediate feedback.
When we do detect stream name errors, we conveniently focus the
text field to let the user correct the problem.
It's technically the number of users yesterday. Also, "number of active
users today" suggests something like daily actives today, whereas this graph
currently shows 2-week actives.
Fixes bugs of when multiple messages are being edited simultaneously.
Specifically, typeahead is no longer broken, copying messages to clipboard
is less buggy, and resizing is no longer
broken when multiple messages are being edited.
I changed the watch_manual_resize function to return the listener
functions it creates, and then these are used to remove the event
listeners before the edit box is hidden.
Reusing code from the main compose_message component so that resizing now
behaves correctly. This means that when the user tries to resize vertically,
the autoresize code is disabled, and the textbox reverts to manual resizing.
Fixes#4573
When you subscribe to a stream, we now set a newly_subscribed
flag on the object, and we return true during the is_active()
call.
This solves the problem that immediately after you subscribe, you
don't have any messages in the stream, so it would appear active
by our old criteria.
This is still something of a workaround, as once you reload, the
stream will become inactive again, unless other messages come in.
A more permanent solution here would be to have the backend
indicate newly subscribed streams to us (apart from the initial
event), but we may not really need that in practice.
The new logic has 4 tiers of priority:
* Whether a match is found in the name, start of description, middle
of description, etc.
* Importance to the user / activity -- more specifically, the order
used in the left sidebar. This means pinned streams first, active
streams, then inactive streams.
* Subscriber count: How big is the stream? Bigger is better.
* Alphabetical ordering is a final tiebreak.
Fixes#4508.
There is a mechanism to prevent a user from "clicking" on a message
if they drag over it, to allow people to copy message contents without
triggering the compose box to open.
In the case that a user would start dragging from outside a message
and finish dragging within a message, data on where the cursor started
at is missing.
This is fixed by checking if start data exists and if it doesn't, we
just throw a drag distance of Infinity which will tell the program to
not count the action as a "click" on the message. This now does not
have an uncaught error because it instead validates "start" as existing
before attempting to access its properties.
Due to a past refactoring, the from_reload argument to do_hashchange
changed from having true/undefined as the possible values to
true/false instead. The check that sets the from_reload and
first_unread_from_server narrow options was thus incorreclty treating
from_reload of false the same as a from_reload of undefined.
As a result, if the browser had been loaded with a
page_params.initial_narrow_pointer (aka via the background reload code
path), then for the duration of that browser session, every time one
narrowed via a hashchange rather than an explicit click handler (which
apparently includes clicking on a PM thread in the left sidebar), we'd
end up narrowing with a then_select_id of the that initial narrow
pointer, not the correct first unread message.
The fix is simply changing the check for truthiness, not undefined, in
do_hashchange.
Despite the length of this commit, it is a very straightforward
moving of code from narrow.js -> narrow_state.js, and then
everything else is just s/narrow.foo()/narrow_state.foo()/
(with a few tiny cleanups to remove some code duplication
in certain callers).
The only new functions are simple setter/getters that
encapsulate the current_filter variable:
narrow_state.reset_current_filter()
narrow_state.set_current_filter()
narrow_state.get_current_filter()
We removed narrow.predicate() as part of this, since it was dead
code.
Also, we removed the shim for narrow_state.set_compose_defaults(),
and since that was the last shim, we removed shim.js from the app.
This code makes the right pane work in "Manage Streams" when
you are editing a stream subscription. It handles basic
functionality (submitting forms, etc.), live updates, and
showing the pane as needed.
Most of the code here was simply moved from subs.js, but some
functions were pulled out of larger functions:
live update:
add_me_to_member_list
update_stream_name
update_stream_description
collapse/show:
collapse
show_sub
We also now export subs.show_subs_pane.
We eventually want stream_edit not to call into subs.js, and
this should be fairly easy--we just need to move some shared
methods to a new module.
This new modules handles the UI to create streams. It mostly moves
code from subs.js.
It introduces an API around what used to be called meta.stream_created:
reset_created_stream()
set_name()
get_name()
It only partially moves new_stream_clicked().
Note that this code is disabled until the infrastructure for the
feature can be finished.
Tweaked by tabbott to use slightly cleaner names for the various sets.
This commit forces the files that create modals to create their own
modal closing function instead of creating all of them in the modals
file. These functions are then passed to the modals.close object. This
is intended to remove modals.js's dependencies on these other files.
We now only call compose_state.composing() in a boolean context,
where we simply care whether or not the compose box is open. The
function now also returns true/false.
Callers who need to know the actual message type (e.g. "stream" or
"private") now call compose_state.get_message_type().
We now use "map" to have our inner generator of topics be
mapped to objects with both the stream and topic. Thanks to
Mahim Goyal for helping with this design.
This fixes a regression in 3041480600
that would cause anything rendered on the backend differently than on
the frontend to experience this animation.
We actually only want to do the animation when the message content was
changed in a way that generates an edit history event, i.e. a
user-facing edit, not in cases where we're either transparently
swapping in post-backend-rendering content (e.g. with link previews)
or cases where there's a discrepancy between the exact HTML from the
frontend and backend markdown processes (e.g. mentions).
The comments that were added in the code for this commit explain
the cases here, but essentially for topics, we need to decide
among a few possible behaviors with regard to composing:
- Leave it closed.
- Cancel the compose.
- Leave the compose box as it was before.
- Fill in the new topic.
Before this commit, we were cancelling compose in all cases (or
leaving it closed).
Now we leave it alone in some cases where there is already content.
And we fill in the topic when the stream was correct and the topic
was empty.
Fixes#3300
This fixes the /me elements to be display inline-block and inline
rather than display block with top and left properties.
This also fixes an unrelated issue with emoji reactions not being
able to be clicked on with /me messages.
Fixes: #4218.
When a message update comes back from the server and replaces an
old message, it should fade in. There are two components to the fade:
1. The message fades in from opacity: 0 => 1.
2. The "edited" text will transform from X: -10 => X: 0.
This commit extracts the method compose_actions.on_narrow()
to handle changing the compose box (as appropriate) after
any narrowing action.
This change should be mostly non-user-facing, but it's not
exactly a trivial extraction.
For the case where the user already had content in their
compose box, we continue to leave the compose box alone,
but we now update compose fading 150+ lines later in
narrow.activate().
Likewise, for cases where we cancel composing, this will
also happen later in the function.
Finally, for PM narrows, where we auto-open the compose box, we
no longer call compose.cancel() before calling compose.start(),
because either a) the compose box would have not been open
in the first place or b) the start() function can handle
clearing the old fields.
Before this change, we would move "dormant" streams to the bottom
of your stream sidebar, but only if you had 40+ streams.
Now we do this in all cases to be more consistent.
This commit also changes the redraw strategy when we remove rows.
Before this change, we were doing incremental updates, but now we
call build_stream_list to do a complete rebuild. This was partly
motivated by adding the new divider, which would have complicated
the incrememental approach when you removed the last remaining
dormant stream.
This creates get_emoji_at_index() and
find_index_for_emoji() functions, which search for
emojis and indices in reactions_show_list. Update
maybe_select_emoji with newly created functions.