Skip to content

Commit

Permalink
user_settings: Add checkbox to enable/disable PM on invitee signup.
Browse files Browse the repository at this point in the history
Everytime an invitee joins any realm the referrer is informed about
invitee joining the realm through private message.

This commit adds a checkbox at invite modal which allows the user to
choose whether or not to get that private message. For that a new
`receive_private_message_on_invitee_signup` field is added to user_
notification_setting.

Fixes: zulip#20398
  • Loading branch information
yashd26 committed Jan 29, 2022
1 parent 90e202c commit 6fab353
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 3 deletions.
14 changes: 14 additions & 0 deletions static/js/invite.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import * as settings_config from "./settings_config";
import * as stream_data from "./stream_data";
import * as ui from "./ui";
import * as ui_report from "./ui_report";
import {user_settings} from "./user_settings";
import * as util from "./util";

function reset_error_messages() {
Expand Down Expand Up @@ -68,6 +69,15 @@ function submit_invitation_form() {
const invitee_emails_group = invitee_emails.closest(".control-group");
const data = get_common_invitation_data();
data.invitee_emails = $("#invitee_emails").val();
const receive_private_message_on_invitee_signup = JSON.stringify(
$("#receive_pm").prop("checked"),
);

channel.patch({
url: "/json/settings",
idempotent: true,
data: {receive_private_message_on_invitee_signup},
});

channel.post({
url: "/json/invites",
Expand Down Expand Up @@ -126,6 +136,7 @@ function submit_invitation_form() {
$("#submit-invitation").text($t({defaultMessage: "Invite"}));
$("#submit-invitation").prop("disabled", false);
$("#invitee_emails").focus();
$("#receive_pm").prop("checked", true);
ui.get_scroll_element($("#invite_user_form .modal-body"))[0].scrollTop = 0;
},
});
Expand Down Expand Up @@ -211,6 +222,7 @@ export function initialize() {
development_environment: page_params.development_environment,
invite_as_options: settings_config.user_role_values,
expires_in_options: settings_config.expires_in_values,
receive_pm_enabled: user_settings.receive_private_message_on_invitee_signup,
});

$(".app").append(rendered);
Expand All @@ -237,13 +249,15 @@ export function initialize() {
$("#multiuse_radio_section").show();
$("#invite-method-choice").hide();
$("#invitee_emails").prop("disabled", true);
$("#receive_pm").prop("disabled", true);
$("#submit-invitation").text($t({defaultMessage: "Generate invite link"}));
$("#submit-invitation").data("loading-text", $t({defaultMessage: "Generating link..."}));
reset_error_messages();
});

