At the beginning of this week, I've found an interesting issue on Zulip's repo.
Zulip overview
Zulip is a powerful, open source group chat application that combines the immediacy of real-time chat with the productivity benefits of threaded conversations. Zulip is used by open source projects, Fortune 500 companies large standards bodies, and others who need a real-time chat system that allows users to easily process hundreds or thousands of messages a day. With over 700 contributors merging over 500 commits a month, Zulip is also the largest and fastest growing open source group chat project.
Getting started
Click on the appropriate link below. If nothing seems to apply join us on the Zulip community server and tell us what's up!
You might be interested in:
-
Contributing code. Check out our guide for new contributors to get started. Zulip prides itself on maintaining a clean and well-tested codebase, and a stock of hundreds of beginner-friendly issues.
-
Contributing non-code Report an issue…
Zulip is a popular open source communication platform built with Django (Python). Despite having spent some time one it, I eventually let another developer handle that issue1 and claimed another one. It's a feature request for showing profile pictures in search autocomplete suggestions.
Show profile pictures in search auto-complete suggestions
#20267
At present, we show profile pictures in @-mention auto-complete suggestions, but not in auto-complete suggestions for search. As a result, it's hard to quickly find the person you need in search auto-complete. Moreover, using the search suggestions is very awkward when multiple people have the same name.
To address this, we should show avatars in the search auto-complete suggestions when a user is being suggested (sender, PMs with, etc.).
From an implementation perspective, we would ideally reuse the send-PM-pills component rather than duplicating the logic.
What the feature involves
I was overwhelmed with Zulip's gigantic codebase and technologies. Luckily, their documentation is really clear, concise, and helpful. Although setting up a local development environment for the project took more time than usual, the process was straightforward. I had a chance to learn a bit about Docker and Vagrant. Apart from that, I had an unexpected reunion with Git's pre-commit hooks, my old friend from OSD's lab.
The next part was a nightmare: tracing the relevant code in a codebase developed by 700+ contributors with 45000+ commits. After doing some research and receiving support from Zulip's community server, I've had some ideas for the feature.
Based on an existing approach to a relatively similar feature, I need to customize the existing typeahead.js's layout to include an avatar for any suggested person or organization. As the author of the issue suggested, I could reuse a Handlebars partial for each suggestion.
How I approach it
Firstly, I need a way to render a user's profile picture from their name. After some code tracing, I found render_person_or_user_group()
, a typeahead's helper function that can help me with that task. It uses this Handlebars partial to render a suggestion:
{{#if is_emoji}}
{{#if has_image}}
<img class="emoji" src="{{ img_src }}" />
{{else}}
<span class='emoji emoji-{{ emoji_code }}'></span>
{{/if}}
{{else}}
{{#if is_person}}
{{#if user_circle_class}}
<span class="{{user_circle_class}} user_circle"></span>
{{/if}}
{{#if has_image}}
<img class="typeahead-image" src="{{ img_src }}" />
{{else}}
<span class='typeahead-image fa fa-bullhorn no-presence-circle'></span>
{{/if}}
{{else}}
{{#if is_user_group}}
<i class="typeahead-image icon fa fa-group no-presence-circle" aria-hidden="true"></i>
{{/if}}
{{/if}}
{{/if}}
<strong>
{{~ primary ~}}
</strong>
{{~#if has_secondary}}
<small class="autocomplete_secondary">
{{~ secondary ~}}
</small>
{{#if is_unsubscribed}}
<span class="fa fa-exclamation-triangle unsubscribed_icon"
title="{{t 'You are not currently subscribed to this stream.' }}"></span>
{{/if}}
{{~/if}}
Having said that, I still need more time to understand the behaviour of the function. It's likely that I have to write a similar one to exclude the irrelevant.
Secondly, I need to find a way to customize a suggestion's layout. After some research, I noticed highlighter()
is responsible for it:
highlighter(item) {
const obj = search_map.get(item);
return obj.description;
}
-
obj.description
is some bizarre raw HTML with a par of<strong>
tags, enclosing each character of a name, and another one that follows it and encloses absolutely nothing. For instance, the HTML for "Sent by Aayush Solanki" looks like this:
<a href="#">Sent by <strong>A</strong><strong></strong><strong>a</strong><strong></strong><strong>y</strong><strong></strong><strong>u</strong><strong></strong><strong>s</strong><strong></strong><strong>h</strong> <strong>S</strong><strong></strong><strong>o</strong><strong></strong><strong>l</strong><strong></strong><strong>a</strong><strong></strong><strong>n</strong><strong></strong><strong>k</strong><strong></strong><strong>i</strong></a>
Finally, I must come up with a way to connect the two functions seamlessly. This is the most complicated part.
Conclusion
This seems like an impactful contribution to a large open source project. I'm still clueless about how to build upon my initial approach, but I'll try to keep you posted about my progress.
Cover photo by Kaleidico on Unsplash
-
There was another developer who had worked on the issue before me. He abandoned the issue due to his college work. However, he asked to work on it again a day after I discussed my approaches with the project maintainers. Since he claimed to have some progress on it already, I decided to let him take over the issue. Do you think I've done the right thing in this situation? Let me know the comments. ↩
Discussion (0)