This contains two more complex changes:
- The default versions of sorter and matcher assume that ItemType is a
string. But the Typeahead class works on a generic ItemType and I'm
not aware of a way to assert that this function is only called for
typeaheads with string items. For `matcher`, we can assert that the
items are strings. `sorter` is now a required option instead of an
optional one that could fall back to the default.
- `element` can be either an `input` element or a `contenteditable`
`div`. We distinguish between them using `.is("[contenteditable]"))`
but TypeScript doesn't understand that. So we replaced `this.$element`
with `this.input_element` where `input_element` is an object with the
`$element` and also a `type` specifying which type of element it is
(input or contenteditable).
The test data was not the correct representation of submessage's
content field. This caused the zod schema to throw error.
This is a temporary solution and eventually we have to move to an
efficient approach making the test data more representative and
accurate.
Discussion:
https://chat.zulip.org/#narrow/stream/6-frontend/topic/TypeScript.20migration/near/1766122
We sent entire 'events' array to 'widgetize.activate' and then
removed its first element(using .shift()); instead we should
send only relevant data ie. the entire array after the first element.
This also helps us avoid an extra check in node tests.
This was only used in the undocumented narrow_stream mode, and relied
on a deprecated synchronous XHR request.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
To increase the discoverability of the possibility of specifying the
language for a code block, we trigger the language typeahead when code
syntax is added using the code formatting button. A blank option is
shown preselected in the typeahead, so that pressing enter will not
mistakenly add a language to the code block.
We only trigger the typeahead on empty opening fences when added by the
button, by setting a state variable to true when adding the syntax using
the button, checking for this state when sourcing languages for the code
typeahead, and then resetting the state variable to false.
Fixes: #29150.
Uptil now, the `query_matches_string_in_order` function would respect
the order of words in the query string when matching a source string.
This meant that for query "two one", the source string "one two three"
would not be matched.
For more flexibility, a new function, `query_matches_string_in_any_order`,
has been added., which returns true if each word in the query string matches
the prefix of a distinct word in the source string, else it returns false.
The algorithm for computing this is quadratic in terms of the source word
count so can be a little expensive, but it is only currently used for
searching topics in Recent Conversations, where the strings' length is
limited by the max stream / topic name length allowed, so this should be
performant enough for this use case.
TypeScript does not check that these annotations are consistent with
the given selector strings. We need to ensure that ourselves for
runtime safety.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This fixes a bug where alert words that are contained in another alert
word would have only the smaller alert word highlighted.
Note that it does not handle weirder cases, like "one two" and "two
three" being alert words; "two three" will always be highlighted, and
not "one"; this is probably fine in practice.
Fixes: #28415
Co-Authored-By: danieldotcomcoder <daniel_shdeed@hotmail.com>
We redesign the message history modal to make it look similar to the
drafts and scheduled messages, using the shared styling/rendering
logic for that those existing elements to have a less goofy widget.
Fixes#28695.
Earlier in stream settings, filtering for streams by search stream
name would reset the right panel to default if a stream was selected
from stream row.
This commit fixes the behaviour by keeping the stream open in right
panel in stream settings even on any filter change.
To achive this the `stream_header_colorblock` div was removed from
`dropdown_widget_with_stream_colorblock.hbs` template. this change made
the file name irelevenet so it was necessary to rename the file to
`dropdown_widget_wrapper.hbs`. After removing the html strcuture for
colorblock from templates the css for colorblock was also removed.
followed by the javascript which was used to add colorblock to the
stream picker. After removing javascript tests were updated.
Fixes: #28796.
Whenever a setting that needs confirmation to save is tweaked, and the
save button is not visible, we scroll it into view, to ensure the user
does not mistake it for an automatically saved change and misses saving
their change.
Fixes: #29290.
Now we show the number of drafts that are addressed to the current
recipient selected in the compose box, if any, in the Drafts button
within parentheses (whether it is next to the Send button, or in the
Send options popover), and explain that it is the number of drafts for
this conversation in the tooltip.
Fixes: #28696.
Fixes: #29006
We make the following changes:
* Do not show the typeahead menu when there are no matching topics.
* When the typeahead is not shown, pressing Tab in the topic field
should move the cursor to the compose box.
* When the typeahead is shown, pressing Tab should select the
currently focused option (as it does now), but put the cursor at
the end of the topic, rather than at the beginning.
Whenever the user has text selected within a single message, and uses
the hotkey to quote and reply, this selection will be quoted. In case of
no selection or selection not within a single message, the entirety of
the currently focused message will be quoted like before.
Similarly, when the user selects text within a single message, opens
that message's actions menu, and clicks the "Quote and reply" option,
the selected text will be quoted. In case of no selection or selection
containing any other message/s, the entirety of the message whose menu
was opened will be quoted like before.
When partially quoting a message, it is the markdown version of the
selection that is quoted, hence preserving any formatting. Any other
elements of the message, outside of the content, selected presumably by
accident (like the timestamp or sender name), are ignored.
Fixes: #19712.
All existing typeaheads have values for highlighter that are one
of the following:
* render_search_list_item (a handlebars render function)
* render_typeahead_item which calls a handlebars render function
* another function in typeahead_helper which eventually calls
typeahead_helper
Earlier, streams were prioritised like this: pinned streams > subscribed
streams > other streams, with message volume serving as the tie breaker.
Now we prioritise them like: stream being composed to > pinned unmuted
streams > unpinned unmuted streams > pinned muted streams > unpinned
muted streams > unsubscribed streams, with the same tie breaker.
Fixes: #20618.
Only affects zulipchat, by being based on the BILLING_ENABLED setting.
The restricted backends in this commit are
- AzureAD - restricted to Standard plan
- SAML - restricted to Plus plan, although it was already practically
restricted due to requiring server-side configuration to be done by us
This restriction is placed upon **enabling** a backend - so
organizations that already have a backend enabled, will continue to be
able to use it. This allows us to make exceptions and enable a backend
for an org manually via the shell, and to grandfather organizations into
keeping the backend they have been relying on.
Since the html copied from VS Code is not structured as code but as
styled divs for each line, any code copied from it would be pasted
unformatted with blank lines between each line of code.
This has now been fixed, by detecting VS Code style code blocks by the
CSS property `white-space: pre` and pasting the text within as is, as
code.
We want to name types/views that are not Stream or Direct related to be
"non-specific". The previously used term "non-stream" could be confusing
since it would literally mean any type/view which is not a stream type/
view, which would encapsulate the Direct type/view also.
Thus, we finally use the following terms to describe the type of
conversation:
1. Stream type (Streams or Topics)
2. Direct type (A)
3. Non specific type (Inbox, Recent conversation, All messages)
This is essential for converting to typescript, because
we can't create half a clean reaction and then calculate
vote_text afterwards. Instead, we should calculate it
with the information we already have, and create the
clean reaction object afterwards, all at once.
On chromium browsers, the scroll position is not restored when the text
in a textarea is replaced. So instead of directly replacing the text,
we call the `insert_and_scroll_into_view` function with `replace_all`
set to true.
It was always being set after the fact, and it will
be easier to manage types for the conversion to
Typescript if we just set this when setting the
rest of the data for the draft message.
Sometimes get_color is called with undefined
stream ids. This change makes more clear
what was already happening, and allows
for smoother conversion of other files
to typescript, including an upcoming
conversion of the drafts module, which
can call `get_color` with a draft with
undefined stream_id.
This keeps the color logic contained in
the `get_color` function, which seems
cleaner than the alternative of exporting
DEFAULT_COLOR to be used wherever sream_id
might be undefined.
Since the html copied from VS Code is not structured as code but as
styled divs for each line, any code copied from it would be pasted
unformatted with blank lines between each line of code.
This has now been fixed, by detecting VS Code style code blocks by the
CSS property `white-space: pre` and pasting the text within as is, as
code.
This commit adds a realm-level setting named
'zulip_update_announcements_stream' that configures the
stream to which zulip updates should be posted.
Fixes part of #28604.
It doesn't make sense for us to track a separate current filter when
it should just the be filter of current message list if there is one.
This will reduce possible confusion in the codebase where filter
returned by narrow_state is different from message_lists.current.
The `upload_objects_by_message_edit_row` map object was being exported
to handle the uploads during the editing of a message. To improve the
abstraction, we move the logic being used to access
`upload_objects_by_message_edit_row` and itself into `upload.js`.
Similarly, the `compose_upload_object` constant which was being exported
to handle the cancelling of compose uploads. This commit removes this
export and instead defines a new method `compose_upload_cancel` to
handle the same.
The work now being done in set_render_data used
to be done in render_more, which is called in
batches of 20 rows at a time. This work only
needs to be done once per narrow/view, so this
is a great performance improvement.
There were couple of problems in our handling of invalid or
incomplete URLs-
- The browser back button behavior breaks if someone enters
url with invalid group ID, incorrect group name.
- On typing group edit URLs with invalid group ID, an error
was raised and the URLs remained the same with just opening
the groups overlay with "Your" tab selected in left panel.
- On typing group edit URLs with incorrect right side tab or
without any right side tab, we showed "general" section, which
is fine, but the URL was still incorrect.
This commit fixes the above mentioned problems-
- URLs with invalid group IDs are now handled gracefully
with groups UI opening in the same way as before but the
url is updated to "#groups/your".
- We now update the right side tab to "general" if right
side tab is invalid or there is no right side tab.
- All the URL updates to fix invalid urls are done using
"history.replaceState" to make sure the browser back button
behaves as expected.
- All the code for checking the urls is done in hashchange.js
itself, so we can remove some code from change_state.
There were couple of problems in our handling of invalid or
incomplete URLs-
- The browser back button behavior breaks if someone enters
url with invalid or inaccessible stream ID, incorrect stream
name, "#streams/new" url without permission to create streams.
- On typing stream edit URLs with incorrect right side tab or
without any right side tab, we showed "general" section, which
is fine, but the URL was still incorrect.
This commit fixes the above mentioned problems-
- We now update the right side tab to "general" if right
side tab is invalid or there is no right side tab.
- All the URL updates to fix invalid urls are done using
"history.replaceState" to make sure the browser back button
behaves as expected.
- All the code for checking the urls is done in hashchange.js
itself, so we can remove some code from change_state.
The read receipts option, resides under the triple-dot message actions
menu. This made the process of viewing the read receipts take up
multiple steps, even via a keyboard-driven workflow.
Via this commit, now while focused on any message in a message feed,
and pressing `Shift` + `V`, efficiently brings up the read receipts
for that message.
Fixes part of #24716.
Co-Authored-by: SameepAher <sameepaher@gmail.com>
This was just debugging logic working around the fact that vdom.ts was
not originally implemented in TypeScript, and should not be polluting
our types.
This commit renames the realm-level setting
'signup_notifications_stream' to 'signup_announcements_stream'.
The new name reflects better what the setting does.
This commit renames the realm-level setting 'notifications_stream'
to 'new_stream_announcements_stream'.
The new name reflects better what the setting does.
Now whenever we initiate sending a message, we save / update its draft,
which is deleted on a successful send. Earlier, we did this only for
locally echoed messages. Hence a non locally echoed message's draft
would remain, if created in the timeframe between initiating send and
receiving the same message from the server, which can be significant
for slow connections.
For spectators, the chunk of page_params that originates from
do_events_register isn’t assigned until ui_init.js. That means the
TypeScript type of page_params is mostly a lie during module load
time: reading a parameter too early silently results in undefined
rather than the declared type, with unpredictable results later on.
We want to make such an early read into an immediate runtime error,
for both users and spectators consistently, and pave the way for
runtime validation of the page_params type. As a second step, split
out the subset of fields that pertain to the entire realm.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
For spectators, the chunk of page_params that originates from
do_events_register isn’t assigned until ui_init.js. That means the
TypeScript type of page_params is mostly a lie during module load
time: reading a parameter too early silently results in undefined
rather than the declared type, with unpredictable results later on.
We want to make such an early read into an immediate runtime error,
for both users and spectators consistently, and pave the way for
runtime validation of the page_params type. As a first step, split
out the subset of fields that pertain to the current user.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit extracts the edited notice computation logic of
edited_in_left_col, edited_alongside_sender and edited_status_message
to a new function - set_edited_notice_locations and calls it right
after the method merge_message_groups.
This is a preparatory commit, and is done since theses three variables
were previously wrongly initialized in the beginning for live messages
received.
We also introduce a modified flag to decide whether to display the
edited notice or not. This is useful since now we are computing
the edited notice values even when messages are not edited, and
hence we show the notices only when the modified flag is true.
The previous batch of improvements to this code path in
6562ea94e4 introduced a race bug where:
- You navigate to a narrowed view; Zulip renders cached data from
`all_messages_data` that we know is current, but
`fetch_status.has_found_newest` is initialized to `false`
nonetheless.
- The bottom is visible, triggering the check for whether the view
should be marked as read.
- `fetch_status.has_found_newest` is still `false`, and so we
incorrectly refuse to mark as read.
- We finish fetching data from the server, do the background rerender
for that (with no changes), but that doesn't trigger a re-check for
whether the bottom is visible.
There's several ways to address this, but most correct to me is to not
check fetch_status in this particular code path.
The same reasoning applies to the navigate.js call sites.
This should help reduce the risk of hitting rate limits when users
have a very large number of messages to fetch via this mechanism.
Inline the `messages` variable that was only used in one place while
we're touching this.
I was not able to reproduce obviously badly broken behavior from these
logic bugs, but after the renaming of message_viewport helpers in the
last few commits, it's clear that this logic was trying to check if
we're actually at the start/end of the possibly message feed, not just
the rendered portion, and doing so incorrectly.
So far, there were 2 separate turndown rules for code blocks; one for
general ones, and the other for Zulip message code blocks.
Now the filter rule has been generalised to handle both cases together.
As a side effect, the bug where partially copied Zulip code blocks
lost formatting on pasting has been fixed.
As discussed in the new comments, we had a bug where the
system-initiated animated scroll that happens when the compose box
opens as a result of narrowing would race with the internal
rerendering that occurs when the message_fetch request asking the
server for additional data returns.
The correct fix for this is just to open the compose box, if we're
going to do so, before setting the user's scroll position in the
narrowing/rendering process.
This ends up being a UI improvement (in that the compose box is
available for typing a bit earlier) as well as avoiding both the risk
of this race as well as the bad UX of adjusting the user's scroll
position multiple times as part of entering the view.
This does not address an as-yet-unknown bug wherein the animated
scroll that occurs when opening the compose box, when racing with a
background rerender, results in a bogus ending scroll position, though
it's easy to see how that might occur given that rerendering does
clear the DOM briefly.
Needed for typescript, because we want to preserve
types, so instead of mutating a message object,
we can instead calculate return these values
for a message object before it's created in full.
This commit also renames apply_markdown
to render, see this comment
https://github.com/zulip/zulip/pull/28652#discussion_r1470514780
Since notifications have limited space for the contents of a message,
a quote from a previous message, or elsewhere, can take up most of the
notification, leaving little room for the actual message, and reducing
the usefulness of the notification.
To fix this, we collapse blockquotes and "user said" paragraphs to make
space for the actual message.
From `get_current_nth_hash_section` `get_nth_hash_section()` is
extracted to allow for reuse for any hash. The indexing is also changed
to 0-based and negative indexing also works now.
This is a prep commit for the next, where `get_nth_hash_section()` will
be used in a new function with negative indexing.
Also, makes small updates to `next_plan_forms_support.html`.
Removes unneeded "btn" and "btn-default" classes, and updates
the placeholder text for the input as not marked for translation.
So far, when ordering typeahead suggestions, any query matches that did
not occur at the start of the target string were considered equally. So
for example, for the query "ok", "squared_ok" and "smoking" were
allotted equal priority, which does not make sense.
Now, matches from a word boundary (space, hyphen, underscore or slash)
are given priority (after exact matches and beginning matches), so that
in the above example, "squared_ok" is regarded as a better match than
"smoking".
Since recipients' sorting is complex, and needs word boundary matches
separately for decoupled sorting post triage, `triage_raw` is extracted
from `triage` to return the raw matches.
Fixes: #24127.
Though the correct mapping for Alt in Mac is Option, we had so far been
mapping it to Command, since for the 2 pre-existing shortcuts that used
Alt, Command was the only key that worked on Mac. However, these are
exceptions.
Now we map Alt to Option, and handle the 2 exceptions separately, using
data attributes on those shortcut elements.
This is a prep commit for introducing a hotkey that uses Alt / Option.
This will prevent any message we want to select after narrowing
from being offscreen entirely or partially.
Steps to reproduce the bug:
* `./manage.py populate_db -n 3000 --max-topics=2`
* Narrow to a stream and scroll high up.
* Align two recipient bars together with nothing between them.
* Click on the first recipient bar after keeping the selected message
on the second recipient bar.
* You will see that the selected message is not in view.
Fixes#26774.
We don't need the today argument anymore since every value passed to
it was a new Date() except the tests where we are using MockDate now.
All message view has `in-home` filter and is not empty.
If there are no terms provided, we set filter to display
all messages (including muted streams/topics).
We make it mandatory to provide terms to Filter.
For compose state variables `last_focused_compose_type_input` and
`message_type` that are assigned non-boolean values on user interaction,
`undefined` is the semantically better choice than `false` for
initialisation, to avoid incorrect boolean implications.
When pasting any code without any newlines, whether from a code block or
a code span, it will always be pasted as inline code.
That is, a line of code copied from within a code span will retain code
span formatting on paste, and a line of code copied from within a code
block will be pasted as inline code, instead of a 1 line code block.
Earlier, the tests for compose formatting were verbose, hard to read as
well as extend, and overly granular, without even having the ability to
test the final text selection or the cursor position.
Now, new test helpers, `init_textarea_state` and `get_textarea_state`,
have been added, enabling the tests to be more concise and readable,
while also being more powerful. A representative string alone now
describes the textarea state (the text and the selection / cursor),
making each test case as easy as defining the initial state as a string
and comparing the expected state post formatting with another string.
These new tests helped surface a couple bugs which have been fixed in
preceding commits.
Earlier, a new banner would be showed for each mention of the same
private stream in the compose box. This commit fixes that by checking
if the private stream warning banners already shown include the private
stream just mentioned, and if so, not showing a new banner.
This implementation is in line with the one for warnings for mentions of
users not subscribed to the current stream.
Fixes: #26914.
We previously allowed adding pills for inaccessible user by typing
the email manually. This commit updates it to handle inaccessible
users like we handle invalid emails.
Operand is a confusing name because this
data structure has an attribute *called*
operand. This commit renames references to
this structure to "term", short for "search
term".
For spectators, page_params.custom_profile_field_types has not been
initialized yet at module load time.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Some files already were using `noop` in place of `() => {}`.
It's both clearer what it means and is easier to type.
This updates all test files to fully use `noop`, and
adds a shared import from the test lib file.
The "user_group_name_dict" value for the old group name key
was not deleted and this led to a bug where the stream creation
UI was incorrectly showing about a user group already existing
with the old group name.
Fixes#28108.
This commit adds code to not show typing notifications for inaccessible
users as the user would not have any information even if we show them
as the name shown would be "Unknown user".
Inaccessible user names are shown as "Unknown user" in the
reacted users list and tooltip.
This commit removes the call to `is_known_user_id` since we
may have reactions data from inaccessible users. And it is
fine to remove the `is_known_user_id` call anyways, because
it was added to ignore showing reactions from deactivated
users when the client did not have data about them, but now
the client has data about deactivated users.
So we anyways do not expect unknown user IDs in cases
other than inaccessible users for which we have to show
the reactions by showing their name as "Unknown user".
This commit also updates the comment for "is_known_user_id"
function accordingly.
We do not update the name for mention pills of inaccessible users
and keep it same as it was in the message content, and we show
the "Unknown user" popover on clicking the pill.
This commit sets the client capability value to not pass
unknown users data in the webapp and also does some changes
to avoid errors while loading the web-app home page.
This commit only does some basic webapp changes to not show
inaccessible users in sidebar and we would need need more
changes to make the web-app work as expected which will be
done in further commits.
The "User groups" panel is now removed from settings overlay
and we instead use new "#groups" UI.
This commit also makes some changes to tests to ensure coverage
for pill_typeahead.js which was previously done by
settings_user_group_legacy.test.js. We have still not got
complete coverage on user_pill.ts as we have removed
settings_user_group_legacy.test.js, but we just add the file
to EXEMPT_FILS list for now and will handle it in future.
Fixes#28012.
Earlier, the event sent when an onboarding step (hotspot till now)
is marked as read generated an event with type='hotspots' and
'hotspots' named array in it.
This commit renames the type to 'onboarding_steps' and the array
to 'onboarding_steps' to reflect the fact that it'll also contain
data for elements other than hotspots.
We have already fixed the actual bugs that were resulting in client
receiving presence data for unknown user, so we can remove the
blueslip logging and just skip the unknown users.
To extend the drag and drop upload area to blank areas after sidebars,
we now detect the drag/drop event on the entire ".app" division.
We also change replace `width` and `height` css properties with
`min-width` and `min-height` properties respectively, to make sure
that the ".app" div spans the entire width and height of the viewport.
Fixes: #27550.
When a user is replying to a message while in a search view, we now warn
them that the full conversation is not visible and urge them to go to
the conversation they are composing to, so they can see the complete
conversation. On narrowing to that conversation, the banner is removed.
Fixes: #25893.
This fixes a very rare exception seen in production, which the
previous assertion allowed us to understand was possible in a rare
race, now documented in comments.
Earlier, when a topic had less than 15 participants,
the @-topic typeahead was not visible. It should be visible
irrespective of the 'realm_wildcard_mention_policy' setting
when the participant count is not greater than 15.
The participant count for a topic can't always be calculated
accurately in the client as some of the messages might still
be loading.
We show @-topic in the typeahead whenever it might be possible
to use it.
We will give an error later if you aren't allowed to use it.
Fixes#27852.
This prep commit renames:
* 'stream_wildcard_mention_allowed_in_large_stream' to
'wildcard_mention_policy_authorizes_user' because the function
checks if the sender is allowed to use wildcard mentions based
on the 'wildcard_mention_policy' setting, and we plan to use that
for topic wildcard mentions too.
* 'stream_wildcard_mention_large_stream_threshold' to
'wildcard_mention_threshold' because this value is going to be
used as a threshold value for the max number of subscribers and
participant count allowed for stream and topic wildcard mention
respectively.
Earlier, for the desktop notifications having latex math
like "$$1 \oplus 0 = 1$$, the notification had the math
included multiple times.
This commit fixes the incorrect behavior by replacing
the KaTeX with the raw LaTeX source.
Fixes#25289.
This commit introduces non-intro hotspots.
They are a bit different than intro hotspots in the
following ways:
* All the non-intro hotspots are sent at once instead of
sending them one by one like intro hotspots.
* They only activate when a specific event occurs,
unlike intro hotspot where they activate after the
previous hotspot is read.