Add user setting option to always send push notifications.

Add option in user's settings for getting mobile push notifications
even if a Zulip browser is online.  Default is False.

Fixes: #1596.
This commit is contained in:
Tomasz Kolek 2016-09-19 22:55:18 +02:00 committed by Tim Abbott
parent b6da450b96
commit 4790316b57
12 changed files with 85 additions and 15 deletions

View File

@ -75,6 +75,7 @@ function render(template_name, args) {
"sounds_enabled": false, "sounds_enabled": false,
"enable_offline_email_notifications": false, "enable_offline_email_notifications": false,
"enable_offline_push_notifications": false, "enable_offline_push_notifications": false,
"enable_online_push_notifications": false,
"enable_digest_emails": false, "enable_digest_emails": false,
"domain": "zulip.com", "domain": "zulip.com",
"autoscroll_forever": false, "autoscroll_forever": false,

View File

@ -539,7 +539,8 @@ fs.readdirSync(path.join(__dirname, "../../static/templates/", "settings")).forE
stream_desktop_notifications_enabled: true, stream_desktop_notifications_enabled: true,
stream_sounds_enabled: true, desktop_notifications_enabled: true, stream_sounds_enabled: true, desktop_notifications_enabled: true,
sounds_enabled: true, enable_offline_email_notifications: true, sounds_enabled: true, enable_offline_email_notifications: true,
enable_offline_push_notifications: true, enable_digest_emails: true, enable_offline_push_notifications: true, enable_online_push_notifications: true,
enable_digest_emails: true,
autoscroll_forever: true, default_desktop_notifications: true autoscroll_forever: true, default_desktop_notifications: true
}; };
var page_params = $.extend(page_param_checkbox_options, { var page_params = $.extend(page_param_checkbox_options, {
@ -551,6 +552,7 @@ fs.readdirSync(path.join(__dirname, "../../static/templates/", "settings")).forE
var checkbox_ids = ["enable_stream_desktop_notifications", var checkbox_ids = ["enable_stream_desktop_notifications",
"enable_stream_sounds", "enable_desktop_notifications", "enable_stream_sounds", "enable_desktop_notifications",
"enable_sounds", "enable_offline_push_notifications", "enable_sounds", "enable_offline_push_notifications",
"enable_online_push_notifications",
"enable_digest_emails", "autoscroll_forever", "enable_digest_emails", "autoscroll_forever",
"default_desktop_notifications"]; "default_desktop_notifications"];

View File

@ -608,7 +608,9 @@ exports.handle_global_notification_updates = function (notification_name, settin
} else if (notification_name === "enable_offline_email_notifications") { } else if (notification_name === "enable_offline_email_notifications") {
page_params.enable_offline_email_notifications = setting; page_params.enable_offline_email_notifications = setting;
} else if (notification_name === "enable_offline_push_notifications") { } else if (notification_name === "enable_offline_push_notifications") {
page_params.enable_offline_push_notifications= setting; page_params.enable_offline_push_notifications = setting;
} else if (notification_name === "enable_online_push_notifications") {
page_params.enable_online_push_notifications = setting;
} else if (notification_name === "enable_digest_emails") { } else if (notification_name === "enable_digest_emails") {
page_params.enable_digest_emails = setting; page_params.enable_digest_emails = setting;
} }

View File

@ -284,6 +284,10 @@ function _setup_page() {
page_params.enable_offline_push_notifications = result.enable_offline_push_notifications; page_params.enable_offline_push_notifications = result.enable_offline_push_notifications;
} }
if (result.enable_online_push_notifications !== undefined) {
page_params.enable_online_push_notifications = result.enable_online_push_notifications;
}
// Other notification settings. // Other notification settings.
if (result.enable_digest_emails !== undefined) { if (result.enable_digest_emails !== undefined) {
@ -312,7 +316,8 @@ function _setup_page() {
_.each(["enable_stream_desktop_notifications", "enable_stream_sounds", _.each(["enable_stream_desktop_notifications", "enable_stream_sounds",
"enable_desktop_notifications", "enable_sounds", "enable_desktop_notifications", "enable_sounds",
"enable_offline_email_notifications", "enable_offline_email_notifications",
"enable_offline_push_notifications", "enable_digest_emails"], "enable_offline_push_notifications", "enable_online_push_notifications",
"enable_digest_emails"],
function (setting) { function (setting) {
updated_settings[setting] = $("#" + setting).is(":checked"); updated_settings[setting] = $("#" + setting).is(":checked");
}); });

View File

@ -85,6 +85,17 @@
{{t "Mobile push notifications when offline" }} {{t "Mobile push notifications when offline" }}
</label> </label>
</div> </div>
<div class="input-group thinner">
<input type="checkbox" class="inline-block" name="enable_online_push_notifications" id="enable_online_push_notifications"
{{#if page_params.enable_online_push_notifications}}
checked="checked"
{{/if}} />
<label for="enable_online_push_notifications" class="inline-block">
{{t "Mobile push notifications always (even when online)" }}
</label>
</div>
</div> </div>
<div id="other_notifications"> <div id="other_notifications">

View File

@ -35,7 +35,7 @@ from zerver.models import Realm, RealmEmoji, Stream, UserProfile, UserActivity,
UserActivityInterval, get_active_user_dicts_in_realm, get_active_streams, \ UserActivityInterval, get_active_user_dicts_in_realm, get_active_streams, \
realm_filters_for_domain, RealmFilter, receives_offline_notifications, \ realm_filters_for_domain, RealmFilter, receives_offline_notifications, \
ScheduledJob, realm_filters_for_domain, get_owned_bot_dicts, \ ScheduledJob, realm_filters_for_domain, get_owned_bot_dicts, \
get_old_unclaimed_attachments, get_cross_realm_users get_old_unclaimed_attachments, get_cross_realm_users, receives_online_notifications
from zerver.lib.alert_words import alert_words_in_realm from zerver.lib.alert_words import alert_words_in_realm
from zerver.lib.avatar import get_avatar_url, avatar_url from zerver.lib.avatar import get_avatar_url, avatar_url
@ -625,12 +625,6 @@ def log_message(message):
if not message.sending_client.name.startswith("test:"): if not message.sending_client.name.startswith("test:"):
log_event(message.to_log_dict()) log_event(message.to_log_dict())
def always_push_notify(user):
# type: (UserProfile) -> bool
# robinhood.io asked to get push notifications for **all** notifyable
# messages, regardless of idle status
return user.realm.domain in ['robinhood.io']
# Helper function. Defaults here are overriden by those set in do_send_messages # Helper function. Defaults here are overriden by those set in do_send_messages
def do_send_message(message, rendered_content = None, no_log = False, stream = None, local_id = None): def do_send_message(message, rendered_content = None, no_log = False, stream = None, local_id = None):
# type: (Union[int, Message], Optional[text_type], bool, Optional[Stream], Optional[int]) -> int # type: (Union[int, Message], Optional[text_type], bool, Optional[Stream], Optional[int]) -> int
@ -701,6 +695,7 @@ def do_send_messages(messages):
'user_profile__id', 'user_profile__id',
'user_profile__email', 'user_profile__email',
'user_profile__is_active', 'user_profile__is_active',
'user_profile__enable_online_push_notifications',
'user_profile__realm__domain' 'user_profile__realm__domain'
] ]
query = Subscription.objects.select_related("user_profile", "user_profile__realm").only(*fields).filter( query = Subscription.objects.select_related("user_profile", "user_profile__realm").only(*fields).filter(
@ -783,7 +778,7 @@ def do_send_messages(messages):
presences = presences) presences = presences)
users = [{'id': user.id, users = [{'id': user.id,
'flags': user_flags.get(user.id, []), 'flags': user_flags.get(user.id, []),
'always_push_notify': always_push_notify(user)} 'always_push_notify': user.enable_online_push_notifications}
for user in message['active_recipients']] for user in message['active_recipients']]
if message['message'].recipient.type == Recipient.STREAM: if message['message'].recipient.type == Recipient.STREAM:
# Note: This is where authorization for single-stream # Note: This is where authorization for single-stream
@ -2098,6 +2093,18 @@ def do_change_enable_offline_push_notifications(user_profile, offline_push_notif
log_event(event) log_event(event)
send_event(event, [user_profile.id]) send_event(event, [user_profile.id])
def do_change_enable_online_push_notifications(user_profile, online_push_notifications, log=True):
# type: (UserProfile, bool, bool) -> None
user_profile.enable_online_push_notifications = online_push_notifications
user_profile.save(update_fields=["enable_online_push_notifications"])
event = {'type': 'update_global_notifications',
'user': user_profile.email,
'notification_name': 'online_push_notifications',
'setting': online_push_notifications}
if log:
log_event(event)
send_event(event, [user_profile.id])
def do_change_enable_digest_emails(user_profile, enable_digest_emails, log=True): def do_change_enable_digest_emails(user_profile, enable_digest_emails, log=True):
# type: (UserProfile, bool, bool) -> None # type: (UserProfile, bool, bool) -> None
user_profile.enable_digest_emails = enable_digest_emails user_profile.enable_digest_emails = enable_digest_emails
@ -3132,7 +3139,7 @@ def handle_push_notification(user_profile_id, missed_message):
# type: (int, Dict[str, Any]) -> None # type: (int, Dict[str, Any]) -> None
try: try:
user_profile = get_user_profile_by_id(user_profile_id) user_profile = get_user_profile_by_id(user_profile_id)
if not receives_offline_notifications(user_profile): if not (receives_offline_notifications(user_profile) or receives_online_notifications(user_profile)):
return return
umessage = UserMessage.objects.get(user_profile=user_profile, umessage = UserMessage.objects.get(user_profile=user_profile,

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('zerver', '0033_migrate_domain_to_realmalias'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='enable_online_push_notifications',
field=models.BooleanField(default=False),
),
]

View File

@ -446,6 +446,7 @@ class UserProfile(ModelReprMixin, AbstractBaseUser, PermissionsMixin):
enable_sounds = models.BooleanField(default=True) # type: bool enable_sounds = models.BooleanField(default=True) # type: bool
enable_offline_email_notifications = models.BooleanField(default=True) # type: bool enable_offline_email_notifications = models.BooleanField(default=True) # type: bool
enable_offline_push_notifications = models.BooleanField(default=True) # type: bool enable_offline_push_notifications = models.BooleanField(default=True) # type: bool
enable_online_push_notifications = models.BooleanField(default=False) # type: bool
enable_digest_emails = models.BooleanField(default=True) # type: bool enable_digest_emails = models.BooleanField(default=True) # type: bool
@ -556,6 +557,11 @@ def receives_offline_notifications(user_profile):
user_profile.enable_offline_push_notifications) and user_profile.enable_offline_push_notifications) and
not user_profile.is_bot) not user_profile.is_bot)
def receives_online_notifications(user_profile):
# type: (UserProfile) -> bool
return (user_profile.enable_online_push_notifications and
not user_profile.is_bot)
# Make sure we flush the UserProfile object from our remote cache # Make sure we flush the UserProfile object from our remote cache
# whenever we save it. # whenever we save it.
post_save.connect(flush_user_profile, sender=UserProfile) post_save.connect(flush_user_profile, sender=UserProfile)

View File

@ -1564,6 +1564,7 @@ class ChangeSettingsTest(ZulipTestCase):
self.check_for_toggle_param("/json/notify_settings/change", "enable_sounds") self.check_for_toggle_param("/json/notify_settings/change", "enable_sounds")
self.check_for_toggle_param("/json/notify_settings/change", "enable_offline_email_notifications") self.check_for_toggle_param("/json/notify_settings/change", "enable_offline_email_notifications")
self.check_for_toggle_param("/json/notify_settings/change", "enable_offline_push_notifications") self.check_for_toggle_param("/json/notify_settings/change", "enable_offline_push_notifications")
self.check_for_toggle_param("/json/notify_settings/change", "enable_online_push_notifications")
self.check_for_toggle_param("/json/notify_settings/change", "enable_digest_emails") self.check_for_toggle_param("/json/notify_settings/change", "enable_digest_emails")
def test_ui_settings(self): def test_ui_settings(self):
@ -1785,6 +1786,7 @@ class HomeTest(ZulipTestCase):
"enable_digest_emails", "enable_digest_emails",
"enable_offline_email_notifications", "enable_offline_email_notifications",
"enable_offline_push_notifications", "enable_offline_push_notifications",
"enable_online_push_notifications",
"enter_sends", "enter_sends",
"event_queue_id", "event_queue_id",
"first_in_realm", "first_in_realm",

View File

@ -569,6 +569,8 @@ def home(request):
user_profile.enable_offline_email_notifications, user_profile.enable_offline_email_notifications,
enable_offline_push_notifications = enable_offline_push_notifications =
user_profile.enable_offline_push_notifications, user_profile.enable_offline_push_notifications,
enable_online_push_notifications =
user_profile.enable_online_push_notifications,
twenty_four_hour_time = register_ret['twenty_four_hour_time'], twenty_four_hour_time = register_ret['twenty_four_hour_time'],
enable_digest_emails = user_profile.enable_digest_emails, enable_digest_emails = user_profile.enable_digest_emails,

View File

@ -12,8 +12,8 @@ from zerver.lib.actions import do_change_password, \
do_change_full_name, do_change_enable_desktop_notifications, \ do_change_full_name, do_change_enable_desktop_notifications, \
do_change_enter_sends, do_change_enable_sounds, \ do_change_enter_sends, do_change_enable_sounds, \
do_change_enable_offline_email_notifications, do_change_enable_digest_emails, \ do_change_enable_offline_email_notifications, do_change_enable_digest_emails, \
do_change_enable_offline_push_notifications, do_change_autoscroll_forever, \ do_change_enable_offline_push_notifications, do_change_enable_online_push_notifications, \
do_change_default_desktop_notifications, \ do_change_default_desktop_notifications, do_change_autoscroll_forever, \
do_change_enable_stream_desktop_notifications, do_change_enable_stream_sounds, \ do_change_enable_stream_desktop_notifications, do_change_enable_stream_sounds, \
do_regenerate_api_key, do_change_avatar_source, do_change_twenty_four_hour_time, \ do_regenerate_api_key, do_change_avatar_source, do_change_twenty_four_hour_time, \
do_change_left_side_userlist, do_change_default_language do_change_left_side_userlist, do_change_default_language
@ -138,9 +138,11 @@ def json_change_notify_settings(request, user_profile,
default=None), default=None),
enable_offline_push_notifications=REQ(validator=check_bool, enable_offline_push_notifications=REQ(validator=check_bool,
default=None), default=None),
enable_online_push_notifications=REQ(validator=check_bool,
default=None),
enable_digest_emails=REQ(validator=check_bool, enable_digest_emails=REQ(validator=check_bool,
default=None)): default=None)):
# type: (HttpRequest, UserProfile, Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool]) -> HttpResponse # type: (HttpRequest, UserProfile, Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool]) -> HttpResponse
result = {} result = {}
# Stream notification settings. # Stream notification settings.
@ -178,6 +180,11 @@ def json_change_notify_settings(request, user_profile,
do_change_enable_offline_push_notifications(user_profile, enable_offline_push_notifications) do_change_enable_offline_push_notifications(user_profile, enable_offline_push_notifications)
result['enable_offline_push_notifications'] = enable_offline_push_notifications result['enable_offline_push_notifications'] = enable_offline_push_notifications
if enable_online_push_notifications is not None and \
user_profile.enable_online_push_notifications != enable_online_push_notifications:
do_change_enable_online_push_notifications(user_profile, enable_online_push_notifications)
result['enable_online_push_notifications'] = enable_online_push_notifications
if enable_digest_emails is not None and \ if enable_digest_emails is not None and \
user_profile.enable_digest_emails != enable_digest_emails: user_profile.enable_digest_emails != enable_digest_emails:
do_change_enable_digest_emails(user_profile, enable_digest_emails) do_change_enable_digest_emails(user_profile, enable_digest_emails)

View File

@ -618,6 +618,12 @@ def restore_saved_messages():
old_message["enable_offline_push_notifications"] != "false") old_message["enable_offline_push_notifications"] != "false")
user_profile.save(update_fields=["enable_offline_push_notifications"]) user_profile.save(update_fields=["enable_offline_push_notifications"])
continue continue
elif message_type == "enable_online_push_notifications_changed":
user_profile = users[old_message["user"]]
user_profile.enable_online_push_notifications_changed = (
old_message["enable_online_push_notifications_changed"] != "false")
user_profile.save(update_fields=["enable_online_push_notifications_changed"])
continue
elif message_type == "default_streams": elif message_type == "default_streams":
set_default_streams(get_realm(old_message["domain"]), set_default_streams(get_realm(old_message["domain"]),
old_message["streams"]) old_message["streams"])