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 app—powerful open source team chat

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.

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

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:

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 }}" />
        <span class='emoji emoji-{{ emoji_code }}'></span>
    {{#if is_person}}
        {{#if user_circle_class}}
        <span class="{{user_circle_class}} user_circle"></span>
        {{#if has_image}}
        <img class="typeahead-image" src="{{ img_src }}" />
        <span class='typeahead-image fa fa-bullhorn no-presence-circle'></span>
        {{#if is_user_group}}
        <i class="typeahead-image icon fa fa-group no-presence-circle" aria-hidden="true"></i>
    {{~ primary ~}}
{{~#if has_secondary}}
<small class="autocomplete_secondary">
    {{~ secondary ~}}
{{#if is_unsubscribed}}
<span class="fa fa-exclamation-triangle unsubscribed_icon"
  title="{{t 'You are not currently subscribed to this stream.' }}"></span>
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.


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. 

Discussion (0)