Commit 006b4402f3d2aac21ac5426cd255eec9e5cb69a7

Authored by Zambom
1 parent fe932798

Adding user info popover in mural

amadeus/static/js/mural.js
... ... @@ -24,9 +24,47 @@ $(function () {
24 24 });
25 25  
26 26 postHeightLimits();
  27 + setUserDataPopover();
27 28  
28 29 });
29 30  
  31 +function setUserDataPopover() {
  32 + $('[data-toggle="popover"]').popover({
  33 + html: true,
  34 + content: function () {
  35 + return $(this).parent().find(".popover").html();
  36 + }
  37 + }).on('show.bs.popover', function (e) {
  38 + $('[data-toggle="popover"]').not(e.target).popover('hide');
  39 + }).on('shown.bs.popover', function (e) {
  40 + if($(this).is(e.target)){
  41 + var popover = $(".popover.fade.in"),
  42 + buttons = popover.parent().find('a'),
  43 + close = popover.parent().find('.close:visible');
  44 +
  45 + popover.animate({
  46 + 'max-width': '330px',
  47 + }, 0);
  48 +
  49 + popover.find('.popover-content').animate({
  50 + padding: '9px 5px',
  51 + }, 0);
  52 +
  53 + popover.find('h4').animate({
  54 + 'font-size': '16px',
  55 + }, 0);
  56 +
  57 + close.on("click", function () {
  58 + popover.popover('hide');
  59 + });
  60 +
  61 + buttons.on("click", function () {
  62 + popover.popover('hide');
  63 + })
  64 + }
  65 + });
  66 +}
  67 +
