recent_topics: Add avatars of recent senders to topic.

This commit is contained in:
Aman Agrawal 2020-05-23 00:34:03 +05:30 committed by Tim Abbott
parent bdaf4e1079
commit bc7136590a
6 changed files with 112 additions and 0 deletions

View File

@ -598,6 +598,26 @@ run_test('message_methods', () => {
assert.equal(people.small_avatar_url_for_person(maria),
'https://secure.gravatar.com/avatar/md5-athens@example.com?d=identicon&s=50');
assert.deepEqual(people.sender_info_with_small_avatar_urls_for_sender_ids([30]), [
{
avatar_url_small: 'https://secure.gravatar.com/avatar/md5-me@example.com?d=identicon&s=50',
email: 'me@example.com',
full_name: 'Me the Third',
is_admin: false,
is_bot: false,
is_guest: false,
profile_data: {
3: {
rendered_value: '<p>Field value</p>',
value: 'Field value',
},
},
timezone: 'US/Pacific',
user_id: 30,
},
]);
let message = {
type: 'private',
display_recipient: [

View File

@ -13,6 +13,9 @@ set_global('people', {
is_my_user_id: function (id) {
return id === 1;
},
sender_info_with_small_avatar_urls_for_sender_ids: (ids) => {
return ids;
},
});
set_global('XDate', zrequire('XDate', 'xdate'));
set_global('timerender', {
@ -33,6 +36,9 @@ set_global('hash_util', {
return "https://www.example.com";
},
});
set_global('recent_senders', {
get_topic_recent_senders: () => { return [1, 2]; },
});
// Custom Data
@ -195,6 +201,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: true,
senders: [1, 2],
count_senders: 0,
},
{
stream_id: 1,
@ -205,6 +213,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: false,
senders: [1, 2],
count_senders: 0,
},
{
stream_id: 1,
@ -215,6 +225,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: false,
senders: [1, 2],
count_senders: 0,
},
{
stream_id: 1,
@ -225,6 +237,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: false,
senders: [1, 2],
count_senders: 0,
},
{
stream_id: 1,
@ -235,6 +249,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: false,
senders: [1, 2],
count_senders: 0,
},
{
stream_id: 1,
@ -245,6 +261,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: false,
senders: [1, 2],
count_senders: 0,
},
{
stream_id: 1,
@ -255,6 +273,8 @@ run_test("test_recent_topics_launch", () => {
stream_url: 'https://www.example.com',
topic_url: 'https://www.example.com',
hidden: false,
senders: [1, 2],
count_senders: 0,
},
],
};

View File

@ -605,6 +605,16 @@ exports.small_avatar_url_for_person = function (person) {
return gravatar_url_for_email(person.email);
};
exports.sender_info_with_small_avatar_urls_for_sender_ids = function (sender_ids) {
const senders_info = [];
for (const id of sender_ids) {
const sender = {...exports.get_by_user_id(id)};
sender.avatar_url_small = exports.small_avatar_url_for_person(sender);
senders_info.push(sender);
}
return senders_info;
};
exports.small_avatar_url = function (message) {
// Try to call this function in all places where we need 25px
// avatar images, so that the browser can help

View File

@ -1,6 +1,9 @@
const render_recent_topics_body = require('../templates/recent_topics_table.hbs');
const render_recent_topic_row = require('../templates/recent_topic_row.hbs');
const topics = new Map(); // Key is stream-id:topic.
// Sets the number of avatars to display.
// Rest of the avatars, if present, are displayed as {+x}
const MAX_AVATAR = 4;
exports.process_messages = function (messages) {
// Since a complete re-render is expensive, we
@ -77,6 +80,12 @@ function format_topic(topic_data) {
const last_msg_time = timerender.last_seen_status_from_date(time);
const unread_count = unread.unread_topic_counter.get(stream_id, topic);
const hidden = muting.is_topic_muted(stream_id, topic);
// Display in most recent sender first order
const all_senders = recent_senders.get_topic_recent_senders(stream_id, topic);
const senders = all_senders.slice(-MAX_AVATAR);
const senders_info = people.sender_info_with_small_avatar_urls_for_sender_ids(senders);
return {
stream_id: stream_id,
stream: stream,
@ -86,6 +95,8 @@ function format_topic(topic_data) {
stream_url: hash_util.by_stream_uri(stream_id),
topic_url: hash_util.by_stream_topic_uri(stream_id, topic),
hidden: hidden,
senders: senders_info,
count_senders: Math.max(0, all_senders.length - MAX_AVATAR),
};
}

View File

@ -69,5 +69,44 @@
// is set to header's width.
width: 1px;
}
.recent_avatars {
display: inline-flex; /* Causes LI items to display in row. */
list-style-type: none;
margin: auto; /* Centers vertically / horizontally in flex container. */
height: 15px !important;
/*
By using the row-reverse layout, the visual ordering will be opposite of
the DOM ordering. This will allows us to stack the items in the opposite
direction of the natural stacking order without having to mess with the
zIndex value. The MAJOR DOWNSIDE is that the HTML itself now reads
backwards, which super janky.
*/
flex-direction: row-reverse;
}
.recent_avatars_item {
height: 18px;
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
position: relative;
min-width: 18px;
}
.recent_avatars_img,
.recent_avatars_others {
border: 1px solid hsl(221.1, 23.5%, 15.9%);
border-left: 0 !important;
border-radius: 6px;
color: hsl(0, 0%, 100%);
display: block;
height: 18px;
text-align: center;
}
.recent_avatars_others {
background-color: hsl(205.2, 76.5%, 50%);
}
}
}

View File

@ -17,6 +17,18 @@
<i class="fa fa-check-circle on_hover_topic_read recipient_bar_icon" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" title="{{t 'Mark as read' }}" role="button" tabindex="0" aria-label="{{t 'Mark as read' }}"></i>
</td>
<td class='recent_topic_users'>
<ul class="recent_avatars">
{{#if count_senders}}
<li class="recent_avatars_item">
<span class="recent_avatars_others">+{{count_senders}}</span>
</li>
{{/if}}
{{#each senders}}
<li class="recent_avatars_item" title="{{this.full_name}}">
<img src="{{this.avatar_url_small}}" class="recent_avatars_img" />
</li>
{{/each}}
</ul>
</td>
<td class="recent_topic_timestamp">
{{ last_msg_time }}