So the top navbar is above the left sidebar
on the z-axis, not the y-axis.
So it doesn't make sense to use the top
navbar in calculating the size of the left
sidebar.
It kind of coincidentally works, since these
two numbers are closely related:
left sidebar top margin = 50
navbar height = 40
Calculating `bottom_sidebar_height` correctly
decreases its value by 10.
And then the only value that depends on it
is `stream_filters_max_height`. We were
subtracting out 10 there to make it work,
since `bottom_sidebar_height` was inaccurate
by +10. Now that's fixed.
The comment there was inaccurate--the
`stream_filter` div actually has a bottom
margin of 22px. The bottom margin does
have some consequences for scrolling,
but the main goal here is to make the
calculation return the same value but
be more accurate about what happens
toward the top of the screen.
We have always intended to have 10px of whitespace
below the navbar, and this enforces it directly
and explicitly in the CSS.
Note that the three major panels still should
have a margin of 50px, which is equal to
the safe outer height of the header (40px + 10px).
The border makes the alignment look nicer. Without
a border your eyes plays tricks on you and makes it
seem like numbers are not in the same column.
The border color is the same subtle color as the
backgrounds in others.
Because CSS is annoying, you have to tweak the padding
to make room for the border.
(It should look ok in night mode, too.)
Since the main autoscroll feature was implemeneted, the
maybe_advance_to_recently_sent_message logic had an unfortunate
structure, where the code for this potentially large scroll was
running AFTER the autoscroll decision was made, but before an actual
scroll could have occurred.
This resulted in code that was very difficult to reason about, as
there were 2 potential sources of scrolling when you send a new
message, with little connection between their implementations either
in location or implementation.
Moving this into the main autoscrolling code path clarifies the code,
with the added benefit of fixing a bug where we would report to the
user that they needed to scroll down when in fact we were just about
to scroll the bottom of the feed into view (via
maybe_advance_to_recently_sent_message).
With this change, we never display the "you need to scroll manually"
message in the cast that we just scrolled you there via selecting a
message.
When you just sent a large message, our logic for "you need to scroll"
notifications did not correctly take into account the height of the
compose box. This was easily reproduced when sending very long
messages. The correct solution requires a bit of math to compute what
the visible area will look like after the compose box is closed.
This should be the final fix to #11138.
This adds a function that controls the whole process of applying
markdown and displaying the markdown rendering preview on request;
This is required to avoid code duplication when adding preview feature
to message-edit UI.
We had disabled reference style links in bugdown, however,
we hadn't disabled them in marked. This commit rectifies
that and adds test cases for the same.
Fixes#11350.
The beforeSubmit function was a feature of the jquery-form plugin that
we removed months ago; the appropriate similar feature of jQuery's
built-in AJAX library is beforeSend.
This code will correctly add video call link to the message
textarea based on whether 'Add video call' was selected from
message composition form or message edit form.
The implementation was semi-rewritten by tabbott to remove an
unnecessary global variable, with fixes for the unit tests from
showell.
Fixes#11188.
This is primarily a feature for onboarding, where an organization
administrator might send a bunch of random test messages as part of
joining, but then want a pristine organization when their users later
join.
But it can theoretically be used for other use cases (e.g. for
moderation or removing threads that are problematic in some way).
Tweaked by tabbott to handle corner cases with
is_history_public_to_subscribers.
Fixes#10912.
This replaces the current usage of stream names with stream ids.
This commit also removes the `traditional` attribute from the invite
form as now we are sending stream_ids as an argument; this was the
only place in the codebase we used traditional=true, and it's great to
have it removed.
This function unlike `invite_streams()` returns an array of objects having
various info (name, stream_id, invite_only, default_stream) related to
streams rather than an array of names of streams.
We now compute the class that drives the tiny
green/orange/empty dot in the user popover using
the same logic as the buddy list.
This was broken in the early implementation of
set/clear-away, but it was never released.
Fixes#11413
This makes it possible to mention a user with a name like Gaël that
contains diacritics by typing e.g. "Gael", significantly reducing the
need to use a special keyboard to mention other users.
Fixes#11183.
The only time we set the `home` flag to true
is when it's the last (and only) item in the
list, in which case we flip `hash` to false
at the end of `make_tab_data()`.
So the section of code where both `home` and
`flag` were true is dead code.
Also, we can use `else` instead of `unless`.
The following elements in the top left corner
are major components of our app:
All messages
Private messages
Starred messages
Mentions
We can now find them directly:
$('.top_left_all_messages')
$('.top_left_private_messages')
$('.top_left_starred_messages')
$('.top_left_mentions')
Before this, we had to build up complicated selectors
like below:
exports.get_global_filter_li = function (filter_name) {
var selector = "#global_filters li[data-name='"
+ filter_name + "']";
return $(selector);
};
I don't think any newbie would know to grep for "global_filter",
and I've seen a PR where somebody added specific markup here
to "Private messages" because they couldn't grok the old scheme.
Another thing to note is that we still have a "home-link"
class for "All messages", which overlapped with portico
code that had the same name. (There were some inaccurate
comments in the code relating to the tab bar, but we don't
actually have a way to click to the home view in the tab
bar any more.) I'll eliminate that cruft in another commit.
For this commit the four elements still have the
"global-filter" class, since there's some benefit to being
able to style them all as a group, although we should give
it a nicer name in a subsequent commit.
Most of this PR is basic search/replace, but I did add a
two-line helper: `top_left_corner.update_starred_count`
We had initially designed the poll widget like a blog
post with comments beneath it but it makes more sense
to think of it as just a simple poll with options.
We add a new syntax which converts the messages like the following:
```
/poll Who do you support?
Nadal
- Djokovic
```
to a poll with the two names as options. The list syntax is optional
since anyone making a poll is likely to want to create a list anyway.
When you hover over a user that has set a user
status, we now show something like "out to lunch."
You can test this in the console by doing:
user_status.server_update({status_text: 'out to lunch'})
And then hover over your name in the buddy list.
The name `insert_user_into_list` is sort of misleading,
since we are often just redrawing the user's existing
item in the buddy list.
I chose `redraw_user` over `update_user` to emphasize
that we're just going to redraw it with whatever data
has been updated by the callers.
This fixes an annoying bug where clicking to subscribe to a stream
would change the color shown in the "manage streams" UI immediately
after you click.
Fixes#11072.
This adds a setting under "Notification" section of
"Organization settings" tab, which enables Organization administrator to
control whether the missed message emails include the message content or
not.
Fixes: #11123.
The commit f863a9b567 had modified
jquery.filedrop's paste method to exit early if any of the items in the
clipboardData is of the string kind. The early exit was added to prevent pasting
an image thumbnail for text copied from software like MS Word, instead of
pasting the actual copied text content. When copying an image in a (modern?)
Browser, though, the clipboard seems to contain a html `img` tag item, along
with the actual image file. This resulted in pastes being broken.
This commit modifies the condition checked for the early exit. We now actually
look at the html content in the clipboard to see if it is an `img` tag, in which
case we upload the image, instead of exiting early.
Closes#7130.
This is likely not the "right" fix in that it involved a negative
margin, but this does eliminate an annoying visual glitch where the
scrollbar overflows above its container in the left sidebar, without
creating other apparent problems.
Fixes#8731.
User was able to click delete button multiple time which could cause
multiple delete requests. This commit disables and hides the delete
message button after the first click and shows a spinner until http
the delete request responds.
Also adds a casperjs test to ensure that spinner becomes visible and
delete button becomes invisible after clicking on delete button for
first time and hides spinner and show delete buttton when message is
deleted.
Fixes: #11219.
This fixes a section of code that hasn't really
been turned on yet. We decided to rename
"info" to "status_text", and I apparently missed
this. We don't have any UI to set these yet,
so it was a harmless bug.
I'll try to get some better test coverage on this
when I tweak the buddy list to show user status.
This commit takes away the ability for non-admin members to create
streams where only admins can post messages by hiding the option from
them.
Fixes#11290.
You can now pass in an info field with a value
like "out to lunch" to the /users/me/status,
and the server will include that in its outbound
events.
The semantics here are that both "away" and
"status_text" have to have defined values in order
to cause changes. You can omit the keys or
pass in None when values don't change.
The way you clear info is to pass the empty
string.
We also change page_params to have a dictionary
called "user_status" instead of a set of user
ids. This requires a few small changes on the
frontend. (We will add "status_text" support in
subsequent commits; the changes here just keep
the "away" feature working correctly.)
We had a bug where if you started typing a message
and then used quote/reply (after the fact), we
would overwrite the user's original message.
The bug was kind of subtle--the internal call
to "respond" to the message would select the message
text, and then `smart_insert` would replace the
selection, unless it was Firefox.
Note that we now also allow you to cross-post
replies, which is a plausible scenario, although
possibly unintentional at times, too. I'm erring
on the side of giving the user control here, but
I'll add a warning in the next commit. Our compose
fade feature should also prevent unintentional
mixes here, too.
We often need to go to the server to get raw content.
The exceptions are messages for which we've already
fetched the raw content for some other reason (maybe
a previous quote-and-reply) or which are locally echoed.
Whether we can get the raw content locally or from
the server, the replace_content() logic is the same.
NOTE: If you revert this commit, you want to revert
the immediately prior commit as well. The history
is that Ishan made some improvements to the widget,
but there were some minor bugs. I decided not
to squash the commits together so that the git
history is clear who did what. (In particular, I
want questions about the JS code to come to me if
somebody does `git blame`.)
Anyway...
This is a fairly significant rewrite of the polling
widget, where I clean up the overall structure of
the code (including things from before the prior
fix) and try to polish the prior commit a bit as
well.
There are a few new features:
* We tell "other" users to wait for the poll
to start (if there's no question yet).
* We tip the author to say "/poll foo" (as
needed).
* We add edit controls for the question.
* We don't allow new choices until there's
a question.
This also fixes few unusual UI issues like an invitation got failed when
certain emails can't be invited then the error box is left with "warning"
even when next request got succeed and another case when invitation got
succeed after failing it's still reported with "alert-error" class alert
banner.
It's no longer used, as can be seen in
2d52463b61, in past we use `type` for
specifiying whether status is 'subscriptions-status' or else, which isn't
used now, hence `type` is removed here.
This reverts the temporary fix done in commit
46f4e58782 and replaced it with the fix that
non-admins should be able to see a dropdown to select a non-admin type of
invited user i.e. normal member or guest user.
This commit fixes a bug that caused:
1: A valid full name on an onboarding form to be cleared after an
invalid submission.
2: Incorrectly cleared name populated from LDAP which was janky from
UX perspective.
Ideally we should disable name change for LDAP as next login
will overwrite any changes but I think that can be done in a
separate PR.
Fixes: #10867.
On the backend, we extend the BlockQuoteProcessor's clean function that
just removes '>' from the start of each line to convert each mention to
have the silent mention syntax, before UserMentionPattern is invoked.
The frontend, however, has an edge case where if you are mentioned in
some message and you quote it while having mentioned yourself above
the quoted message, you wouldn't see the red highlight till we get the
final rendered message from the backend.
This is such a subtle glitch that it's likely not worth worrying about.
Fixes#8025.
These mentions look like regular mentions except they do not
trigger any notification for the person mentioned. These are
primarily to be used when you make a bot take an action and
the bot mentions you, or when you quote a message that mentions
you.
Fixes#11221.
Users can preview their profile from user settings. If user
open preview profile modal from user settings, then closing
preview profile modal should redirect them to settings modal
again (since probably they want to keep editing).
This commit fixes above issue.
This adds the same style of "Saving"/"Saved" loading spinners we use
elsewhere in our settings.
Tweaked significantly by tabbott to fix issues with the notifications
being on the wrong screen for reactiving/deactivating users; this was
done by introducing the get_status_field helper function and using it
everywhere.
The legacy "Updated Successfully" message shown after saving changes,
is removed, and replaced with our standard "Saving" spinner and
animation.
Fixes: #11177.
This code will correctly render emoji to the message textarea based on
whether emoji was selected from message composition form or message
edit form.
Fixes part of #11188.
AFAIK I should this never fail, hence the blueslip.error line. But it
is failing in practice when rendering user groups after looking them
up by ID, and the error handling should definitely be softer.
Our recent work on inviting users as guests accidentally set the
invite_as argument in a way that would fail for non-admin users.
Fixes#11283, fixes#11255.
We do this because now we send a message to stream if a reminder
is set and won't need the notification above the compose box saying
that we set a reminder. We would still need that notifications for
the send later feature so we make the construct conditional.
In between releases, the following commit introduced
a bug where we agressively scroll to the top every
place we call `ui.update_scrollbar`:
092b73d0b7
The main symptoms were that the left and right sidebars
would go to the top for things like selecting a topic,
getting activity updates from the server, and resizing
the window. It was very jarring.
The recent commit looked innocuous--the root of the problem
was the original API expressed an intent to scroll to the
top, but didn't actually do it, so it was a bug in hiding.
There are **some** occasions where it's actually appropriate
to scroll to the top, mostly around search filtering, and
in those places we now call the new `ui.reset_scrollbar`
function.
This is a bit of an emergency fix, so particularly with
the settings stuff, we may get more reports of glitches here.
The important thing here is that you almost never want to
reset the scrollTop for sidebars.
This seems like a small change (apart from all the
test changes), but it fundamentally changes how
the app finds "topic" on message objects. Now
all code that used to set "subject" now sets "topic"
on message-like objects. We convert incoming messages
to have topic, and we write to "topic" all the way up
to hitting the server (which now accepts "topic" on
incoming endpoints).
We fall back to subject as needed, but the code will
emit a warning that should be heeded--the "subject"
field is prone to becoming stale for things like
topic changes.
We recently added a feature to warn users that they
may need to scroll down to view messages that they
just sent, but it was broken due to various complexities
in the rendering code path.
Now we compute it a bit more rigorously.
It requires us to pass some info about rendering up
and down the stack, which is why it's kind of a long
commit, but the bulk of the logic is in these JS files:
* message_list_view.js
* notifications.js
I choose to pass structs around instead of booleans,
because I anticipate we may eventually add more metadata
about rendering to it, plus bools are just kinda brittle.
(The exceptions are that `_maybe_autoscroll`, which
is at the bottom of the stack, just passes back a simple
boolean, and `notify_local_mixes`, also at the bottom
of the stack, just accepts a simple boolean.)
This errs on the side of warning the user, even if the
new message is partially visible.
Fixes#11138
We now have two functions:
add_new_messages
add_old_messages
This is a lot easier on the eyes, and it will also
prevent us from exceeding line length in future commits.
We also remove an unneeded stub in the narrow_activate
tests.
This commit makes it a bit more explicit about
why we're updating 2 or 3 message lists every time.
It looks funny now to repeat the home-list updates
in both sides of the conditional, but this will be
more obvious in a subsequent commit, where we want
to capture return values from rendering.
In a recent commit we allowed for `scroll_amount`
to be zero (as an indirect consequence of letting
`scroll_limit` be zero without early exiting).
See 0f75be3e8e
We want to short circuit the call to
`system_initiated_animate_scroll`, partly to save
unnecessary computation, but in particular to avoid
invoking the suppress-pointer-update logic.
It's convenient to have visible_bottom as well
as top/height, and the extra computation is
trivial (it's just arithmetic, no extra jQuery
involved).
There's some minor cleanup here too.
This adds a proper template for the /digest page, making it a
reasonable way to view the digest email content for development and
debugging.
Fixes: #11016.
Guest users can not add subscribers to subscribed or unsubscribed
streams. Therefore hide add-subs html element if current user
is guest user.
Tweaked by tabbott to use the early-return pattern.
Add explanation in popover on disabled add-subscriptions input elements,
admin can't add subscribers to non subscribed private streams, only
subscribed users can.
Fixes#10593
There's a subtle change here in how we handle the
hypothetical case that the selected message is above
the top of the feed. Instead of early-exiting
from _maybe_autoscroll(), we just treat the limit
as zero, which will have the same effect.
We also change a var name be just `scroll_limit`
instead of `available_space_for_scroll`. A longer
name would be valuable if it were somehow more
specific, but it was needlessly verbose.
The idea is to use this field for storing the best matching alias
to be displayed in search results. In subsequent commits I will
replace the search and rendering logic to use this field instead
of creating new objects on each search.
Since we have already added the `invite_as` field to models, we can now
replace usage of `invite_as_admin` properly with its equivalent `invite_as
== PreregistrationUser.INVITE_AS['REALM_ADMIN']`.
Hence, also removed now redundant `invite_as`.
This couples the behavior of Enter to Save with Enter to Send.
Extracts and exports functions responsible for checking if enter
does send/edit and handling default behavior otherwise.
Changes made in static/js/message_edit.js and
static/js/composebox_typeahead.js
Fixes#10320.
This adds two functions to static/js/composebox_typeahead.js.
should_enter_send(event) checks if enter should actually send.
handle_enter(textarea,event) emulates browser's default behavior
if enter doesn't send.
These two are just straight extractions of portions of the compose box
logic.
It's a bit dangerous for the user to hit escape
to close the feedback widget, since it can
disappear suddenly, but users will try it, and
we should just close the widget.
(Hitting escape should be a noop if the box
is closed, but now it goes to "All Messages".)
We only need these once, not during every show()
call. We actually were only setting up the
click handlers one time, but we had redundant
mouse handlers.
More importantly, we stop a runaway timer
that tries to fade out our feedback widget
every 100ms or ten times per second!
A few things are still hard coded, but the class exposes
show() and dismiss() now.
The show() method is configured with callbacks for
populate() and on_undo().
We calculate a few values higher up in the function.
This reduces a bit of code duplication and removes
a somewhat janky expression that happens against
a mutated list.
I use shorter var names in frb_botom() and do early
return in obscured_recipient_bar().
Also, we always call exports.hide() if we don't find
a valid recipient bar to "float."
There is no reason not to initialize people.js
super early in the process, as it only reads
data from page_params. Also, other modules
are likely to want its data during their own
initialization steps.
This is the preferred way to check that a user
id belongs to the current user.
We have a recent bug where the current user's
circle doesn't turn green right away. It's not
clear this is the fix, though. (It's hard to
repro locally.)
This is mostly for testing purposes. The code
structure here is pretty stable--we will probably
always use level() here to either sort or
group users, and being able to test it directly
is nice, rather than bringing in all the other
machinery.
This makes it possible it include our standard markdown formatting in
one's custom profile fields, allowing for links, emphasis, emoji, etc.
Fixes#10131.
While we're at it, we remove the JSON parsing that was part of the
user field code path, since this function isn't responsible for
rendering user fields.
Apparently, our custom profile fields feature was parsing the "user
list" field type in multiple places, and ignoring the results in one
of them. That code had been causing some confusion; the correct
solution is to just delete it, since the template rendering process
ignores that value for this field type.
Our logic for doing pageup/pagedown calculation inside compose was
written too tightly, and ended up breaking the keys inside message
editing.
Fix this by using generic selectors that don't hardcode compose.
Previously, messages with more than one line did not parse '/me' at
the beginning of the message. Since there's a reasonable way to
render multi-line messages, this commit adds support for doing so.
This change does potentially break with the expected behavior of other
slash commands, but it seems worth providing useful functionality over
a blind focus on consistency.
Fixes#11025.
If branch for showing the profile details would
not have executed if the subdomain was root ("").
The check was changed to check for select input
instead of checking for subdomain.
This avoids a bunch of potential confusion around users trying to
interact with these UI in situations that don't make sense.
(E.g. showing a menu to start editing the message when the menu is
already open).
Fixes#3802.
We instead get the specific fields from message
that we use. This is particularly helpful
for subject -> topic migration; we no longer
have to account for "subject" fields in
client-side templates.
This continues the effort to isolate "subject" references
to util calls.
Also, we fix a comment.
Finally, we use canonicalized operators in a switch
statement.
This adjusts the spacing so that the out-of-view notifications for
group PMs (which have particularly long text) don't end up with the
"x" to close the notification overlapping the text.
Fixes#11058.
As part of giving the stream/topic fields in the
compose box longer ids, I broke the autocomplete
code that handles re-focusing the cursor after
a user hits enter. The worst symptom of this was
that we tried to send a message before compose
finished (although it wouldn't fully deliver the
message).
The new code should be a bit easier to grep for
if we rename these fields again, as we explicitly
use selector syntax.
Previously, we were searching the whole message_row object for emoji,
mentions, etc., which has a bunch of UI elements that can't contain
the syntax we want to modify. This should be a slight improvement in
the performance of message post-processing, which runs a lot of times
and thus is fairly important.
This check caused us to only run the code inside that block if the
message mentioned the current user (since that's when the `mention`
class is added to the main message row).
While this was a useful performance optimization, it probably was a
small one, not worth it for the correctness cost.
This adds a new realm_logo field, which is a horizontal-format logo to
be displayed in the top-left corner of the webapp, and any other
places where we might want a wide-format branding of the organization.
Tweaked significantly by tabbott to rebase, fix styling, etc.
Fixing the styling of this feature's loading indicator caused me to
notice the loading indicator for the realm_icon feature was also ugly,
so I fixed that too.
Fixes#7995.
Logic for checking if the last message in the current table is visible was
already written in message_viewport.js; Code in notifications.js is changed
to reduce redundancy.
We are trying to carve room for a more specific
"user_status" concept, which refers to statuses
that users specifically set, like "I'm away".
So we call this function "update_presence_info",
which reflects that it's more about actual
"presence"--i.e. the user really is present
in the browser, even though the actual human
may not want to be disturbed.
The current user gets excluded from all non-empty
searches, even ones that match the user, since
it can look funny when the user's at the top of a
search, and you'd never need to search for yourself
(again, since the current user is at the top of
the buddy list).
Apparently, we didn't have one of these, and thus had a moderate
number of generally very old violations in the codebase. Fix this and
clear the ones that exist..