30 68 function postHeightLimits() {
31 69 $('.post-body').each(function () {
32 70 if ($(this).outerHeight() > 500) {
... ... @@ -77,6 +115,7 @@ function setPostFormSubmit(post = "") {
77 115 $('.no-subjects:visible').attr('style', 'display:none');
78 116 }
79 117  
  118 + setUserDataPopover();
80 119 setTimeout(function () { postHeightLimits() }, 100);
81 120  
82 121 $('#post-modal-form').modal('hide');
... ... @@ -325,6 +364,8 @@ function loadComments (btn) {
325 364 btn.show();
326 365  
327 366 btn.after(response.loaded);
  367 +
  368 + setUserDataPopover();
328 369 }
329 370 });
330 371 }
... ...
amadeus/static/js/mural_ungeneral.js
... ... @@ -35,7 +35,8 @@ $('.mural-ungeneral').on('shown.bs.collapse', function(e) {
35 35 mural.data('pages', data.num_pages);
36 36 mural.data('page', data.num_page);
37 37  
38   - setTimeout(function () { postHeightLimits() }, 100);
  38 + setUserDataPopover();
  39 + setTimeout(function () { postHeightLimits(); }, 100);
39 40  
40 41 if (data.num_page < data.num_pages) {
41 42 more.show();
... ... @@ -112,7 +113,8 @@ $(&#39;.mural-ungeneral&#39;).on(&#39;shown.bs.collapse&#39;, function(e) {
112 113 mural.data('pages', data.num_pages);
113 114 mural.data('page', data.num_page);
114 115  
115   - setTimeout(function () { postHeightLimits() }, 100);
  116 + setUserDataPopover();
  117 + setTimeout(function () { postHeightLimits(); }, 100);
116 118  
117 119 if (data.num_page < data.num_pages) {
118 120 more.show();
... ... @@ -168,7 +170,8 @@ $(&#39;.mural-ungeneral&#39;).on(&#39;shown.bs.collapse&#39;, function(e) {
168 170 more.hide();
169 171 }
170 172  
171   - setTimeout(function () { postHeightLimits() }, 100);
  173 + setUserDataPopover();
  174 + setTimeout(function () { postHeightLimits(); }, 100);
172 175  
173 176 without.hide();
174 177 } else {
... ...
chat/migrations/0003_auto_20170407_2154.py 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-04-08 00:54
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('chat', '0002_auto_20170402_2207'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='talkmessages',
  17 + name='text',
  18 + field=models.TextField(blank=True, verbose_name='Message'),
  19 + ),
  20 + ]
... ...
mural/templates/mural/_view.html
... ... @@ -7,7 +7,37 @@
7 7 </div>
8 8 <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 post-body">
9 9 <h4 class="post-user">
10   - {{ post.user }}
  10 + {% if not post.user == request.user %}
  11 + {% is_online post.user as status %}
  12 +
  13 + <span data-toggle="popover" data-placement="right">{{ post.user }}</span>
  14 +
  15 + <div class="popover">
  16 + <div class="popover-content participant">
  17 + <button type="button" class="close" aria-label="{% trans 'Close' %}"><span aria-hidden="true">&times;</span></button>
  18 +
  19 + <br clear="all" />
  20 +
  21 + <div class="col-md-3 col-sm-3 user-img">
  22 + <img src="{{ post.user.image_url }}" class="img-responsive" />
  23 + </div>
  24 + <div class="col-md-9 col-sm-9 user-info">
  25 + <h4><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ post.user }}</h4>
  26 + </div>
  27 + </div>
  28 + <div class="popover-footer">
  29 + <a href="#" onclick="getModalInfo($(this), '{{ post|chat_space }}', '{{ post|chat_space_type }}'); return false;" data-url='{% url "chat:profile" post.user.email %}' class="btn btn-default btn-sm btn-raised pull-left">
  30 + {% trans 'See Profile' %}
  31 + </a>
  32 + <a href="#" onclick="getModalInfo($(this), '{{ post|chat_space }}', '{{ post|chat_space_type }}'); return false;" data-url='{% url "chat:talk" post.user.email %}' class="btn btn-success btn-sm btn-raised pull-right">
  33 + {% trans 'Send Message' %}
  34 + </a>
  35 + </div>
  36 + </div>
  37 + {% else %}
  38 + {{ post.user }}
  39 + {% endif %}
  40 +
11 41 <span class="user-action">
12 42 <i class="fa {{ post.action|action_icon }}"></i>
13 43 {{ post.get_action_display }}
... ... @@ -63,4 +93,4 @@
63 93 </div>
64 94 </div>
65 95 </div>
66 96 -</div>
  97 +</div>
67 98 \ No newline at end of file
... ...
mural/templates/mural/_view_comment.html
... ... @@ -8,7 +8,37 @@
8 8 </div>
9 9 <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 comment-body">
10 10 <h4 class="comment-user">
11   - {{ comment.user }}
  11 + {% if not post.user == request.user %}
  12 + {% is_online comment.user as status %}
  13 +
  14 + <span data-toggle="popover" data-container="body" data-placement="right">{{ comment.user }}</span>
  15 +
  16 + <div class="popover">
  17 + <div class="popover-content participant">
  18 + <button type="button" class="close" aria-label="{% trans 'Close' %}"><span aria-hidden="true">&times;</span></button>
  19 +
  20 + <br clear="all" />
  21 +
  22 + <div class="col-md-3 col-sm-3 user-img">
  23 + <img src="{{ comment.user.image_url }}" class="img-responsive" />
  24 + </div>
  25 + <div class="col-md-9 col-sm-9 user-info">
  26 + <h4><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ comment.user }}</h4>
  27 + </div>
  28 + </div>
  29 + <div class="popover-footer">
  30 + <a href="#" onclick="getModalInfo($(this), '{{ comment.post|chat_space }}', '{{ comment.post|chat_space_type }}'); return false;" data-url='{% url "chat:profile" comment.user.email %}' class="btn btn-default btn-sm btn-raised pull-left">
  31 + {% trans 'See Profile' %}
  32 + </a>
  33 + <a href="#" onclick="getModalInfo($(this), '{{ comment.post|chat_space }}', '{{ comment.post|chat_space_type }}'); return false;" data-url='{% url "chat:talk" comment.user.email %}' class="btn btn-success btn-sm btn-raised pull-right">
  34 + {% trans 'Send Message' %}
  35 + </a>
  36 + </div>
  37 + </div>
  38 + {% else %}
  39 + {{ comment.user }}
  40 + {% endif %}
  41 +
12 42 <span class="user-action">
13 43 <i class="fa fa-commenting-o"></i>
14 44 {% trans 'Comment' context "view" %}
... ...
mural/templates/mural/list.html
... ... @@ -91,7 +91,13 @@
91 91 </div>
92 92  
93 93 <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  94 +
  95 + <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  96 +
  97 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  98 +
94 99  
  100 + <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
95 101 <script type="text/javascript" src="{% static 'js/mural.js' %}"></script>
96 102 <script type="text/javascript" src="{% static 'js/mural_general.js' %}"></script>
97 103 {% endblock %}
98 104 \ No newline at end of file
... ...
mural/templates/mural/list_category.html
... ... @@ -155,7 +155,12 @@
155 155  
156 156 <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
157 157  
  158 + <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  159 +
  160 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  161 +
158 162 <script type="text/javascript" src="{% static 'js/category.js' %}"></script>
  163 + <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
159 164 <script type="text/javascript" src="{% static 'js/mural.js' %}"></script>
160 165 <script type="text/javascript" src="{% static 'js/mural_ungeneral.js' %}"></script>
161 166 {% endblock %}
162 167 \ No newline at end of file
... ...
mural/templates/mural/list_subject.html
... ... @@ -154,7 +154,13 @@
154 154  
155 155 <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
156 156  
  157 + <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  158 +
  159 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  160 +
  161 +
157 162 <script type="text/javascript" src="{% static 'js/category.js' %}"></script>
  163 + <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
158 164 <script type="text/javascript" src="{% static 'js/mural.js' %}"></script>
159 165 <script type="text/javascript" src="{% static 'js/mural_ungeneral.js' %}"></script>
160 166 <script type="text/javascript" src="{% static 'subjects/js/modal_subject.js' %}"></script>
... ...
mural/templatetags/mural_filters.py
1 1 from django import template
  2 +from django.conf import settings
  3 +from django.utils import timezone
2 4 from django.db.models import Q
3 5 from django.utils.translation import ugettext_lazy as _
  6 +from django.contrib.sessions.models import Session
  7 +
  8 +from log.models import Log
4 9  
5 10 from mural.models import MuralFavorites, MuralVisualizations
6 11  
... ... @@ -105,4 +110,45 @@ def has_resource(post):
105 110 if post.subjectpost.resource:
106 111 return _("about") + " <span class='post_resource'>" + str(post.subjectpost.resource) + "</span>"
107 112  
108   - return ""
109 113 \ No newline at end of file
  114 + return ""
  115 +
  116 +@register.assignment_tag(name = 'is_online')
  117 +def is_online(user):
  118 + expire_time = settings.SESSION_SECURITY_EXPIRE_AFTER
  119 + now = timezone.now()
  120 +
  121 + activities = Log.objects.filter(user_id = user.id).order_by('-datetime')
  122 +
  123 + if activities.count() > 0:
  124 + last_activity = activities[0]
  125 +
  126 + if last_activity.action != 'logout':
  127 + if (now - last_activity.datetime).total_seconds() < expire_time:
  128 + return "active"
  129 + else:
  130 + return "away"
  131 +
  132 + return ""
  133 +
  134 +@register.filter(name = 'status_text')
  135 +def status_text(status):
  136 + if status == "active":
  137 + return _("Online")
  138 + elif status == "away":
  139 + return _('Away')
  140 + else:
  141 + return _("Offline")
  142 +
  143 +@register.filter(name = 'chat_space')
  144 +def chat_space(post):
  145 + if post._my_subclass == "subjectpost":
  146 + return post.subjectpost.space.id
  147 +
  148 + return 0
  149 +
  150 +@register.filter(name = 'chat_space_type')
  151 +def chat_space_type(post):
  152 + if post._my_subclass == "subjectpost":
  153 + return "subject"
  154 +
  155 + return "general"
110 156 \ No newline at end of file
... ...
news/migrations/0001_initial.py 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-04-08 00:54
  3 +from __future__ import unicode_literals
  4 +
  5 +import autoslug.fields
  6 +from django.conf import settings
  7 +from django.db import migrations, models
  8 +import django.db.models.deletion
  9 +import news.models
  10 +
  11 +
  12 +class Migration(migrations.Migration):
  13 +
  14 + initial = True
  15 +
  16 + dependencies = [
  17 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  18 + ]
  19 +
  20 + operations = [
  21 + migrations.CreateModel(
  22 + name='News',
  23 + fields=[
  24 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  25 + ('title', models.CharField(max_length=200, unique=True, verbose_name='Name')),
  26 + ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='title', unique=True, verbose_name='Slug')),
  27 + ('image', models.ImageField(upload_to='news/', validators=[news.models.validate_img_extension], verbose_name='News Image')),
  28 + ('content', models.TextField(verbose_name='News Content')),
  29 + ('create_date', models.DateTimeField(auto_now_add=True, verbose_name='Create Date')),
  30 + ('creator', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='news_creator_user', to=settings.AUTH_USER_MODEL, verbose_name='Creator')),
  31 + ],
  32 + options={
  33 + 'verbose_name_plural': 'News',
  34 + 'verbose_name': 'News',
  35 + },
  36 + ),
  37 + ]
... ...