diff --git a/api/bots/feedback-bot b/api/bots/feedback-bot
index b1d521ebfc..75f130dcc6 100755
--- a/api/bots/feedback-bot
+++ b/api/bots/feedback-bot
@@ -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",
diff --git a/api/bots/zephyr_mirror_backend.py b/api/bots/zephyr_mirror_backend.py
index 058c8ddac6..8428ea5d65 100755
--- a/api/bots/zephyr_mirror_backend.py
+++ b/api/bots/zephyr_mirror_backend.py
@@ -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")
diff --git a/templates/zephyr/home.html b/templates/zephyr/home.html
index 4a54f3e090..435e9e909b 100644
--- a/templates/zephyr/home.html
+++ b/templates/zephyr/home.html
@@ -29,9 +29,9 @@
-
-
-
+
+
+
@@ -90,15 +90,15 @@
-
-
+
-
+
-
diff --git a/tools/jslint/check-all.js b/tools/jslint/check-all.js
index 0b79836335..af2c3b012b 100644
--- a/tools/jslint/check-all.js
+++ b/tools/jslint/check-all.js
@@ -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'
diff --git a/zephyr/jstemplates/message.html b/zephyr/jstemplates/message.html
index c3f63839d1..63fc132d2f 100644
--- a/zephyr/jstemplates/message.html
+++ b/zephyr/jstemplates/message.html
@@ -35,9 +35,9 @@
{{else}}
-
{{/if}}
diff --git a/zephyr/jstemplates/userinfo_popover_content.html b/zephyr/jstemplates/userinfo_popover_content.html
index da43175287..48e4df3174 100644
--- a/zephyr/jstemplates/userinfo_popover_content.html
+++ b/zephyr/jstemplates/userinfo_popover_content.html
@@ -5,7 +5,7 @@
Reply to this {{#if is_stream}}stream{{else}}private message{{/if}}
- {{#unless is_personal}}
+ {{#unless is_private}}
-
Reply to {{sender_full_name}} only
diff --git a/zephyr/models.py b/zephyr/models.py
index f72cdc4e46..56ab701a9c 100644
--- a/zephyr/models.py
+++ b/zephyr/models.py
@@ -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()))
diff --git a/zephyr/static/js/hotkey.js b/zephyr/static/js/hotkey.js
index 33064ac5f2..46b7ae655f 100644
--- a/zephyr/static/js/hotkey.js
+++ b/zephyr/static/js/hotkey.js
@@ -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
diff --git a/zephyr/static/js/narrow.js b/zephyr/static/js/narrow.js
index 1da907c759..eccff6f271 100644
--- a/zephyr/static/js/narrow.js
+++ b/zephyr/static/js/narrow.js
@@ -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;
diff --git a/zephyr/static/js/notifications.js b/zephyr/static/js/notifications.js
index e137f234bb..54331de465 100644
--- a/zephyr/static/js/notifications.js
+++ b/zephyr/static/js/notifications.js
@@ -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);
}
}
diff --git a/zephyr/static/js/ui.js b/zephyr/static/js/ui.js
index ce0d71c8e8..0d8e72af28 100644
--- a/zephyr/static/js/ui.js
+++ b/zephyr/static/js/ui.js
@@ -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;
}
diff --git a/zephyr/static/js/zephyr.js b/zephyr/static/js/zephyr.js
index a9221e37b0..187f690a4a 100644
--- a/zephyr/static/js/zephyr.js
+++ b/zephyr/static/js/zephyr.js
@@ -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
diff --git a/zephyr/static/styles/zephyr.css b/zephyr/static/styles/zephyr.css
index 31466c6263..da40bb8491 100644
--- a/zephyr/static/styles/zephyr.css
+++ b/zephyr/static/styles/zephyr.css
@@ -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%;
diff --git a/zephyr/views.py b/zephyr/views.py
index 4afb4b6338..470ce921e4 100644
--- a/zephyr/views.py
+++ b/zephyr/views.py
@@ -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:
|