Skip to content

Commit

Permalink
Users sidebar should show a highlighted buddy list (Backend).
Browse files Browse the repository at this point in the history
This adds support for displaying a buddy list and adding and
removing users to it. The buddy list also displays users in
alphabetically increasing order. For moving users to and from
buddy list, user handlebar is re-rendered at the appropriate place.
A new endpoint has been created which manipulates the buddy list and
a backend test for the same has also been added.

Fixes: zulip#236.
  • Loading branch information
vabs22 committed Jan 25, 2017
1 parent 97d7186 commit f72212e
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 5 deletions.
5 changes: 5 additions & 0 deletions static/js/activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ function get_num_unread(user_id) {
function info_for(user_id) {
var presence = exports.presence_info[user_id].status;
var person = people.get_person_from_user_id(user_id);
var bool_buddy = false;
if (exports.buddy_list.indexOf(parseInt(user_id, 10)) > -1) {
bool_buddy = true;
}
return {
href: narrow.pm_with_uri(person.email),
name: person.full_name,
Expand All @@ -288,6 +292,7 @@ function info_for(user_id) {
type: presence,
type_desc: presence_descriptions[presence],
mobile: exports.presence_info[user_id].mobile,
bool_buddy: bool_buddy.toString(),
};
}

Expand Down
20 changes: 19 additions & 1 deletion zerver/lib/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
realm_filters_for_realm, RealmFilter, receives_offline_notifications, \
ScheduledJob, get_owned_bot_dicts, \
get_old_unclaimed_attachments, get_cross_realm_emails, receives_online_notifications, \
Reaction
Reaction, BuddyList

from zerver.lib.alert_words import alert_words_in_realm
from zerver.lib.avatar import get_avatar_url, avatar_url
Expand Down Expand Up @@ -2663,6 +2663,22 @@ def truncate_topic(topic):
# type: (Text) -> Text
return truncate_content(topic, MAX_SUBJECT_LENGTH, "...")

def do_update_buddy_list(user_profile, buddy_profile, should_add):
# type: (UserProfile, str, bool) -> None

record = BuddyList.objects.get_or_create(user=user_profile, buddy=buddy_profile)
if should_add == False:
record[0].delete()

def get_buddy_list(user_profile):
# type: (UserProfile) -> List[int]

records = BuddyList.objects.filter(user=user_profile)
user_list = []
for record in records:
user_list.append(record.buddy.id)

return user_list

def update_user_message_flags(message, ums):
# type: (Message, Iterable[UserMessage]) -> None
Expand Down Expand Up @@ -3125,6 +3141,8 @@ def fetch_initial_state_data(user_profile, event_types, queue_id):
# get any updates during a session from get_events()
pass

if want('buddy_list'):
state['buddy_list'] = get_buddy_list(user_profile)
if want('stream'):
state['streams'] = do_get_streams(user_profile)
if want('default_streams'):
Expand Down
29 changes: 29 additions & 0 deletions zerver/migrations/0050_auto_20170112_0752.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-12 12:52
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('zerver', '0049_userprofile_pm_content_in_desktop_notifications'),
]

operations = [
migrations.CreateModel(
name='BuddyList',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('buddy', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='buddy', to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL)),
],
),
migrations.AlterUniqueTogether(
name='buddylist',
unique_together=set([('user', 'buddy')]),
),
]
7 changes: 7 additions & 0 deletions zerver/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1390,3 +1390,10 @@ class ScheduledJob(models.Model):
# Kind if like a ForeignKey, but table is determined by type.
filter_id = models.IntegerField(null=True) # type: Optional[int]
filter_string = models.CharField(max_length=100) # type: Text

class BuddyList(models.Model):
user = models.ForeignKey(UserProfile, related_name="user") # type: UserProfile
buddy = models.ForeignKey(UserProfile, related_name="buddy") # type: UserProfile

class Meta(object):
unique_together = ("user", "buddy")
37 changes: 37 additions & 0 deletions zerver/tests/test_buddy_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function

from zerver.lib.test_classes import (
ZulipTestCase,
)

from zerver.models import (
get_user_profile_by_email,
)

import ujson

