You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/06/17 15:54:52 UTC

[allura] 01/02: [#8283] Implement user card for user mention hyper links

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 7694fc7cbec7bde3c7a66862982e0102f9a9b1cd
Author: Shalitha Suranga <sh...@gmail.com>
AuthorDate: Sat Jun 8 17:37:21 2019 +0530

    [#8283] Implement user card for user mention hyper links
---
 Allura/allura/ext/user_profile/user_main.py        | 12 +++++
 Allura/allura/nf/allura/css/site_style.css         | 30 +++++++++++
 Allura/allura/public/nf/js/allura-base.js          | 60 ++++++++++++++++++++++
 .../allura/tests/functional/test_user_profile.py   | 15 ++++++
 4 files changed, 117 insertions(+)

diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index a6f218f..67502fd 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -25,6 +25,8 @@ from tg import request
 from tg import tmpl_context as c, app_globals as g
 from pytz import timezone
 from tg import expose, redirect, validate, flash
+from tg.decorators import without_trailing_slash
+from decorator import decorator
 from webob import exc
 
 from allura import version
@@ -199,6 +201,16 @@ class UserProfileController(BaseController, FeedController):
                 g.user_message_max_messages,
                 g.user_message_time_interval), 'error')
         return redirect(c.project.user_project_of.url())
+        
+    @without_trailing_slash
+    @expose('json:')
+    def user_card(self):
+        u = c.project.user_project_of
+        return dict(
+            username=u.username,
+            img=g.gravatar(u.get_pref('email_address'), size=64),
+            name=u.display_name,
+            localization=u.get_pref('localization')._deinstrument())
 
 
 class UserProfileRestController(AppRestControllerMixin):
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 040336d..e35b5f8 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -4056,3 +4056,33 @@ Nav bar styles moved out of navbar.css since they are more stylistic than layout
 .unlocked-container{
     margin-top: 10px;
 }
+
+.user-card {
+  width: 280px;
+}
+
+.user-card .card-left {
+  float: left;
+  width: 70px;
+}
+
+.user-card .card-right {
+  float: right;
+  width: 210px;
+  padding-left: 4px;
+  box-sizing: border-box;
+}
+
+.user-card .card-left img{
+  width: 64px;
+  height: 64px;
+}
+
+.user-card .card-right .name{
+  font-size: 14px;
+  font-weight: bold;
+}
+
+.user-card .card-right .location{
+  font-size: 12px;
+}
diff --git a/Allura/allura/public/nf/js/allura-base.js b/Allura/allura/public/nf/js/allura-base.js
index 6e5f876..428b00e 100644
--- a/Allura/allura/public/nf/js/allura-base.js
+++ b/Allura/allura/public/nf/js/allura-base.js
@@ -262,3 +262,63 @@ $(function(){
         });
     });
 });
+
+// User card for mentions
+
+var umProfileStore = {}; // caching profile data
+
+var displayUserCard = function(instance, data) {
+    var toolBody = '';
+    var locationBody = '';
+
+    if(data.localization.city || data.localization.country) {
+        locationBody += '<span class="location"><i class="fa fa-map-marker"></i> ';
+        if(data.localization.city && data.localization.country) 
+            locationBody += data.localization.city + ', ' + data.localization.country;
+        else if(data.localization.city)
+            locationBody += data.localization.city;
+        else
+            locationBody += data.localization.country;
+        locationBody += '</span>';
+    }
+
+    toolBody = '<div class="user-card">' +
+                    '<div class="card-left">'+
+                        '<img src="' + data.img + '">' +
+                    '</div>' +
+                    '<div class="card-right">' +
+                        '<span class="name">' + data.name + '</span><br/>' +
+                        locationBody +
+                    '</div>' + 
+                '</div>';
+    $(instance).tooltipster('content', toolBody);
+}
+
+$(function(){
+    $(".user-mention").tooltipster({
+        animation: 'fade',
+        delay: 200,
+        theme: 'tooltipster-default',
+        trigger: 'hover',
+        position: 'top',
+        iconCloning: false,
+        maxWidth: 400,
+        contentAsHTML: true,
+        interactive: true,
+        content: 'test',
+        functionReady: function (instance, helper) {
+            var userUrl = $(this).attr('href');
+            
+            if(umProfileStore.hasOwnProperty(userUrl)){
+                displayUserCard(instance, umProfileStore[userUrl]);
+                // load from cache
+            }
+            else {
+                $.get(userUrl + 'profile/user_card', function(data) {
+                    displayUserCard(instance, data);
+                    umProfileStore[userUrl] = data;
+                });
+            }
+        }
+    });
+});
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index c3877de..d19ebd4 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -43,6 +43,21 @@ class TestUserProfile(TestController):
         assert_in('skills', sections)
         assert_in('No skills entered', r.html.find(None, 'skills').getText())
 
+    @td.with_user_project('test-admin')
+    def test_profile_user_card(self):
+        user = User.by_username('test-admin')
+        locals =  {
+            'city': 'test-city',
+            'country': 'US'
+        }
+        user.set_pref('localization', locals)
+        r = self.app.get('/u/test-admin/profile/user_card')
+        assert 'img' in r.json
+        assert user.display_name == r.json['name']
+        assert user.username == r.json['username']
+        assert user.get_pref('localization')['city'] == r.json['localization']['city']
+        assert user.get_pref('localization')['country'] == r.json['localization']['country']
+
     def test_wrong_profile(self):
         self.app.get('/u/no-such-user/profile/', status=404)