$("#invite-user").on("change", "#generate_multiuse_invite_radio", () => {
$("#invitee_emails").prop("disabled", false);
$("#receive_pm").prop("disabled", false);
$("#submit-invitation").text($t({defaultMessage: "Invite"}));
$("#submit-invitation").data("loading-text", $t({defaultMessage: "Inviting..."}));
$("#multiuse_radio_section").hide();
Expand Down
1 change: 1 addition & 0 deletions static/js/user_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type UserSettingsType = {
send_stream_typing_notifications: boolean;
send_private_typing_notifications: boolean;
send_read_receipts: boolean;
receive_private_message_on_invitee_signup: boolean;
};

export let user_settings = {} as UserSettingsType;
Expand Down
7 changes: 7 additions & 0 deletions static/templates/invite_user.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@
</select>
</div>
</div>
<div class="input-group">
<label class="checkbox display-block" for="receive_pm">
<input type="checkbox" id="receive_pm" name="receive_pm" {{#if receive_pm_enabled }} checked{{/if}} />
<span></span>
{{t "Send me a private message when my invitation is accepted" }}
</label>
</div>
<div>
<label>{{t "Streams they should join" }}</label>
<div id="streams_to_add"></div>
Expand Down
4 changes: 4 additions & 0 deletions templates/zerver/api/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ format used by the Zulip server that they are interacting with.

## Changes in Zulip 5.0

**Feature level 115**

* [`PATCH /settings`](/api/update-settings), [`POST /register`](/api/register-queue), [`PATCH /settings`](/api/get-server-settings): Added new user notification setting `receive_private_message_on_invitee_signup` to allow user to choose whether or not to get private message when an invitee joins.

**Feature level 114**

* [`GET /events`](/api/get-events): Added `rendering_only` field to
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
# Changes should be accompanied by documentation explaining what the
# new level means in templates/zerver/api/changelog.md, as well as
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
API_FEATURE_LEVEL = 114
API_FEATURE_LEVEL = 115

# Bump the minor PROVISION_VERSION to indicate that folks should provision
# only when going from an old version of the code to a newer version. Bump
Expand Down
6 changes: 5 additions & 1 deletion zerver/lib/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ def process_new_human_user(
and prereg_user is not None
and prereg_user.referred_by is not None
and prereg_user.referred_by.is_active
and prereg_user.referred_by.receive_private_message_on_invitee_signup
):
# This is a cross-realm private message.
with override_language(prereg_user.referred_by.default_language):
Expand Down Expand Up @@ -7622,7 +7623,10 @@ def do_invite_users(
for email in validated_emails:
# The logged in user is the referrer.
prereg_user = PreregistrationUser(
email=email, referred_by=user_profile, invited_as=invite_as, realm=user_profile.realm
email=email,
referred_by=user_profile,
invited_as=invite_as,
realm=user_profile.realm,
)
prereg_user.save()
stream_ids = [stream.id for stream in streams]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.10 on 2022-01-29 16:05

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('zerver', '0374_backfill_user_delete_realmauditlog'),
]

operations = [
migrations.AddField(
model_name='realmuserdefault',
name='receive_private_message_on_invitee_signup',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='userprofile',
name='receive_private_message_on_invitee_signup',
field=models.BooleanField(default=True),
),
]
6 changes: 5 additions & 1 deletion zerver/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,7 @@ class UserBaseSettings(models.Model):
enable_marketing_emails: bool = models.BooleanField(default=True)
realm_name_in_notifications: bool = models.BooleanField(default=False)
presence_enabled: bool = models.BooleanField(default=True)
receive_private_message_on_invitee_signup: bool = models.BooleanField(default=True)

# Whether or not the user wants to sync their drafts.
enable_drafts_synchronization = models.BooleanField(default=True)
Expand Down Expand Up @@ -1542,7 +1543,10 @@ class UserBaseSettings(models.Model):
)

notification_setting_types = {
**notification_settings_legacy
**notification_settings_legacy,
**dict(
receive_private_message_on_invitee_signup=bool,
),
} # Add new notifications settings here.

# Define the types of the various automatically managed properties
Expand Down
34 changes: 34 additions & 0 deletions zerver/openapi/zulip.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7898,6 +7898,15 @@ paths:
schema:
type: boolean
example: true
- name: receive_private_message_on_invitee_signup
in: query
description: |
Whether or not to receive private message on invitee signup.

**Changes**: New in Zulip 5.0 (feature level 115).
schema:
type: boolean
example: true
responses:
"200":
description: Success
Expand Down Expand Up @@ -9764,6 +9773,12 @@ paths:
read messages.

**Changes**: New in Zulip 5.0 (feature level 105).
receive_private_message_on_invitee_signup:
type: boolean
description: |
Whether or not to receive private message on invitee signup.

**Changes**: New in Zulip 5.0 (feature level 115).
has_zoom_token:
type: boolean
description: |
Expand Down Expand Up @@ -11476,6 +11491,12 @@ paths:
read messages.

**Changes**: New in Zulip 5.0 (feature level 105).
receive_private_message_on_invitee_signup:
type: boolean
description: |
Whether or not to receive private message on invitee signup.

**Changes**: New in Zulip 5.0 (feature level 115).
realm_users:
type: array
description: |
Expand Down Expand Up @@ -11669,6 +11690,10 @@ paths:
Present if `realm_user` is present in `fetch_event_types`.

The full name of the current user.
receive_private_message_on_invitee_signup:
type: boolean
description: |
Whether or not to receive private message on invitee signup.
cross_realm_bots:
type: array
description: |
Expand Down Expand Up @@ -12559,6 +12584,15 @@ paths:
schema:
type: boolean
example: true
- name: receive_private_message_on_invitee_signup
in: query
description: |
Whether or not to receive private message on invitee signup.

**Changes**: New in Zulip 5.0 (feature level 115).
schema:
type: boolean
example: true
responses:
"200":
description: Success
Expand Down
43 changes: 43 additions & 0 deletions zerver/tests/test_signup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
do_change_full_name,
do_change_realm_subdomain,
do_change_user_role,
do_change_user_setting,
do_create_default_stream_group,
do_create_multiuse_invite_link,
do_create_realm,
Expand Down Expand Up @@ -1619,6 +1620,48 @@ def test_invite_user_signup_initial_history(self) -> None:
self.assertTrue(invitee_msg.content.startswith("Hello, and welcome to Zulip!"))
self.assertNotIn("demo organization", invitee_msg.content)

# when receive_private_message_on_invitee_signup is set to False
secret_msg_id = self.send_stream_message(
self.example_user("hamlet"),
private_stream_name,
topic_name="Secret topic",
content="Secret message",
)
invitee = self.nonreg_email("bob")
self.assert_json_success(self.invite(invitee, [private_stream_name, "Denmark"]))
self.assertTrue(find_key_by_email(invitee))

prereg_user = PreregistrationUser.objects.get(email=invitee)
do_change_user_setting(
prereg_user.referred_by,
"receive_private_message_on_invitee_signup",
False,
acting_user=prereg_user.referred_by,
)
self.submit_reg_form_for_user(invitee, "password")
invitee_profile = self.nonreg_user("bob")
invitee_msg_ids = [
um.message_id for um in UserMessage.objects.filter(user_profile=invitee_profile)
]
self.assertTrue(public_msg_id in invitee_msg_ids)
self.assertFalse(secret_msg_id in invitee_msg_ids)
self.assertFalse(invitee_profile.is_realm_admin)

invitee_msg, signups_stream_msg, secret_msg = Message.objects.all().order_by("-id")[0:3]

self.assertEqual(secret_msg.id, secret_msg_id)

self.assertEqual(signups_stream_msg.sender.email, "notification-bot@zulip.com")
self.assertTrue(
signups_stream_msg.content.startswith(
f"@_**bob_zulip.com|{invitee_profile.id}** just signed up",
)
)

self.assertEqual(invitee_msg.sender.email, "welcome-bot@zulip.com")
self.assertTrue(invitee_msg.content.startswith("Hello, and welcome to Zulip!"))
self.assertNotIn("demo organization", invitee_msg.content)

def test_multi_user_invite(self) -> None:
"""
Invites multiple users with a variety of delimiters.
Expand Down
3 changes: 3 additions & 0 deletions zerver/views/realm.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ def update_realm_user_settings_defaults(
json_validator=check_bool, default=None
),
send_read_receipts: Optional[bool] = REQ(json_validator=check_bool, default=None),
receive_private_message_on_invitee_signup: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
) -> HttpResponse:
if notification_sound is not None or email_notifications_batching_period_seconds is not None:
check_settings_values(notification_sound, email_notifications_batching_period_seconds)
Expand Down
3 changes: 3 additions & 0 deletions zerver/views/user_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ def json_change_settings(
),
send_stream_typing_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
send_read_receipts: Optional[bool] = REQ(json_validator=check_bool, default=None),
receive_private_message_on_invitee_signup: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
) -> HttpResponse:
if (
default_language is not None
Expand Down

0 comments on commit 6fab353

Please sign in to comment.