class BuddyListUpdateTest(ZulipTestCase):
def test_update_buddy_list(self):
# type: () -> None
user_email = "hamlet@zulip.com"
buddy_email = "iago@zulip.com"

self.login(user_email)
user_profile = get_user_profile_by_email(user_email)
buddy_profile = get_user_profile_by_email(buddy_email)

result = self.client_patch("/json/users/me/buddy", {
'user_id': ujson.dumps(str(user_profile.id)),
'buddy_id': ujson.dumps(str(buddy_profile.id)),
'should_add': ujson.dumps(str(True)),
})
self.assert_json_success(result)

result = self.client_patch("/json/users/me/buddy", {
'user_id': ujson.dumps(str(user_profile.id)),
'buddy_id': ujson.dumps(str(buddy_profile.id)),
'should_add': ujson.dumps(str(False)),
})
self.assert_json_success(result)
1 change: 1 addition & 0 deletions zerver/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,7 @@ def test_home(self):
"avatar_url",
"avatar_url_medium",
"bot_list",
"buddy_list",
"can_create_streams",
"cross_realm_bots",
"debug_mode",
Expand Down
1 change: 1 addition & 0 deletions zerver/views/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ def home_real(request):
notifications_stream = notifications_stream,
cross_realm_bots = list(get_cross_realm_dicts()),
use_websockets = settings.USE_WEBSOCKETS,
buddy_list = register_ret['buddy_list'],

# Stream message notification settings:
stream_desktop_notifications_enabled = user_profile.enable_stream_desktop_notifications,
Expand Down
22 changes: 20 additions & 2 deletions zerver/views/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
from zerver.lib.actions import do_change_full_name, do_change_is_admin, \
do_create_user, subscribed_to_stream, do_deactivate_user, do_reactivate_user, \
do_change_default_events_register_stream, do_change_default_sending_stream, \
do_change_default_all_public_streams, do_regenerate_api_key, do_change_avatar_source
do_change_default_all_public_streams, do_regenerate_api_key, do_change_avatar_source, \
do_update_buddy_list
from zerver.lib.avatar import avatar_url, get_avatar_url
from zerver.lib.response import json_error, json_success
from zerver.lib.upload import upload_avatar_image
from zerver.lib.validator import check_bool, check_string
from zerver.lib.utils import generate_random_token
from zerver.models import UserProfile, Stream, Realm, Message, get_user_profile_by_email, \
get_stream, email_allowed_for_realm
get_stream, email_allowed_for_realm, get_user_profile_by_id
from zproject.jinja2 import render_to_response


Expand Down Expand Up @@ -113,6 +114,23 @@ def update_user_backend(request, user_profile, email,

return json_success()

@has_request_variables
def update_buddy_list(request, user_profile, user_id=REQ(validator=check_string),
buddy_id=REQ(validator=check_string), should_add=REQ(validator=check_string)):
# type: (HttpRequest, UserProfile, str, str, str) -> HttpResponse
try:
user_profile = get_user_profile_by_id(user_id)
except UserProfile.DoesNotExist:
return json_error(_('No such user with email id ' + user_id))

try:
buddy_profile = get_user_profile_by_id(buddy_id)
except UserProfile.DoesNotExist:
return json_error(_('No such user with user id ' + buddy_id))
do_update_buddy_list(user_profile, buddy_profile, (should_add == "true"))

return json_success()

def avatar(request, email):
# type: (HttpRequest, str) -> HttpResponse
try:
Expand Down
4 changes: 2 additions & 2 deletions zproject/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@
url(r'^users/me$', rest_dispatch,
{'GET': 'zerver.views.users.get_profile_backend',
'DELETE': 'zerver.views.users.deactivate_user_own_backend'}),
# PUT is currently used by mobile apps, we intend to remove the PUT version
# as soon as possible. POST exists to correct the erroneous use of PUT.
url(r'^users/me/buddy$', rest_dispatch,
{'PATCH': 'zerver.views.users.update_buddy_list'}),
url(r'^users/me/pointer$', rest_dispatch,
{'GET': 'zerver.views.pointer.get_pointer_backend',
'PUT': 'zerver.views.pointer.update_pointer_backend',
Expand Down

0 comments on commit f72212e

Please sign in to comment.