Commit 2c02d7ee6dd357c98c4517bbe0d8fb07667584bf
1 parent
a7d5f7a6
Exists in
master
and in
2 other branches
User status change propagation via notification
Showing
8 changed files
with
79 additions
and
6 deletions
Show diff stats
amadeus/static/js/socket.js
... | ... | @@ -21,6 +21,8 @@ socket.onmessage = function(e) { |
21 | 21 | } |
22 | 22 | } else if (content.type == "chat") { |
23 | 23 | messageReceived(content); |
24 | + } else if (content.type == "user_status") { | |
25 | + changeUserStatus(content); | |
24 | 26 | } |
25 | 27 | } |
26 | 28 | // Call onopen directly if socket is already open |
... | ... | @@ -297,4 +299,18 @@ function messageReceived(content) { |
297 | 299 | setTimeout(notification.close.bind(notification), 3000); |
298 | 300 | } |
299 | 301 | } |
302 | +} | |
303 | + | |
304 | +function changeUserStatus(content) { | |
305 | + var elem = $(".user_" + content.user_id + "_status"); | |
306 | + | |
307 | + elem.removeClass(content.remove_class); | |
308 | + | |
309 | + if (content.status_class == "") { | |
310 | + elem.removeClass('active'); | |
311 | + } else { | |
312 | + elem.addClass(content.status_class); | |
313 | + } | |
314 | + | |
315 | + elem.attr('data-original-title', content.status); | |
300 | 316 | } |
301 | 317 | \ No newline at end of file | ... | ... |
chat/templates/chat/_profile.html
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | <img src="{{ participant.image_url }}" /> |
15 | 15 | </span> |
16 | 16 | <h4> |
17 | - <a class="status {{ status }}" title="{{ status|status_text }}"></a> | |
17 | + <a class="user_{{ participant.id }}_status status {{ status }}" title="{{ status|status_text }}"></a> | |
18 | 18 | <b>{{ participant }}</b> |
19 | 19 | </h4> |
20 | 20 | <a href="#" onclick="getModalInfo($(this), '{{ space }}', '{{ space_type }}'); return false;" data-url='{% url "chat:talk" participant.email %}' class="btn btn-raised btn-success btn-block">{% trans 'Send Message' %}</a> | ... | ... |
chat/templates/chat/_view.html
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <img src="{{ talking_to.image_url }}" class="img-responsive" /> |
10 | 10 | </div> |
11 | 11 | <div class="col-md-6 user-info"> |
12 | - <h4 class='talking-header'><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ talking_to }} (<span class="chat_notify">{{ chat|notifies:request.user }}</span>)</h4> | |
12 | + <h4 class='talking-header'><a class="user_{{ talking_to.id }}_status status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ talking_to }} (<span class="chat_notify">{{ chat|notifies:request.user }}</span>)</h4> | |
13 | 13 | <p class="talk-last_msg">{% trans 'Last message in' %} {{ chat|last_message }}</p> |
14 | 14 | </div> |
15 | 15 | <div class="col-md-4 buttons pull-right text-center"> | ... | ... |
chat/templates/chat/_view_participant.html
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | <img src="{{ participant.image_url }}" class="img-responsive" /> |
8 | 8 | </div> |
9 | 9 | <div class="col-md-6 user-info"> |
10 | - <h4><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ participant }}</h4> | |
10 | + <h4><a class="user_{{ participant.id }}_status status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ participant }}</h4> | |
11 | 11 | </div> |
12 | 12 | <div class="col-md-4 buttons pull-right text-center"> |
13 | 13 | <a href="#" onclick="getModalInfo($(this), '{{ space }}', '{{ space_type }}'); return false;" data-url='{% url "chat:profile" participant.email %}' class="btn btn-raised btn-default">{% trans 'See Profile' %}</a> | ... | ... |
chat/templates/chat/talk.html
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | <img src="{{ participant.image_url }}" /> |
12 | 12 | </span> |
13 | 13 | <h4 class="pull-left" data-breadcrumb="{% trans 'Talk with ' %}{{ participant }}"> |
14 | - <a class="status {{ status }}" title="{{ status|status_text }}"></a> | |
14 | + <a class="user_{{ participant.id }}_status status {{ status }}" title="{{ status|status_text }}"></a> | |
15 | 15 | <b>{{ participant }}</b> |
16 | 16 | </h4> |
17 | 17 | </div> | ... | ... |
subjects/templates/subjects/view.html
... | ... | @@ -93,7 +93,7 @@ |
93 | 93 | |
94 | 94 | <div class="participants-container"> |
95 | 95 | <div class="col-md-12 sub-user" data-toggle="popover" data-container="body" data-placement="left"> |
96 | - <h4><a class="status {{ status }}" data-placement="right" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ participant }}</h4> | |
96 | + <h4><a class="user_{{ participant.id }}_status status {{ status }}" data-placement="right" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ participant }}</h4> | |
97 | 97 | </div> |
98 | 98 | |
99 | 99 | <div class="popover"> | ... | ... |
users/middleware.py
... | ... | @@ -9,6 +9,11 @@ from session_security.utils import get_last_activity, set_last_activity |
9 | 9 | |
10 | 10 | from log.models import Log |
11 | 11 | |
12 | +from .models import User | |
13 | +from django.utils.translation import ugettext as _u | |
14 | +from channels import Group | |
15 | +import json | |
16 | + | |
12 | 17 | class SessionExpireMiddleware(object): |
13 | 18 | |
14 | 19 | def process_request(self, request): |
... | ... | @@ -33,4 +38,19 @@ class SessionExpireMiddleware(object): |
33 | 38 | log.action = "logout" |
34 | 39 | log.resource = "system" |
35 | 40 | |
36 | - log.save() | |
37 | 41 | \ No newline at end of file |
42 | + log.save() | |
43 | + | |
44 | + users = User.objects.all().exclude(email = request.user.email) | |
45 | + | |
46 | + notification = { | |
47 | + "type": "user_status", | |
48 | + "user_id": str(request.user.id), | |
49 | + "status": _u("Offline"), | |
50 | + "status_class": "", | |
51 | + "remove_class": "away" | |
52 | + } | |
53 | + | |
54 | + notification = json.dumps(notification) | |
55 | + | |
56 | + for u in users: | |
57 | + Group("user-%s" % u.id).send({'text': notification}) | |
38 | 58 | \ No newline at end of file | ... | ... |
users/views.py
... | ... | @@ -5,6 +5,7 @@ from django.contrib.auth import authenticate, login as login_user, logout as log |
5 | 5 | from django.contrib.auth.mixins import LoginRequiredMixin |
6 | 6 | from django.core.urlresolvers import reverse, reverse_lazy |
7 | 7 | from django.utils.translation import ugettext_lazy as _ |
8 | +from django.utils.translation import ugettext as _u | |
8 | 9 | from django.db.models import Q, Count |
9 | 10 | |
10 | 11 | from braces import views as braces_mixins |
... | ... | @@ -19,6 +20,10 @@ from .models import User |
19 | 20 | from .utils import has_dependencies |
20 | 21 | from .forms import RegisterUserForm, ProfileForm, UserForm, ChangePassForm, PassResetRequest, SetPasswordForm |
21 | 22 | |
23 | +#USER STATUS NOTIFICATION | |
24 | +from channels import Group | |
25 | +import json | |
26 | + | |
22 | 27 | #RECOVER PASS IMPORTS |
23 | 28 | from django.contrib.auth.tokens import default_token_generator |
24 | 29 | from django.core.mail import send_mail |
... | ... | @@ -501,6 +506,21 @@ def login(request): |
501 | 506 | if not security.maintence or user.is_staff: |
502 | 507 | login_user(request, user) |
503 | 508 | |
509 | + users = User.objects.all().exclude(email = username) | |
510 | + | |
511 | + notification = { | |
512 | + "type": "user_status", | |
513 | + "user_id": str(user.id), | |
514 | + "status": _u("Online"), | |
515 | + "status_class": "active", | |
516 | + "remove_class": "away" | |
517 | + } | |
518 | + | |
519 | + notification = json.dumps(notification) | |
520 | + | |
521 | + for u in users: | |
522 | + Group("user-%s" % u.id).send({'text': notification}) | |
523 | + | |
504 | 524 | next_url = request.GET.get('next', None) |
505 | 525 | |
506 | 526 | if next_url: |
... | ... | @@ -519,8 +539,25 @@ def login(request): |
519 | 539 | |
520 | 540 | @log_decorator('user', 'logout', 'system') |
521 | 541 | def logout(request, next_page = None): |
542 | + user = request.user | |
543 | + | |
522 | 544 | logout_user(request) |
523 | 545 | |
546 | + users = User.objects.all().exclude(email = user.email) | |
547 | + | |
548 | + notification = { | |
549 | + "type": "user_status", | |
550 | + "user_id": str(user.id), | |
551 | + "status": _u("Offline"), | |
552 | + "status_class": "", | |
553 | + "remove_class": "away" | |
554 | + } | |
555 | + | |
556 | + notification = json.dumps(notification) | |
557 | + | |
558 | + for u in users: | |
559 | + Group("user-%s" % u.id).send({'text': notification}) | |
560 | + | |
524 | 561 | if next_page: |
525 | 562 | return redirect(next_page) |
526 | 563 | ... | ... |