Apparently, our logic was broken on systems where altKey and metaKey
are different, because we didn't ignore hotkey combinations that
included altKey.
Fixes#3738.
This restyles the subscriber list in the subscription settings panel to
have a more padded and lighter aesthetic and replaces the dark red
buttons with transparent buttons that have only red borders and inner
text.
Change `from django.utils.timezone import now` to
`from django.utils import timezone`.
This is both because now() is ambiguous (could be datetime.datetime.now),
and more importantly to make it easier to write a lint rule against
datetime.datetime.now().
It's currently broken (e.g. see Issue #3713) and non-responsive. The whole
page needs to be styled anyway, so these can be added back once that
happens.
This makes text look bad in Chrome on Linux; it happened to not cause
problems in production because our minifier broke it (see
https://github.com/yui/yuicompressor/issues/91), but text looked bad
in development.
The transition "all" by default also affected the transition
on the height change of the compose box which ended up making the
compose box appear to be laggy and choppy.
Add neccesary UI in #administration and #settings for
changing the bot owner. The bot owner select control
is rendered dynamically in order to avoid performance
issues in case of large number of users.
Fixes: #2719.
Previously the mechanism worked such that the innerHTML was being
appended to directly potentially thousands of times which has horrific
performance implications. By concating all the strings together before
appending to the HTML it all gets rendered in one chunk without forcing
a re-render of previous elements. Performance is ~15x-20x faster now.
Use `name_to_codepoint.json` file (and the similar structure in
emoji_codes.js) to map emoji names directly to codepoints and change
the rendered emoji image to `unicode/<codepoint.png>` rather than
`<emoji_name>.png`.
Fixes: #3539.
If you send a group PM from the home view, and then one of the
recipients changes their email, and then you send a group PM
to the same recipients, we need to make sure we don't create
a spurious recipient bar. This fix makes this happen by
changing util.same_recipient() to look at user ids instead of
emails.
Using stream_id in recipient comparisons fixes a
bug in this scenario: go to home view, send message
to stream, wait for admin to rename stream, send
another message to the stream. Before this change,
the stream name would live-update but you'd get a
spurious recipient bar due to the prior message still
having the old stream name in places internally.
There were other ways to fix the live-update glitch,
but it's just generally cleaner to do stream id
comparisons.
Part of this change is to add stream_id to
compose_fade.set_focused_recipient().
Change the remaining "Admin settings" with a button, namely
changing a stream's privacy, to instead be a "[Change]" link
opening a confirmation modal.
Fixes: #3493.
This changes the time render to be done on the client-side and
therefore take advantage of knowing the client’s timezone, along with
being formatted in a more human-parseable way.
This removes the arrow from the subscriptions header at full
widths where the arrow is not required because the subscription
settings/stream creation prompt don't take up the full width of
the screen and require an arrow to go back to the streams list.
Fixes: #3762.
This changes the layout of administration for non-administrators such
that they can view organization settings and emoji settings and
displays everything as readonly unless they have the capability to edit.
For now, we just enabled this for the emoji settings and organization
settings features.
This removes all the .expectOne statements and replaces with a
single broad stroke .hide() that doesn't check if they exist,
but rather just ensures they are hidden by default until triggered.
This adds to Zulip support for a user changing their own email
address.
It's backed by a huge amount of work by Steve Howell on making email
changes actually work from a UI perspective.
Fixes#734.
* Created a drafts modal to display/restore/delete drafts
* Created a Draft model to support storing draft data in localstorage
* Removed existing restore-draft functionality
* Added casper and node tests for drafts functionality
Fixes#1717.
This re-adds the deleted "Delete Avatar" button back to the
settings/your-account tab view in the overlay, which only appears
if you do not currently have a gravitar.
We now sweep all active messages for avatar changes and update
the message items and re-render, rather than patching the
DOM. This avoids some quirks that happen when subsequent messages
get sent and we re-render previous messages out of the message
store.
Our approach here is similar to how we do full-name updates.
In f75af94984 I added some
lines of code that made it so that live updates for avatar
urls would affect messages currently in the browser.
This change worked well when the live update actually happened,
but then the next time the user would reload, the avatar in
the message pane would regress back to showing the avatar urls
from the server (which could have caching issues of their own).
This fix removes a couple lines of code that had the intended
effect of making all of your messages from any given sender
show the same url (good) but which generally grabbed
the url from an old message (bad).
After this fix, we go back to having old messages possibly
showing the old avatar urls, but new messages will display the
new avatar.
(There are lots of moving parts in the avatar system, because
not only do browsers cache image urls, but our server caches
messages and recipient info, so there have been "fixes" to
avatars since this change that are valid fixes in their own
right but not directly relevant to this commit.)
This provides a fairly intense highlighting of when you're hovering
over a given emoji reaction element.
We may want to tone down the color a bit; I'm hoping for some feedback on this.
This makes life a lot easier for people inviting users to a new Zulip
organization, since they can give some form of context now.
Modified by tabbott to clean up CSS, backend code flow, and improve
the formatting of the emails.
Fixes: #1409.
The current logic that we have is as follows:
* If a message is locally echoed, the draft is stored via the locally
rendered message, and that system takes care of it. So no need to
store it here.
* If the message isn't locally echoed, we don't close the compose box
until, so the content is safe here as well. It'll be saved as a draft
if the compose box is later closed due to a failure sending.
This replaces the settings toggle which had the same markup as the
current component toggle, but not the same JavaScript, along with
having an issue with inline-block spacing, with the new JS generated
one.
We now call activity.build_user_sidebar when we initialize
the user sidebar, which avoids some janky jQuery code
that was intended for partial updates.
With 2000 users in dev, the amount of time to build the sidebar
decreases from 1100ms to 700ms in my tests. (Times vary a bit,
but it does seem consistently faster now.)
Activity.update_users() is still used to handle partial
updates of users in the buddy list, but now all the places
that want to re-build the whole widget go through
build_user_sidebar().
The pinned streams were sorted in alphabetic order (i.e. Verona appears
before devel). The reason is that after we plucked pinned streams out from
stream_data.subscribed_streams(), we didn't sort them again, so they
remained in the alphabetic order used in stream_data.
However, we did sort unpinned streams explicitly by using custom compare
function in stream_list.js (by default sort by lowercase stream name,
but when there are more than 40 subscribed streams, sort active streams
first). That's why this issue only relates to pinned streams.
Changes were made to sort pinned streams by lowercase stream name, always,
whether they are active or not (different from unpinned streams).
Tests were added to ensure this overall sort order is correct, i.e.
1. pinned streams are always sorted by lowercase stream name.
2. pinned streams are always before unpinned streams.
3. unpinned streams are sorted by lowercase stream name, if there are more
than 40 subscribed streams, sort active streams at the top, among active
and inactive streams, still sorted by lowercase stream name.
Fixes#3701
User search for streams will now return results where the stream
description (but not the stream name) include the string in the
user query.
The filtering process first obtains the streams whose names match the
user search query, then sorts and displays them. From the remaining
streams, it obtains streams whose description matches the query and
displays them in sorted order after the name match results. Other
streams are not displayed.
Fixes: #2674.
When an admin deactivate a stream, we now remove the
appropriate row from the default streams tables for other
folks viewing default streams in the admin tables.
We add a default_streams_table() function that builds an
object encapsulating the defaults streams table in the admin
system.
This function allows us to simplify the click handler code by
closing on row/stream_name rather than picking those values out
of the DOM.
Fixes#268.
Modified significantly by tabbott to:
* improve code cleanliness / repetition
* add missing translation tags
* move code into message_edit.js
* correspond with the new backend.
* not display the option for messages only topic-edited
The new behavior is:
(1) If enter-sends is enabled, just send the messsage.
(2) If enter-sends is not enabled, return focus to the compose area.
Based on great work by khantaalaman in #3673.
Fixes#3489.
This is a fairly risky, invasive change that speeds up
stream deactivation by no longer sending subscription/remove
events for individual subscribers to all of the clients who
care about a stream. Instead, we let the client handle the
stream deactivation on a coarser level.
The back end changes here are pretty straightforward.
On the front end we handle stream deactivations by removing the
stream (as needed) from the streams sidebar and/or the stream
settings page. We also remove the stream from the internal data
structures.
There may be some edge cases where live updates don't handle
everything, such as if you are about to compose a message to a
stream that has been deactivated. These should be rare, as admins
generally deactivate streams that have been dormant, and they
should be recoverable either by getting proper error handling when
you try to send to the stream or via reload.
(There was a method with the same name before, but it wasn't
being used. The new version will accept stream_id instead
of name, and we will use it as part of deactivating streams.)