A common source of confusion for new users is sending a message when
you're scrolled up in the message feed; in this case, it's nice to
communicate to the user why the message is not in view.
Fixes#10792.
Restructured by tabbott to replace overly complex logic for getting
the position of the new message with a `message_list.get_row()` call.
This fixes the most core data structures inside of
muting.js. We still use stream names for incoming
data to set_muted_topics and outgoing data from
get_muted_topics.
This will make us more resilient to stream name changes.
Before, if you were logged on when a stream rename
occured, topics that were muted under that stream would
appear to be unmuted. (You could fix it with a reload,
but it can be jarring to have a bunch of unread messages
appear in your feed suddenly.)
Fixes#11033
Also, add a new notification sound, "ding". It comes from
https://freesound.org, where the original Zulip notification sound comes
from as well. In the future, new sounds can be added by adding audio
files to the `static/audio/notification_sounds` directory.
Tweaked significantly by tabbott:
* Avoided removing static/audio/zulip.ogg, because that file is
checked for by old versions of the desktop app.
* Added a views check for the sound being valid + tests.
* Added additional tests.
* Restructured the test_events test to be cleaner.
* Removed check_bool_or_string.
* Increased max length of notification_sound.
* Provide available_notification_sounds in events data set if global
notifications settings are requested.
Fixes#8051.
This commit prepares the frontend code to be consumed by webpack.
It is a hack: In theory, modules should be declaring and importing the
modules they depend on and the globals they expose directly.
However, that requires significant per-module work, which we don't
really want to block moving our toolchain to webpack on.
So we expose the modules by setting window.varName = varName; as
needed in the js files.
This is preparation for enabling an eslint indentation configuration.
90% of these changes are just fixes for indentation errors that have
snuck into the codebase over the years; the others are more
significant reformatting to make eslint happy (that are not otherwise
actually improvements).
The one area that we do not attempt to work on here is the
"switch/case" indentation.
We consistently either pass a `then_select_id` into narrow.activate,
or were using the select_first_unread option. Now, we just compute
select_first_unread based on the value of then_select_id.
This commit exposes some inner variables of notifications.js to make
them easily testable. The first test added simply checks whether the
showing and closing of notifications works properly, and doesn't yet
verify the main code logic of the notification generation.
To prevent specifying notifications individually for global
updates, automate handle_global_notification_updates using
settings_notifications.notification_settings where we have
the keys of all the types of notifications.
We create a node unit test,
with 'muting' and 'stream_data' modules as dependencies,
to test the logic in notifications.message_is_notifiable.
Part of #2945
Users having only account in one realm will not be distracted by realm
name in subject lines of every email. Users who have multiple
accounts in realms can turn this setting on and receive a
corresponding realm name in email's subject.
Tweaked by tabbott to rebase and address a few small issues.
Fixes#5489.
A comment like this was removed in
fa44d2ea6 "settings: Remove autoscroll_forever setting."
The comment went on to say something about autoscroll, but this
part still seems relevant. While here, adjust grammar and caps.
We do not want the code to lead to a path where it will attempt to
display native notifications if the “Notification” object doesn’t
exist, as this likely means that the device does not support OS
notifications.
This removes a test for "webkit" in the userAgent string in order
to see whether notifications should be displayed. This is so that
the notifications process will work correctly in Firefox and not
keep registering as "false" which makes the notifications prompt
continue to re-show itself.
This checks whether the user is already in the state of having
blocked notifications, so that we can *not* show them the banner
to enable notifications, since browsers won't allow the request
to go through again.
Perhaps in a follow up we should create a different banner for
this case that shows how to enable notifications at the browser
level for this site.
This is a two-step notifications process that will ask a user
to enable notifications and if they click exit give them three
options:
1. Enable notifications.
2. Ask later.
3. Never ask on this computer again.
The first two are self-explanatory (ask later = next session it
asks again). The third is captured and stored in localStorage and
a check is done on page load to see whether or not notifications
should be displayed.
Commit modified heavily by Brock Whittaker <brock@zulipchat.com>.
Fixes#1189.
This commit renames possibly_notify_new_messages_outside_viewport()
to the more concise name notify_local_mixes().
We really only need to call this function in one place, so we
have the caller check the `local_id` condition. We can eventually
upstream this code even further so that it's completely
obvious that it's only ever called from the local-echo codepath.
This commit early-exits before our loop when local_id is none,
and it tries to more clearly indicate that the callers will
generally be just calling this with messages sent on the
local-echo path.
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.
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.
Pass down 'local_id' through functions that handle notifications for messages
that are sent locally. If 'local_id' is undefined, the message was not sent in
the respective tab, so no "outside_viewport" notification should be displayed.
This fixes#1783.
We attempted a number of different approaches to solving this problem:
First, we tried using HTML5 local storage to keep track of which
browser should have created the desktop notification. This failed
because one needs locking, and it doesn't appear there is an working
locking implementation for HTML5 local storage that could allow us to
do this across tabs. See #2936 for details.
Ultimately we went with setting the message ID as a tag. Tags are
intended to be used for updating existing desktop notifications, which
means this implementation causes new notifications to flicker in and
out sometimes when multiple tabs are open, but that certainly beats
having duplicates.
Fixes#99.
This moves these functions from subs.js to stream_data.js:
receives_desktop_notifications
receives_audible_notifications
This makes notifications.js no longer dependent on the
bloated subs.js.
$.browser is not supported in higher versions of jQuery. The solution
is to instead use vanilla JavaScript to test the navigator.userAgent
property for the browser.
Fixes: #1033.
Previously, we were checking if a particular user was the current user
in dozens of places in the codebase, and correct case-insensitive
checks were not used consistently, leading to bugs like #502.
860cf68716 introduced calls to
notifications.redraw_title() on narrow activation. This introduced a
bug when the Zulip desktop app reloads while narrowed --
new_message_count would still be set to undefined when
narrow.activate() is called as the page (re)loads, and thus we'd call
window.bridge.updateCount(undefined), resulting in a traceback.
We fix this by just initializing it to 0, rather than using the old
default value of undefined.
Known issues:
* No support for whitelabeling in the email
* No whitelabeling for any externally-visible branding
(imported from commit 9eab7b0744e56a87007b8621a8bb18bbb1080256)
Chrome has removed the webkitNotifications API and not only has the w3c
web notifications API. This adds a shim when webkitNotifications is
missing but Notification is present.
(imported from commit e21c476f9ae6570c297c88bd6ff90a97818688e6)
This sets us up to redraw the window title without having to
pass in the unread count, which will be useful for realm name
changes. The redraw_title() function is only responsible for
rendering stuff, whereas update_title_count() handles
the details of caching the count.
(imported from commit 67cfb7a273e2a61720ce2bd8d91d73fe1089c813)
If a message edit causes a message to become notifiable, we send
a notification to the user, but only if they haven't had any previous
notifications for this message.
(imported from commit cee854de2d42c31a7352a350f79490caf94b613c)
This is the "Tried to call a Dict method with an undefined key" error
because it tried to look up stream information for `undefined`.
(imported from commit 0187f185f3e424a0c9ea940d9b32f07376ac8952)
`$(message.content)` breaks on /me messages because they are not
wrapped in `<p>` so the message content is interpreted as a selector.
The message text is no longer used, so this line can simply be removed.
(imported from commit ee8d48c1f5fc489cc577cc466f629891ea65d55f)
This seems to only work in Chrome and Safari.
Firefox (at least my version) simply doesn't fire an onclick
event, and our desktop app has its own native code that decides
what to do when a notification is clicked.
(imported from commit 30bacec4726b9e6c022dd2c74f83d37747260dba)
This makes the notification slightly more conservative as we do our
initial roll out. In particular, it avoids cases like being notified
when you are almost at the bottom of your feed for a message in your
narrow.
(imported from commit 9c834b1c344d8c429de92fb3512f32494fc02379)
This moves the notify-not-in-view notifications into the composebox area.
It also tries to be a bit smarter about what action it links and what it displays.
(imported from commit 1c79bd0d9ef972059a006b17501a09b72e961ee3)
It's somewhat buggy, and has thus been annoying our internal users, so
better to disable it until we can fix the bugs.
(imported from commit f981791d32d321b0cfe06b4a337e26ab48832bb3)
Displays a notification above the composebox in cases where the message
is not visible (further down), or where it's outside the current narrow or search.
It also offers a link to the appropriate narrow when it makes sense, and offers
timetravel when appropriate. There is currently a bug with timetravel (and you can
see this when using the popover menu) that makes "narrow to messages around this time"
not work for muted messages.
This resolves Trac #1518.
(imported from commit 391ca0b9c07d91496f6585a4fd8e15723d1170e2)
This doesn't address the more complicated case of someone @-mentioning
you on a muted topic, which consensus is you do want to get
information for, but we need to develop some infrastructure to present
that case to users clearly.
(imported from commit a4bc1e89c108fa8ba6eccc0a198eabf2231326ab)
For web pages, the initial favicon is the same as the favicon we
set for no unread messages and the initial page title is the same
as the page title we set for no unread messages. However, for the
OS X app, the dock icon does not get its badge updated on initial
page load. If the badge icon was wrong right before a reload and
we actually have no unread messages then we will never execute
bridge.updateCount() until the unread count changes. Therefore,
we now ensure that bridge.updateCount is always run at least once
to synchronize it with the page title.
(imported from commit 5d1269c62c1c3190aea96ef6f96c46acdb9fdf9c)
In a few cases the $.each was doing something imperatively that was
terser and easier to understand by using a different Underscore method,
so a few of these I rewrote.
Some code was using the fact that jQuery sets `this` in the callback to
be the item; I rewrote those to use an explicit parameter.
Some code was using $(some selector).each(callback). I converted these
to _.each($(some selector), callback).
One function, ui.process_condensing, was written to be a jQuery $.each
callback despite being in a totally different module from code using it.
I noticed this and updated the function's args.
(imported from commit bf5922a35f257c168cc09ec1d077415d6ef19a03)