DEV Community

Cover image for Initial Thoughts on a Zulip's Issue
Oliver Pham
Oliver Pham

Posted on • Updated on

Initial Thoughts on a Zulip's Issue

At the beginning of this week, I've found an interesting issue on Zulip's repo.

GitHub logo zulip / zulip

Zulip server and web application. Open-source team chat that helps teams stay productive and focused.

Zulip overview

Zulip is an open-source team collaboration tool with unique topic-based threading that combines the best of email and chat to make remote work productive and delightful. Fortune 500 companies, leading open source projects, and thousands of other organizations use Zulip every day. Zulip is the only modern team chat app that is designed for both live and asynchronous conversations.

Zulip is built by a distributed community of developers from all around the world, with 74+ people who have each contributed 100+ commits. With over 1000 contributors merging over 500 commits a month, Zulip is the largest and fastest growing open source team chat project.

Come find us on the development community chat!

GitHub Actions build status coverage status Mypy coverage Ruff code style: black code style: prettier GitHub release docs Zulip chat Twitter GitHub Sponsors

Getting started

  • Contributing code. Check out our guide for new contributors to get started. We have invested in making Zulip’s code highly readable, thoughtfully tested, and easy to modify. Beyond that, we have…

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

alya avatar
alya posted on

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.

CZO discussion thread

For reference, the @-mention UI: Screen Shot 2021-11-15 at 5 07 42 PM

Current search suggestions UI: Screen Shot 2021-11-15 at 5 08 29 PM

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}}
    &nbsp;&nbsp;
{{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}}
&nbsp;&nbsp;
<small class="autocomplete_secondary">
    {{~ secondary ~}}
</small>
{{#if is_unsubscribed}}
&nbsp;
<span class="fa fa-exclamation-triangle unsubscribed_icon"
  title="{{t 'You are not currently subscribed to this stream.' }}"></span>
{{/if}}
{{~/if}}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode
  • 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>
Enter fullscreen mode Exit fullscreen mode

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


  1. 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. 

Oldest comments (0)