mirror of https://github.com/zulip/zulip.git
[manual] Unify huddles and personals into private messages on the receive path
feedback-bot and zephyr_mirror will need to be updated and restarted when this is deployed to prod. (imported from commit fe2b524424c174bcb1b717a851a5d3815fda3f69)
This commit is contained in:
parent
02df4f76b6
commit
7e4776322d
|
@ -18,7 +18,7 @@ staging_client = humbug.Client(
|
|||
site="https://staging.humbughq.com")
|
||||
|
||||
def forward_message(message):
|
||||
if message["type"] != "personal":
|
||||
if message["type"] != "private" or len(message["recipient"]) != 2:
|
||||
return
|
||||
forwarded_message = {
|
||||
"type": "stream",
|
||||
|
|
|
@ -461,13 +461,14 @@ def forward_to_zephyr(message):
|
|||
instance = zephyr_class
|
||||
zephyr_class = "message"
|
||||
zwrite_args.extend(["-c", zephyr_class, "-i", instance])
|
||||
elif message['type'] == "personal":
|
||||
recipient = to_zephyr_username(message["display_recipient"]["email"])
|
||||
zwrite_args.extend([recipient])
|
||||
elif message['type'] == "huddle":
|
||||
zwrite_args.extend(["-C"])
|
||||
zwrite_args.extend([to_zephyr_username(user["email"]).replace("@ATHENA.MIT.EDU", "")
|
||||
for user in message["display_recipient"]])
|
||||
elif message['type'] == "private":
|
||||
if len(message['display_recipient']) == 1:
|
||||
recipient = to_zephyr_username(message["display_recipient"][0]["email"])
|
||||
zwrite_args.extend([recipient])
|
||||
else:
|
||||
zwrite_args.extend(["-C"])
|
||||
zwrite_args.extend([to_zephyr_username(user["email"]).replace("@ATHENA.MIT.EDU", "")
|
||||
for user in message["display_recipient"]])
|
||||
|
||||
if options.test_mode:
|
||||
logger.debug("Would have forwarded: %s\n%s" %
|
||||
|
@ -522,12 +523,10 @@ received it, Zephyr users did not. The error message from zwrite was:
|
|||
def maybe_forward_to_zephyr(message):
|
||||
if (message["sender_email"] == options.user + "@mit.edu"):
|
||||
if not ((message["type"] == "stream") or
|
||||
(message["type"] == "personal" and
|
||||
message["display_recipient"]["email"].lower().endswith("mit.edu")) or
|
||||
(message["type"] == "huddle" and
|
||||
(message["type"] == "private" and
|
||||
False not in [u["email"].lower().endswith("mit.edu") for u in
|
||||
message["display_recipient"]])):
|
||||
# Don't try forward personals/huddles with non-MIT users
|
||||
# Don't try forward private messages with non-MIT users
|
||||
# to MIT Zephyr.
|
||||
return
|
||||
timestamp_now = datetime.datetime.now().strftime("%s")
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
<td colspan="2" class="message_label_clickable message_header message_header_stream left_part"></td>
|
||||
<td class="message_label_clickable message_header message_header_stream right_part"></td>
|
||||
</tr>
|
||||
<tr style="display: none;" id="current_label_huddle" class="recipient_row">
|
||||
<td colspan="2" class="message_label_clickable message_header message_header_huddle left_part"></td>
|
||||
<td class="message_label_clickable message_header message_header_huddle right_part"></td>
|
||||
<tr style="display: none;" id="current_label_private_message" class="recipient_row">
|
||||
<td colspan="2" class="message_label_clickable message_header message_header_private_message left_part"></td>
|
||||
<td class="message_label_clickable message_header message_header_private_message right_part"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -90,15 +90,15 @@
|
|||
</td>
|
||||
</tr>
|
||||
<tr id="private-message">
|
||||
<td colspan="2" class="message_header message_header_huddle left_part"></td>
|
||||
<td class="message_header message_header_huddle right_part">
|
||||
<td colspan="2" class="message_header message_header_private_message left_part"></td>
|
||||
<td class="message_header message_header_private_message right_part">
|
||||
You and <input type="text" class="recipient_box" name="recipient" id="private_message_recipient"
|
||||
value="" placeholder="one or more people..." autocomplete="off" tabindex="130"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="message_picture">
|
||||
<div id="stream_or_huddle">
|
||||
<div id="stream_or_private_message">
|
||||
<ul class="nav nav-pills nav-stacked" id="message-type-tabs">
|
||||
<li class="active" id="stream_toggle">
|
||||
<a href="#stream-message" data-toggle="pill" title="Send a stream message" tabindex="100" onclick="compose.set_mode('stream');">
|
||||
|
|
|
@ -58,7 +58,7 @@ var globals =
|
|||
+ ' keep_pointer_in_view move_pointer_at_page_top_and_bottom'
|
||||
+ ' respond_to_message'
|
||||
+ ' select_message select_message_by_id'
|
||||
+ ' scroll_to_selected disable_pointer_movement'
|
||||
+ ' scroll_to_selected disable_pointer_movement get_private_message_recipient'
|
||||
+ ' load_old_messages'
|
||||
+ ' selected_message selected_message_id'
|
||||
+ ' at_top_of_viewport at_bottom_of_viewport'
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
{{else}}
|
||||
<tr zid="{{id}}" class="recipient_row">
|
||||
<td colspan="2"
|
||||
class="message_header message_header_huddle left_part">
|
||||
class="message_header message_header_private_message left_part">
|
||||
</td>
|
||||
<td class="message_label_clickable narrows_by_recipient message_header message_header_huddle right_part"
|
||||
<td class="message_label_clickable narrows_by_recipient message_header message_header_private_message right_part"
|
||||
title="Narrow to your private messages with {{display_reply_to}}">You and {{display_reply_to}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<i class="icon-share-alt"></i> Reply to this {{#if is_stream}}stream{{else}}private message{{/if}}
|
||||
</a>
|
||||
</li>
|
||||
{{#unless is_personal}}
|
||||
{{#unless is_private}}
|
||||
<li>
|
||||
<a onclick="respond_to_message('personal');">
|
||||
<i class="icon-user"></i> Reply to {{sender_full_name}} only
|
||||
|
|
|
@ -27,38 +27,18 @@ def get_display_recipient(recipient):
|
|||
"""
|
||||
recipient: an instance of Recipient.
|
||||
|
||||
returns: an appropriate string describing the recipient (the stream
|
||||
name, for a stream, or the email, for a user).
|
||||
"""
|
||||
if recipient.type == Recipient.STREAM:
|
||||
stream = Stream.objects.get(id=recipient.type_id)
|
||||
return stream.name
|
||||
elif recipient.type == Recipient.HUDDLE:
|
||||
# We don't really care what the ordering is, just that it's deterministic.
|
||||
user_profile_list = (UserProfile.objects.filter(subscription__recipient=recipient)
|
||||
.select_related()
|
||||
.order_by('user__email'))
|
||||
return [{'email': user_profile.user.email,
|
||||
'full_name': user_profile.full_name,
|
||||
'short_name': user_profile.short_name} for user_profile in user_profile_list]
|
||||
else:
|
||||
user_profile = UserProfile.objects.select_related().get(id=recipient.type_id)
|
||||
return {'email': user_profile.user.email,
|
||||
'full_name': user_profile.full_name,
|
||||
'short_name': user_profile.short_name}
|
||||
|
||||
def get_log_recipient(recipient):
|
||||
"""
|
||||
recipient: an instance of Recipient.
|
||||
|
||||
returns: an appropriate string describing the recipient (the stream
|
||||
name, for a stream, or the email, for a user).
|
||||
returns: an appropriate object describing the recipient. For a
|
||||
stream this will be the stream name as a string. For a huddle or
|
||||
personal, it will be an array of dicts about each recipient.
|
||||
"""
|
||||
if recipient.type == Recipient.STREAM:
|
||||
stream = Stream.objects.get(id=recipient.type_id)
|
||||
return stream.name
|
||||
|
||||
user_profile_list = UserProfile.objects.filter(subscription__recipient=recipient).select_related()
|
||||
# We don't really care what the ordering is, just that it's deterministic.
|
||||
user_profile_list = (UserProfile.objects.filter(subscription__recipient=recipient)
|
||||
.select_related()
|
||||
.order_by('user__email'))
|
||||
return [{'email': user_profile.user.email,
|
||||
'full_name': user_profile.full_name,
|
||||
'short_name': user_profile.short_name} for user_profile in user_profile_list]
|
||||
|
@ -427,13 +407,31 @@ class Message(models.Model):
|
|||
if hasattr(self, 'precomputed_dicts'):
|
||||
return self.precomputed_dicts['text/html' if apply_markdown else 'text/x-markdown']
|
||||
|
||||
display_recipient = get_display_recipient(self.recipient)
|
||||
if self.recipient.type == Recipient.STREAM:
|
||||
display_type = "stream"
|
||||
elif self.recipient.type in (Recipient.HUDDLE, Recipient.PERSONAL):
|
||||
display_type = "private"
|
||||
if len(display_recipient) == 1:
|
||||
# add the sender in if this isn't a message between
|
||||
# someone and his self, preserving ordering
|
||||
recip = {'email': self.sender.user.email,
|
||||
'full_name': self.sender.full_name,
|
||||
'short_name': self.sender.short_name};
|
||||
if recip['email'] < display_recipient[0]['email']:
|
||||
display_recipient = [recip, display_recipient[0]]
|
||||
elif recip['email'] > display_recipient[0]['email']:
|
||||
display_recipient = [display_recipient[0], recip]
|
||||
else:
|
||||
display_type = self.recipient.type_name()
|
||||
|
||||
obj = dict(
|
||||
id = self.id,
|
||||
sender_email = self.sender.user.email,
|
||||
sender_full_name = self.sender.full_name,
|
||||
sender_short_name = self.sender.short_name,
|
||||
type = self.recipient.type_name(),
|
||||
display_recipient = get_display_recipient(self.recipient),
|
||||
type = display_type,
|
||||
display_recipient = display_recipient,
|
||||
recipient_id = self.recipient.id,
|
||||
subject = self.subject,
|
||||
timestamp = calendar.timegm(self.pub_date.timetuple()),
|
||||
|
@ -456,7 +454,7 @@ class Message(models.Model):
|
|||
sender_short_name = self.sender.short_name,
|
||||
sending_client = self.sending_client.name,
|
||||
type = self.recipient.type_name(),
|
||||
recipient = get_log_recipient(self.recipient),
|
||||
recipient = get_display_recipient(self.recipient),
|
||||
subject = self.subject,
|
||||
content = self.content,
|
||||
timestamp = calendar.timegm(self.pub_date.timetuple()))
|
||||
|
|
|
@ -12,9 +12,9 @@ var directional_hotkeys = {
|
|||
};
|
||||
|
||||
var narrow_hotkeys = {
|
||||
115: narrow.by_recipient, // 's'
|
||||
83: narrow.by_subject, // 'S'
|
||||
118: narrow.all_huddles // 'v'
|
||||
115: narrow.by_recipient, // 's'
|
||||
83: narrow.by_subject, // 'S'
|
||||
118: narrow.all_private_messages // 'v'
|
||||
};
|
||||
|
||||
// Process a keydown or keypress event.
|
||||
|
@ -105,7 +105,7 @@ function process_hotkey(e) {
|
|||
case 99: // 'c': compose
|
||||
compose.start('stream');
|
||||
return true;
|
||||
case 67: // 'C': compose huddle
|
||||
case 67: // 'C': compose private message
|
||||
compose.start('private');
|
||||
return true;
|
||||
case 13: // Enter or
|
||||
|
|
|
@ -119,11 +119,11 @@ exports.target = function (id) {
|
|||
target_id = id;
|
||||
};
|
||||
|
||||
exports.all_huddles = function () {
|
||||
var new_narrow = {type: "all_huddles"};
|
||||
exports.all_private_messages = function () {
|
||||
var new_narrow = {type: "all_private_messages"};
|
||||
var bar = {icon: 'user', description: 'You and anyone else'};
|
||||
do_narrow(new_narrow, bar, false, function (other) {
|
||||
return other.type === "personal" || other.type === "huddle";
|
||||
return other.type === "private";
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -161,15 +161,12 @@ exports.by_stream_name = function (name) {
|
|||
};
|
||||
|
||||
exports.by_private_message_partner = function (their_name, their_email) {
|
||||
var new_narrow = {type: "huddle", one_on_one_email: their_email};
|
||||
var new_narrow = {type: "private", one_on_one_email: their_email};
|
||||
var bar = {icon: 'user', description: "You and " + their_name};
|
||||
var my_email = email;
|
||||
do_narrow(new_narrow, bar, false, function (other) {
|
||||
return (other.type === 'personal') &&
|
||||
(((other.display_recipient.email === their_email)
|
||||
&& (other.sender_email === my_email)) ||
|
||||
((other.display_recipient.email === my_email)
|
||||
&& (other.sender_email === their_email)));
|
||||
return (other.type === 'private' &&
|
||||
get_private_message_recipient(other, 'email') === their_email);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -177,26 +174,14 @@ exports.by_private_message_partner = function (their_name, their_email) {
|
|||
exports.by_recipient = function () {
|
||||
var message = message_dict[target_id];
|
||||
var bar;
|
||||
var new_narrow;
|
||||
switch (message.type) {
|
||||
case 'personal':
|
||||
// Narrow to personals with a specific user
|
||||
var new_narrow = {type: "huddle", one_on_one_email: message.reply_to};
|
||||
case 'private':
|
||||
new_narrow = {type: "private", recipient_id: message.recipient_id};
|
||||
bar = {icon: 'user', description: "You and " + message.display_reply_to};
|
||||
do_narrow(new_narrow, bar, false, function (other) {
|
||||
return (other.type === 'personal') &&
|
||||
(((other.display_recipient.email === message.display_recipient.email)
|
||||
&& (other.sender_email === message.sender_email)) ||
|
||||
((other.display_recipient.email === message.sender_email)
|
||||
&& (other.sender_email === message.display_recipient.email)));
|
||||
});
|
||||
break;
|
||||
|
||||
case 'huddle':
|
||||
new_narrow = {type: "huddle", recipient_id: message.recipient_id};
|
||||
bar = {icon: 'user', description: "You and " + message.display_reply_to};
|
||||
do_narrow(new_narrow, bar, false, function (other) {
|
||||
return (other.type === "personal" || other.type === "huddle")
|
||||
&& other.reply_to === message.reply_to;
|
||||
return (other.type === "private" &&
|
||||
other.reply_to === message.reply_to);
|
||||
});
|
||||
break;
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ function process_desktop_notification(message) {
|
|||
notification_object.cancel();
|
||||
}
|
||||
|
||||
if (message.type === "huddle") {
|
||||
if (message.type === "private" && message.display_recipient.length > 2) {
|
||||
// If the message has too many recipients to list them all...
|
||||
if (content.length + title.length + other_recipients.length > 230) {
|
||||
// Then count how many people are in the conversation and summarize
|
||||
|
@ -117,7 +117,7 @@ exports.received_messages = function (messages) {
|
|||
|
||||
if (desktop_notifications_enabled &&
|
||||
browser_desktop_notifications_on() &&
|
||||
(message.type === "personal" || message.type === "huddle")) {
|
||||
message.type === "private") {
|
||||
process_desktop_notification(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ function replace_floating_recipient_bar(desired_label) {
|
|||
if (desired_label !== old_label) {
|
||||
if (desired_label.children(".message_header_stream").length !== 0) {
|
||||
new_label = $("#current_label_stream");
|
||||
other_label = $("#current_label_huddle");
|
||||
other_label = $("#current_label_private_message");
|
||||
header = desired_label.children(".message_header_stream.right_part");
|
||||
|
||||
$("#current_label_stream td:first").css(
|
||||
|
@ -147,9 +147,9 @@ function replace_floating_recipient_bar(desired_label) {
|
|||
desired_label.children(".message_header_stream.right_part")
|
||||
.css("background-color"));
|
||||
} else {
|
||||
new_label = $("#current_label_huddle");
|
||||
new_label = $("#current_label_private_message");
|
||||
other_label = $("#current_label_stream");
|
||||
header = desired_label.children(".message_header_huddle.right_part");
|
||||
header = desired_label.children(".message_header_private_message.right_part");
|
||||
}
|
||||
new_label.find("td:last").replaceWith(header.clone());
|
||||
other_label.css('display', 'none');
|
||||
|
@ -228,7 +228,7 @@ function update_floating_recipient_bar() {
|
|||
// If we're narrowed to a huddle or a subject, the floating
|
||||
// recipient bar would be identical to the narrowing header, so
|
||||
// don't display it.
|
||||
if (narrow.narrowing_type() === "huddle" || narrow.narrowing_type() === "subject") {
|
||||
if (narrow.narrowing_type() === "private" || narrow.narrowing_type() === "subject") {
|
||||
hide_floating_recipient_bar();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -79,14 +79,14 @@ function scroll_to_selected() {
|
|||
recenter_view(selected_message);
|
||||
}
|
||||
|
||||
function get_huddle_recipient(message, attr) {
|
||||
function get_private_message_recipient(message, attr) {
|
||||
var recipient, i;
|
||||
var other_recipients = $.grep(message.display_recipient,
|
||||
function (element, index) {
|
||||
return element.email !== email;
|
||||
});
|
||||
if (other_recipients.length === 0) {
|
||||
// huddle with oneself
|
||||
// private message with oneself
|
||||
return message.display_recipient[0][attr];
|
||||
}
|
||||
|
||||
|
@ -109,16 +109,13 @@ function respond_to_message(reply_type) {
|
|||
}
|
||||
|
||||
var pm_recipient = message.reply_to;
|
||||
if (reply_type === "personal" && message.type === "huddle") {
|
||||
// reply_to for huddle messages is the whole huddle, so for
|
||||
// personals replies we need to set the the huddle recipient
|
||||
// to just the sender
|
||||
if (reply_type === "personal" && message.type === "private") {
|
||||
// reply_to for private messages is everyone involved, so for
|
||||
// personals replies we need to set the the private message
|
||||
// recipient to just the sender
|
||||
pm_recipient = message.sender_email;
|
||||
}
|
||||
if (reply_type === 'personal'
|
||||
|| message.type === 'personal'
|
||||
|| message.type === 'huddle')
|
||||
{
|
||||
if (reply_type === 'personal' || message.type === 'private') {
|
||||
msg_type = 'private';
|
||||
} else {
|
||||
msg_type = message.type;
|
||||
|
@ -216,9 +213,7 @@ function same_recipient(a, b) {
|
|||
return false;
|
||||
|
||||
switch (a.type) {
|
||||
case 'huddle':
|
||||
return a.recipient_id === b.recipient_id;
|
||||
case 'personal':
|
||||
case 'private':
|
||||
return a.reply_to === b.reply_to;
|
||||
case 'stream':
|
||||
return same_stream_and_subject(a, b);
|
||||
|
@ -448,10 +443,10 @@ function add_message_metadata(message, dummy) {
|
|||
'email': message.sender_email}];
|
||||
break;
|
||||
|
||||
case 'huddle':
|
||||
message.is_huddle = true;
|
||||
message.reply_to = get_huddle_recipient(message, 'email');
|
||||
message.display_reply_to = get_huddle_recipient(message, 'full_name');
|
||||
case 'private':
|
||||
message.is_private = true;
|
||||
message.reply_to = get_private_message_recipient(message, 'email');
|
||||
message.display_reply_to = get_private_message_recipient(message, 'full_name');
|
||||
|
||||
involved_people = message.display_recipient;
|
||||
|
||||
|
@ -461,25 +456,6 @@ function add_message_metadata(message, dummy) {
|
|||
typeahead_helper.update_all_recipients(involved_people);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'personal':
|
||||
message.is_personal = true;
|
||||
|
||||
involved_people = [message.display_recipient,
|
||||
{'email': message.sender_email,
|
||||
'full_name': message.sender_full_name}];
|
||||
|
||||
if (message.sender_email === email) { // that is, we sent the original message
|
||||
message.reply_to = message.display_recipient.email;
|
||||
message.display_reply_to = message.display_recipient.full_name;
|
||||
typeahead_helper.update_your_recipients(involved_people);
|
||||
} else {
|
||||
message.reply_to = message.sender_email;
|
||||
message.display_reply_to = message.sender_full_name;
|
||||
typeahead_helper.update_all_recipients(involved_people);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Add new people involved in this message to the people list
|
||||
|
|
|
@ -160,7 +160,7 @@ td.pointer {
|
|||
border: 1px solid grey;
|
||||
}
|
||||
|
||||
.message_header_huddle {
|
||||
.message_header_private_message {
|
||||
color: white;
|
||||
background-color: #444;
|
||||
border: 1px solid #444;
|
||||
|
@ -204,7 +204,7 @@ td.pointer {
|
|||
}
|
||||
|
||||
/* Brighten hover because of the dark background */
|
||||
.recipient_row .message_header_huddle:hover {
|
||||
.recipient_row .message_header_private_message:hover {
|
||||
color: #3BF;
|
||||
}
|
||||
|
||||
|
@ -497,7 +497,7 @@ table.floating_recipient {
|
|||
padding-right: 40px;
|
||||
}
|
||||
|
||||
#stream_or_huddle {
|
||||
#stream_or_private_message {
|
||||
margin: 3px;
|
||||
padding: 5px;
|
||||
width: 90%;
|
||||
|
|
|
@ -268,7 +268,7 @@ def get_old_messages_backend(request, anchor = POST(converter=to_non_negative_in
|
|||
query = query.filter(Q(sender__user__email=narrow['one_on_one_email']) & Q(recipient=recipient))
|
||||
else:
|
||||
query = query.filter(Q(sender__user__email=narrow['one_on_one_email']) | Q(recipient=recipient))
|
||||
elif 'type' in narrow and (narrow['type'] == "huddle" or narrow['type'] == "all_huddles"):
|
||||
elif 'type' in narrow and (narrow['type'] == "private" or narrow['type'] == "all_private_messages"):
|
||||
query = query.filter(Q(recipient__type=Recipient.PERSONAL) | Q(recipient__type=Recipient.HUDDLE))
|
||||
|
||||
if 'subject' in narrow:
|
||||
|
|
Loading…
Reference in New Issue