Commit 2d1f0f41ae6500044f02777a930b5476e3a135b0

Authored by felipebormann
2 parents 7de669b4 b70b98ec

Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring

amadeus/static/css/base/amadeus.css
@@ -1026,7 +1026,7 @@ li.item .notify_badge { @@ -1026,7 +1026,7 @@ li.item .notify_badge {
1026 margin: 0; 1026 margin: 0;
1027 } 1027 }
1028 1028
1029 -.post .post-user .btn-group .dropdown-menu a { 1029 +.post .post-user .btn-group .dropdown-menu a, .comment .comment-user .btn-group .dropdown-menu a {
1030 cursor: pointer; 1030 cursor: pointer;
1031 } 1031 }
1032 1032
amadeus/static/js/mural.js 0 → 100644
@@ -0,0 +1,357 @@ @@ -0,0 +1,357 @@
  1 +var new_posts = [];
  2 +var new_comments = {};
  3 +// loadOnScroll handler
  4 +var loadOnScroll = function() {
  5 + // If the current scroll position is past out cutoff point...
  6 + if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
  7 + // temporarily unhook the scroll event watcher so we don't call a bunch of times in a row
  8 + $(window).unbind();
  9 + // execute the load function below that will visit the view and return the content
  10 + loadPosts();
  11 + }
  12 +};
  13 +
  14 +var loadPosts = function() {
  15 + var loadUrl = $('.mural').data('url'),
  16 + pageNum = $('.mural').data('page'),
  17 + numberPages = $('.mural').data('pages'),
  18 + favorites = $('.mural').data('fav'),
  19 + mine = $('.mural').data('mine'),
  20 + showing = new_posts.join(',');
  21 + // Check if page is equal to the number of pages
  22 + if (pageNum == numberPages) {
  23 + return false
  24 + }
  25 + // Update the page number
  26 + pageNum = pageNum + 1;
  27 +
  28 + $("#loading_posts").show();
  29 + // Configure the url we're about to hit
  30 + setTimeout(function (){
  31 + $.ajax({
  32 + url: loadUrl,
  33 + data: {'page': pageNum, "favorite": favorites, "mine": mine, "showing": showing},
  34 + success: function(data) {
  35 + $("#loading_posts").hide();
  36 +
  37 + $(".posts").append(data);
  38 +
  39 + $('.mural').data('page', pageNum);
  40 + },
  41 + complete: function(data, textStatus){
  42 + // Turn the scroll monitor back on
  43 + $(window).bind('scroll', loadOnScroll);
  44 + }
  45 + });
  46 + }, 1000)
  47 +};
  48 +
  49 +$(function () {
  50 + $(window).bind('scroll', loadOnScroll);
  51 +
  52 + $(".post-field").click(function () {
  53 + var url = $(this).find('h4').data('url');
  54 +
  55 + $.ajax({
  56 + url: url,
  57 + success: function (data) {
  58 + $('#post-modal-form').html(data);
  59 +
  60 + setPostFormSubmit();
  61 +
  62 + $('#post-modal-form').modal('show');
  63 + }
  64 + });
  65 + });
  66 +
  67 + $("#clear_filter").click(function () {
  68 + var frm = $(this).parent();
  69 +
  70 + frm.find("input[type='checkbox']").prop('checked', false);
  71 +
  72 + frm.submit();
  73 + });
  74 +
  75 + $(".comment-section").each(function () {
  76 + var height = $(this)[0].scrollHeight;
  77 +
  78 + $(this).animate({scrollTop: height}, 0);
  79 + });
  80 +});
  81 +
  82 +function setPostFormSubmit(post = "") {
  83 + var frm = $('#post-form');
  84 +
  85 + frm.submit(function () {
  86 + var formData = new FormData($(this)[0]);
  87 +
  88 + $.ajax({
  89 + type: frm.attr('method'),
  90 + url: frm.attr('action'),
  91 + data: formData,
  92 + dataType: "json",
  93 + async: false,
  94 + success: function (data) {
  95 + if (post != "") {
  96 + var old = $("#post-" + post);
  97 +
  98 + old.before(data.view);
  99 +
  100 + old.remove();
  101 + } else {
  102 + $('.posts').prepend(data.view);
  103 +
  104 + new_posts.push(data.new_id);
  105 +
  106 + $('.no-subjects').attr('style', 'display:none');
  107 + }
  108 +
  109 + $('#post-modal-form').modal('hide');
  110 +
  111 + alertify.success(data.message);
  112 + },
  113 + error: function(data) {
  114 + $("#post-modal-form").html(data.responseText);
  115 + setPostFormSubmit(post);
  116 + },
  117 + cache: false,
  118 + contentType: false,
  119 + processData: false
  120 + });
  121 +
  122 + return false;
  123 + });
  124 +}
  125 +
  126 +function favorite(btn) {
  127 + var action = btn.data('action'),
  128 + url = btn.data('url');
  129 +
  130 + $.ajax({
  131 + url: url,
  132 + data: {'action': action},
  133 + dataType: 'json',
  134 + success: function (response) {
  135 + if (action == 'favorite') {
  136 + btn.switchClass("btn_fav", "btn_unfav", 250, "easeInOutQuad");
  137 + btn.data('action', 'unfavorite');
  138 + } else {
  139 + btn.switchClass("btn_unfav", "btn_fav", 250, "easeInOutQuad");
  140 + btn.data('action', 'favorite');
  141 + }
  142 +
  143 + btn.attr('data-original-title', response.label);
  144 + }
  145 + });
  146 +}
  147 +
  148 +function editPost(btn) {
  149 + var url = btn.data('url');
  150 + var post = btn.data('post');
  151 +
  152 + $.ajax({
  153 + url: url,
  154 + success: function (data) {
  155 + $('#post-modal-form').html(data);
  156 +
  157 + setPostFormSubmit(post);
  158 +
  159 + $('#post-modal-form').modal('show');
  160 + }
  161 + });
  162 +}
  163 +
  164 +function deletePost(btn) {
  165 + var url = btn.data('url');
  166 + var post = btn.data('post');
  167 +
  168 + $.ajax({
  169 + url: url,
  170 + success: function (data) {
  171 + $('#post-modal-form').html(data);
  172 +
  173 + setPostDeleteSubmit(post);
  174 +
  175 + $('#post-modal-form').modal('show');
  176 + }
  177 + });
  178 +}
  179 +
  180 +function setPostDeleteSubmit (post) {
  181 + var frm = $("#delete_form");
  182 +
  183 + frm.submit(function () {
  184 + $.ajax({
  185 + type: frm.attr('method'),
  186 + url: frm.attr('action'),
  187 + data: frm.serialize(),
  188 + success: function (response) {
  189 + $("#post-" + post).remove();
  190 +
  191 + $('#post-modal-form').modal('hide');
  192 +
  193 + alertify.success(response.msg);
  194 + },
  195 + error: function (data) {
  196 + console.log(data);
  197 + }
  198 + });
  199 +
  200 + return false;
  201 + });
  202 +}
  203 +
  204 +function comment(field) {
  205 + var url = field.find('h4').data('url'),
  206 + post = field.find('h4').data('post');
  207 +
  208 + $.ajax({
  209 + url: url,
  210 + success: function (data) {
  211 + $('#post-modal-form').html(data);
  212 +
  213 + setCommentFormSubmit(post);
  214 +
  215 + $('#post-modal-form').modal('show');
  216 + }
  217 + });
  218 +}
  219 +
  220 +function editComment(btn) {
  221 + var url = btn.data('url'),
  222 + post = btn.data('post'),
  223 + comment = btn.data('id');
  224 +
  225 + $.ajax({
  226 + url: url,
  227 + success: function (data) {
  228 + $('#post-modal-form').html(data);
  229 +
  230 + setCommentFormSubmit(post, comment);
  231 +
  232 + $('#post-modal-form').modal('show');
  233 + }
  234 + });
  235 +}
  236 +
  237 +function setCommentFormSubmit(post, comment = "") {
  238 + var frm = $('#comment-form');
  239 +
  240 + frm.submit(function () {
  241 + var formData = new FormData($(this)[0]);
  242 +
  243 + $.ajax({
  244 + type: frm.attr('method'),
  245 + url: frm.attr('action'),
  246 + data: formData,
  247 + dataType: "json",
  248 + async: false,
  249 + success: function (data) {
  250 + if (comment != "") {
  251 + var old = $("#comment-" + comment);
  252 +
  253 + old.before(data.view);
  254 +
  255 + old.remove();
  256 + } else {
  257 + $("#post-" + post).find(".comment-section").append(data.view);
  258 +
  259 + if (typeof(new_comments[post]) == 'undefined') {
  260 + new_comments[post] = [];
  261 + }
  262 +
  263 + new_comments[post].push(data.new_id);
  264 + }
  265 +
  266 + $('#post-modal-form').modal('hide');
  267 +
  268 + alertify.success(data.message);
  269 + },
  270 + error: function(data) {
  271 + $("#post-modal-form").html(data.responseText);
  272 + setPostFormSubmit(post, comment);
  273 + },
  274 + cache: false,
  275 + contentType: false,
  276 + processData: false
  277 + });
  278 +
  279 + return false;
  280 + });
  281 +}
  282 +
  283 +function deleteComment(btn) {
  284 + var url = btn.data('url');
  285 + var comment = btn.data('id');
  286 +
  287 + console.log(comment);
  288 +
  289 + $.ajax({
  290 + url: url,
  291 + success: function (data) {
  292 + $('#post-modal-form').html(data);
  293 +
  294 + setCommentDeleteSubmit(comment);
  295 +
  296 + $('#post-modal-form').modal('show');
  297 + }
  298 + });
  299 +}
  300 +
  301 +function setCommentDeleteSubmit (comment) {
  302 + var frm = $("#delete_form");
  303 +
  304 + frm.submit(function () {
  305 + $.ajax({
  306 + type: frm.attr('method'),
  307 + url: frm.attr('action'),
  308 + data: frm.serialize(),
  309 + success: function (response) {
  310 +
  311 + $("#comment-" + comment).remove();
  312 +
  313 + $('#post-modal-form').modal('hide');
  314 +
  315 + alertify.success(response.msg);
  316 + },
  317 + error: function (data) {
  318 + console.log(data);
  319 + }
  320 + });
  321 +
  322 + return false;
  323 + });
  324 +}
  325 +
  326 +function loadComments (btn) {
  327 + var url = btn.data('url'),
  328 + post = btn.data('post'),
  329 + page = btn.parent().data('page'),
  330 + loading = btn.parent().find('.loading');
  331 +
  332 + page = parseInt(page);
  333 + page = page + 1;
  334 +
  335 + loading.show();
  336 + btn.hide();
  337 +
  338 + var showing;
  339 +
  340 + if (typeof(new_comments[post]) == 'undefined') {
  341 + showing = "";
  342 + } else {
  343 + showing = new_comments[post].join(',');
  344 + }
  345 +
  346 + $.ajax({
  347 + url: url,
  348 + data: {'page': page, 'showing': showing},
  349 + dataType: 'json',
  350 + success: function (response) {
  351 + loading.hide();
  352 + btn.show();
  353 +
  354 + btn.after(response.loaded);
  355 + }
  356 + });
  357 +}
0 \ No newline at end of file 358 \ No newline at end of file
mural/migrations/0007_comment_edited.py 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2017-02-09 21:47
  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 + ('mural', '0006_auto_20170209_1434'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AddField(
  16 + model_name='comment',
  17 + name='edited',
  18 + field=models.BooleanField(default=False, verbose_name='Edited'),
  19 + ),
  20 + ]
mural/models.py
@@ -69,6 +69,7 @@ class Comment(models.Model): @@ -69,6 +69,7 @@ class Comment(models.Model):
69 user = models.ForeignKey(User, verbose_name = _('User'), related_name = "comment_user", null = True) 69 user = models.ForeignKey(User, verbose_name = _('User'), related_name = "comment_user", null = True)
70 create_date = models.DateTimeField(_('Create Date'), auto_now_add = True) 70 create_date = models.DateTimeField(_('Create Date'), auto_now_add = True)
71 last_update = models.DateTimeField(_('Last Update'), auto_now = True) 71 last_update = models.DateTimeField(_('Last Update'), auto_now = True)
  72 + edited = models.BooleanField(_('Edited'), default = False)
72 73
73 """ 74 """
74 Model to handle posts visualizations 75 Model to handle posts visualizations
mural/templates/mural/_form_comment.html
@@ -73,16 +73,10 @@ @@ -73,16 +73,10 @@
73 <div id="add-user-modal" style="display:none"> 73 <div id="add-user-modal" style="display:none">
74 <div class="modal-dialog" role="document"> 74 <div class="modal-dialog" role="document">
75 <div class="modal-content"> 75 <div class="modal-content">
76 - <div class="modal-header">  
77 - <h3>{% trans 'Mark user in comment' %}</h3>  
78 - </div>  
79 <div class="modal-body"> 76 <div class="modal-body">
80 - <p>{% trans 'Type the user name in the field below' %}</p>  
81 <div class="form-group"> 77 <div class="form-group">
82 - <input type="text" class="form-control" id="adduser_field" oninput="typing_search($(this));" />  
83 - <div class="suggestions list-group" data-url="{% url 'mural:suggest_users' %}" style="display:none">  
84 -  
85 - </div> 78 + <input type="text" class="form-control" id="adduser_field" oninput="typing_search($(this));" placeholder="{% trans 'Insert here the name of the user you wish to mark in this comment' %}" />
  79 + <div class="suggestions list-group" data-url="{% url 'mural:suggest_users' %}" style="display:none"></div>
86 </div> 80 </div>
87 </div> 81 </div>
88 <div class="modal-footer"> 82 <div class="modal-footer">
mural/templates/mural/_list_view_comment.html 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +{% for comment in comments reversed %}
  2 + {% include 'mural/_view_comment.html' %}
  3 +{% endfor %}
  4 +
  5 +<script type="text/javascript">
  6 + $(function () {
  7 + var section = $("#post-{{ post_id }}").find('.comment-section'),
  8 + pageNumber = "{{ page_obj.number }}",
  9 + totalPages = "{{ paginator.num_pages }}";
  10 +
  11 + section.data('page', pageNumber);
  12 + section.data('pages', totalPages);
  13 +
  14 + if (pageNumber == totalPages) {
  15 + section.find('.load-btn').hide();
  16 + }
  17 + });
  18 +</script>
0 \ No newline at end of file 19 \ No newline at end of file
mural/templates/mural/_user_suggestions_list.html
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 </a> 12 </a>
13 {% endfor %} 13 {% endfor %}
14 {% else %} 14 {% else %}
15 - <a href="#" class="list-group-item suggested-user"> 15 + <a class="list-group-item suggested-user">
16 <h4 class="text-center">{% trans 'No results found.' %}</h4> 16 <h4 class="text-center">{% trans 'No results found.' %}</h4>
17 </a> 17 </a>
18 {% endif %} 18 {% endif %}
19 \ No newline at end of file 19 \ No newline at end of file
mural/templates/mural/_view.html
1 -{% load i18n mural_filters %} 1 +{% load i18n mural_filters comments_list %}
2 2
3 <div id="post-{{ post.id }}" class="panel panel-default"> 3 <div id="post-{{ post.id }}" class="panel panel-default">
4 <div class="panel-body post"> 4 <div class="panel-body post">
@@ -44,9 +44,9 @@ @@ -44,9 +44,9 @@
44 {% endif %} 44 {% endif %}
45 </div> 45 </div>
46 <div class="col-md-12 comment-section"> 46 <div class="col-md-12 comment-section">
47 - {% for comment in post.comment_post.all %}  
48 - {% include 'mural/_view_comment.html' %}  
49 - {% endfor %} 47 + <button type="button" class="btn btn-block btn-default btn-sm loading" style="display:none"><span class="fa fa-spin fa-circle-o-notch"></span></button>
  48 + <button type="button" onclick="loadComments($(this))" data-url="{% url 'mural:load_comments' post.mural_ptr_id post.id %}" data-post="{{ post.id }}" class="btn btn-block btn-default btn-sm load-btn">{% trans 'See more comments...' %}</button>
  49 + {% comments_list request post %}
50 </div> 50 </div>
51 <div class="col-md-12 post-comment"> 51 <div class="col-md-12 post-comment">
52 <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 user-img"> 52 <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 user-img">
@@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
56 </div> 56 </div>
57 <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 comment-field" onclick="comment($(this))"> 57 <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 comment-field" onclick="comment($(this))">
58 <div> 58 <div>
59 - <h4 data-url="{% url 'mural:create_comment' post.mural_ptr_id %}">{% trans 'Make a comment...' %}</h4> 59 + <h4 data-url="{% url 'mural:create_comment' post.mural_ptr_id %}" data-post="{{ post.id }}">{% trans 'Make a comment...' %}</h4>
60 </div> 60 </div>
61 </div> 61 </div>
62 </div> 62 </div>
mural/templates/mural/_view_comment.html
1 -{% load i18n %} 1 +{% load i18n mural_filters %}
2 2
3 <div id="comment-{{ comment.id }}" class="row comment"> 3 <div id="comment-{{ comment.id }}" class="row comment">
4 <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 comment-img"> 4 <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 comment-img">
@@ -19,16 +19,16 @@ @@ -19,16 +19,16 @@
19 <i class="fa fa-ellipsis-v" aria-hidden="true"></i> 19 <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
20 </button> 20 </button>
21 <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> 21 <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
22 - <li><a onclick="editPost($(this));"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans 'Edit' %}</a></li> 22 + <li><a onclick="editComment($(this));" data-url="{% url 'mural:update_comment' comment.id %}" data-id="{{ comment.id }}" data-post="{{ comment.post.id }}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans 'Edit' %}</a></li>
23 <li> 23 <li>
24 - <a onclick="deletePost($(this))" aria-hidden="true"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans 'Remove' %}</a></li> 24 + <a onclick="deleteComment($(this))" data-url="{% url 'mural:delete_comment' comment.id %}" data-id="{{ comment.id }}" aria-hidden="true"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans 'Remove' %}</a></li>
25 </ul> 25 </ul>
26 </span> 26 </span>
27 {% endif %} 27 {% endif %}
28 </h4> 28 </h4>
29 <p class="comment-time"> 29 <p class="comment-time">
30 <i class="fa fa-clock-o"></i> 30 <i class="fa fa-clock-o"></i>
31 - {% trans 'In' %} {{ comment.last_update }} 31 + {% trans 'In' %} {{ comment.last_update }} {{ comment|is_edited }}
32 </p> 32 </p>
33 33
34 {% autoescape off %} 34 {% autoescape off %}
mural/templates/mural/delete.html
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class="modal-body"> 5 <div class="modal-body">
6 <form id="delete_form" action="{{ form_url }}" method="post"> 6 <form id="delete_form" action="{{ form_url }}" method="post">
7 {% csrf_token %} 7 {% csrf_token %}
8 - <h4>{% trans 'Are you sure you want to delete this post' %}?</h4> 8 + <h4>{{ message }}</h4>
9 </form> 9 </form>
10 </div> 10 </div>
11 <div class="modal-footer"> 11 <div class="modal-footer">
mural/templates/mural/list.html
@@ -72,259 +72,5 @@ @@ -72,259 +72,5 @@
72 72
73 <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div> 73 <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
74 74
75 - <script type="text/javascript">  
76 - var new_posts = [];  
77 - // loadOnScroll handler  
78 - var loadOnScroll = function() {  
79 - // If the current scroll position is past out cutoff point...  
80 - if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {  
81 - // temporarily unhook the scroll event watcher so we don't call a bunch of times in a row  
82 - $(window).unbind();  
83 - // execute the load function below that will visit the view and return the content  
84 - loadPosts();  
85 - }  
86 - };  
87 -  
88 - var loadPosts = function() {  
89 - var loadUrl = $('.mural').data('url'),  
90 - pageNum = $('.mural').data('page'),  
91 - numberPages = $('.mural').data('pages'),  
92 - favorites = $('.mural').data('fav'),  
93 - mine = $('.mural').data('mine'),  
94 - showing = new_posts.join(',');  
95 - // Check if page is equal to the number of pages  
96 - if (pageNum == numberPages) {  
97 - return false  
98 - }  
99 - // Update the page number  
100 - pageNum = pageNum + 1;  
101 -  
102 - $("#loading_posts").show();  
103 - // Configure the url we're about to hit  
104 - setTimeout(function (){  
105 - $.ajax({  
106 - url: loadUrl,  
107 - data: {'page': pageNum, "favorite": favorites, "mine": mine, "showing": showing},  
108 - success: function(data) {  
109 - $("#loading_posts").hide();  
110 -  
111 - $(".posts").append(data);  
112 -  
113 - $('.mural').data('page', pageNum);  
114 - },  
115 - complete: function(data, textStatus){  
116 - // Turn the scroll monitor back on  
117 - $(window).bind('scroll', loadOnScroll);  
118 - }  
119 - });  
120 - }, 1000)  
121 - };  
122 -  
123 - $(function () {  
124 - $(window).bind('scroll', loadOnScroll);  
125 -  
126 - $(".post-field").click(function () {  
127 - var url = $(this).find('h4').data('url');  
128 -  
129 - $.ajax({  
130 - url: url,  
131 - success: function (data) {  
132 - $('#post-modal-form').html(data);  
133 -  
134 - setPostFormSubmit();  
135 -  
136 - $('#post-modal-form').modal('show');  
137 - }  
138 - });  
139 - });  
140 -  
141 - $("#clear_filter").click(function () {  
142 - var frm = $(this).parent();  
143 -  
144 - frm.find("input[type='checkbox']").prop('checked', false);  
145 -  
146 - frm.submit();  
147 - });  
148 - });  
149 -  
150 - function setPostFormSubmit(post = "") {  
151 - var frm = $('#post-form');  
152 -  
153 - frm.submit(function () {  
154 - var formData = new FormData($(this)[0]);  
155 -  
156 - $.ajax({  
157 - type: frm.attr('method'),  
158 - url: frm.attr('action'),  
159 - data: formData,  
160 - dataType: "json",  
161 - async: false,  
162 - success: function (data) {  
163 - if (post != "") {  
164 - var old = $("#post-" + post);  
165 -  
166 - old.before(data.view);  
167 -  
168 - old.remove();  
169 - } else {  
170 - $('.posts').prepend(data.view);  
171 -  
172 - new_posts.push(data.new_id);  
173 -  
174 - $('.no-subjects').attr('style', 'display:none');  
175 - }  
176 -  
177 - $('#post-modal-form').modal('hide');  
178 -  
179 - alertify.success(data.message);  
180 - },  
181 - error: function(data) {  
182 - $("#post-modal-form").html(data.responseText);  
183 - setPostFormSubmit(post);  
184 - },  
185 - cache: false,  
186 - contentType: false,  
187 - processData: false  
188 - });  
189 -  
190 - return false;  
191 - });  
192 - }  
193 -  
194 - function favorite(btn) {  
195 - var action = btn.data('action'),  
196 - url = btn.data('url');  
197 -  
198 - $.ajax({  
199 - url: url,  
200 - data: {'action': action},  
201 - dataType: 'json',  
202 - success: function (response) {  
203 - if (action == 'favorite') {  
204 - btn.switchClass("btn_fav", "btn_unfav", 250, "easeInOutQuad");  
205 - btn.data('action', 'unfavorite');  
206 - } else {  
207 - btn.switchClass("btn_unfav", "btn_fav", 250, "easeInOutQuad");  
208 - btn.data('action', 'favorite');  
209 - }  
210 -  
211 - btn.attr('data-original-title', response.label);  
212 - }  
213 - });  
214 - }  
215 -  
216 - function editPost(btn) {  
217 - var url = btn.data('url');  
218 - var post = btn.data('post');  
219 -  
220 - $.ajax({  
221 - url: url,  
222 - success: function (data) {  
223 - $('#post-modal-form').html(data);  
224 -  
225 - setPostFormSubmit(post);  
226 -  
227 - $('#post-modal-form').modal('show');  
228 - }  
229 - });  
230 - }  
231 -  
232 - function deletePost(btn) {  
233 - var url = btn.data('url');  
234 - var post = btn.data('post');  
235 -  
236 - $.ajax({  
237 - url: url,  
238 - success: function (data) {  
239 - $('#post-modal-form').html(data);  
240 -  
241 - setPostDeleteSubmit(post);  
242 -  
243 - $('#post-modal-form').modal('show');  
244 - }  
245 - });  
246 - }  
247 -  
248 - function setPostDeleteSubmit (post) {  
249 - var frm = $("#delete_form");  
250 -  
251 - frm.submit(function () {  
252 - $.ajax({  
253 - type: frm.attr('method'),  
254 - url: frm.attr('action'),  
255 - data: frm.serialize(),  
256 - success: function (response) {  
257 - $("#post-" + post).remove();  
258 -  
259 - $('#post-modal-form').modal('hide');  
260 -  
261 - alertify.success(response.msg);  
262 - },  
263 - error: function (data) {  
264 - console.log(data);  
265 - }  
266 - });  
267 -  
268 - return false;  
269 - });  
270 - }  
271 -  
272 - function comment(field) {  
273 - var url = field.find('h4').data('url'),  
274 - post = field.parent().parent();  
275 -  
276 - $.ajax({  
277 - url: url,  
278 - success: function (data) {  
279 - $('#post-modal-form').html(data);  
280 -  
281 - setCommentFormSubmit(post);  
282 -  
283 - $('#post-modal-form').modal('show');  
284 - }  
285 - });  
286 - }  
287 -  
288 - function setCommentFormSubmit(post, comment = "") {  
289 - var frm = $('#comment-form');  
290 -  
291 - frm.submit(function () {  
292 - var formData = new FormData($(this)[0]);  
293 -  
294 - $.ajax({  
295 - type: frm.attr('method'),  
296 - url: frm.attr('action'),  
297 - data: formData,  
298 - dataType: "json",  
299 - async: false,  
300 - success: function (data) {  
301 - /*if (post != "") {  
302 - var old = $("#post-" + post);  
303 -  
304 - old.before(data.view);  
305 -  
306 - old.remove();  
307 - } else {*/  
308 - $(post).find(".comment-section").append(data.view);  
309 -  
310 - //new_posts.push(data.new_id);  
311 - //}  
312 -  
313 - $('#post-modal-form').modal('hide');  
314 -  
315 - alertify.success(data.message);  
316 - },  
317 - error: function(data) {  
318 - $("#post-modal-form").html(data.responseText);  
319 - setPostFormSubmit(post, comment);  
320 - },  
321 - cache: false,  
322 - contentType: false,  
323 - processData: false  
324 - });  
325 -  
326 - return false;  
327 - });  
328 - }  
329 - </script> 75 + <script type="text/javascript" src="{% static 'js/mural.js' %}"></script>
330 {% endblock %} 76 {% endblock %}
331 \ No newline at end of file 77 \ No newline at end of file
mural/templatetags/comments_list.py 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +from django import template
  2 +
  3 +from django.core.paginator import Paginator, EmptyPage
  4 +from django.http import Http404
  5 +
  6 +from mural.models import Comment
  7 +
  8 +register = template.Library()
  9 +
  10 +@register.inclusion_tag('mural/_list_view_comment.html')
  11 +def comments_list(request, post):
  12 + context = {
  13 + 'request': request,
  14 + }
  15 +
  16 + comments = Comment.objects.filter(post = post).order_by('-last_update')
  17 +
  18 + paginator = Paginator(comments, 5)
  19 +
  20 + try:
  21 + page_number = 1
  22 + except ValueError:
  23 + raise Http404
  24 +
  25 + try:
  26 + page_obj = paginator.page(page_number)
  27 + except EmptyPage:
  28 + raise Http404
  29 +
  30 + context['paginator'] = paginator
  31 + context['page_obj'] = page_obj
  32 +
  33 + context['comments'] = page_obj.object_list
  34 + context['post_id'] = post.id
  35 +
  36 + return context
0 \ No newline at end of file 37 \ No newline at end of file
@@ -9,7 +9,11 @@ urlpatterns = [ @@ -9,7 +9,11 @@ urlpatterns = [
9 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'), 9 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'),
10 url(r'^deleted/$', views.deleted_post, name='deleted_post'), 10 url(r'^deleted/$', views.deleted_post, name='deleted_post'),
11 url(r'^comment/(?P<post>[\w_-]+)/$', views.CommentCreate.as_view(), name='create_comment'), 11 url(r'^comment/(?P<post>[\w_-]+)/$', views.CommentCreate.as_view(), name='create_comment'),
  12 + url(r'^update_comment/(?P<pk>[\w_-]+)/$', views.CommentUpdate.as_view(), name='update_comment'),
  13 + url(r'^delete_comment/(?P<pk>[\w_-]+)/$', views.CommentDelete.as_view(), name='delete_comment'),
  14 + url(r'^deleted_comment/$', views.deleted_comment, name='deleted_comment'),
12 url(r'^render_comment/([\w_-]+)/([\w_-]+)/$', views.render_comment, name='render_comment'), 15 url(r'^render_comment/([\w_-]+)/([\w_-]+)/$', views.render_comment, name='render_comment'),
13 url(r'^render_post/([\w_-]+)/([\w_-]+)/$', views.render_gen_post, name='render_post_general'), 16 url(r'^render_post/([\w_-]+)/([\w_-]+)/$', views.render_gen_post, name='render_post_general'),
  17 + url(r'^load_comments/([\w_-]+)/([\w_-]+)/$', views.load_comments, name='load_comments'),
14 url(r'^suggest_users/$', views.suggest_users, name='suggest_users'), 18 url(r'^suggest_users/$', views.suggest_users, name='suggest_users'),
15 ] 19 ]
16 \ No newline at end of file 20 \ No newline at end of file
mural/views.py
1 from django.shortcuts import get_object_or_404, redirect, render 1 from django.shortcuts import get_object_or_404, redirect, render
  2 +from django.core.paginator import Paginator, EmptyPage
  3 +from django.http import Http404
2 from django.views import generic 4 from django.views import generic
3 from django.contrib import messages 5 from django.contrib import messages
4 from django.http import JsonResponse 6 from django.http import JsonResponse
@@ -186,6 +188,7 @@ class GeneralDelete(LoginRequiredMixin, generic.DeleteView): @@ -186,6 +188,7 @@ class GeneralDelete(LoginRequiredMixin, generic.DeleteView):
186 context = super(GeneralDelete, self).get_context_data(*args, **kwargs) 188 context = super(GeneralDelete, self).get_context_data(*args, **kwargs)
187 189
188 context['form_url'] = reverse_lazy("mural:delete_general", args = (), kwargs = {'pk': self.object.id}) 190 context['form_url'] = reverse_lazy("mural:delete_general", args = (), kwargs = {'pk': self.object.id})
  191 + context['message'] = _('Are you sure you want to delete this post?')
189 192
190 return context 193 return context
191 194
@@ -259,7 +262,6 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView): @@ -259,7 +262,6 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView):
259 self.object.save() 262 self.object.save()
260 263
261 users = User.objects.all().exclude(id = self.request.user.id) 264 users = User.objects.all().exclude(id = self.request.user.id)
262 - entries = []  
263 265
264 notify_type = "mural" 266 notify_type = "mural"
265 user_icon = self.object.user.image_url 267 user_icon = self.object.user.image_url
@@ -271,8 +273,6 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView): @@ -271,8 +273,6 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView):
271 # entries.append(MuralVisualizations(viewed = False, user = user, post = self.object)) 273 # entries.append(MuralVisualizations(viewed = False, user = user, post = self.object))
272 # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "create", "user_icon": user_icon, "pathname": pathname, "simple": simple_notify, "complete": _view})}) 274 # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "create", "user_icon": user_icon, "pathname": pathname, "simple": simple_notify, "complete": _view})})
273 275
274 - #MuralVisualizations.objects.bulk_create(entries)  
275 -  
276 return super(CommentCreate, self).form_valid(form) 276 return super(CommentCreate, self).form_valid(form)
277 277
278 def get_context_data(self, *args, **kwargs): 278 def get_context_data(self, *args, **kwargs):
@@ -287,6 +287,80 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView): @@ -287,6 +287,80 @@ class CommentCreate(LoginRequiredMixin, generic.edit.CreateView):
287 def get_success_url(self): 287 def get_success_url(self):
288 return reverse_lazy('mural:render_comment', args = (self.object.id, 'create', )) 288 return reverse_lazy('mural:render_comment', args = (self.object.id, 'create', ))
289 289
  290 +class CommentUpdate(LoginRequiredMixin, generic.UpdateView):
  291 + login_url = reverse_lazy("users:login")
  292 + redirect_field_name = 'next'
  293 +
  294 + template_name = 'mural/_form_comment.html'
  295 + model = Comment
  296 + form_class = CommentForm
  297 +
  298 + def form_invalid(self, form):
  299 + context = super(CommentUpdate, self).form_invalid(form)
  300 + context.status_code = 400
  301 +
  302 + return context
  303 +
  304 + def form_valid(self, form):
  305 + self.object = form.save(commit = False)
  306 +
  307 + self.object.edited = True
  308 +
  309 + self.object.save()
  310 +
  311 + users = User.objects.all().exclude(id = self.request.user.id)
  312 + entries = []
  313 +
  314 + notify_type = "mural"
  315 + user_icon = self.object.user.image_url
  316 + #_view = render_to_string("mural/_view.html", {"post": self.object}, self.request)
  317 + simple_notify = _("%s has made a post in General")%(str(self.object.user))
  318 + pathname = reverse("mural:manage_general")
  319 +
  320 + #for user in users:
  321 + # entries.append(MuralVisualizations(viewed = False, user = user, post = self.object))
  322 + # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "create", "user_icon": user_icon, "pathname": pathname, "simple": simple_notify, "complete": _view})})
  323 +
  324 + #MuralVisualizations.objects.bulk_create(entries)
  325 +
  326 + return super(CommentUpdate, self).form_valid(form)
  327 +
  328 + def get_context_data(self, *args, **kwargs):
  329 + context = super(CommentUpdate, self).get_context_data(*args, **kwargs)
  330 +
  331 + context['form_url'] = reverse_lazy("mural:update_comment", args = (), kwargs = {'pk': self.object.id})
  332 +
  333 + return context
  334 +
  335 + def get_success_url(self):
  336 + return reverse_lazy('mural:render_comment', args = (self.object.id, 'update', ))
  337 +
  338 +class CommentDelete(LoginRequiredMixin, generic.DeleteView):
  339 + login_url = reverse_lazy("users:login")
  340 + redirect_field_name = 'next'
  341 +
  342 + template_name = 'mural/delete.html'
  343 + model = Comment
  344 +
  345 + def get_context_data(self, *args, **kwargs):
  346 + context = super(CommentDelete, self).get_context_data(*args, **kwargs)
  347 +
  348 + context['form_url'] = reverse_lazy("mural:delete_comment", args = (), kwargs = {'pk': self.object.id})
  349 + context['message'] = _('Are you sure you want to delete this comment?')
  350 +
  351 + return context
  352 +
  353 + def get_success_url(self):
  354 + users = User.objects.all().exclude(id = self.request.user.id)
  355 +
  356 + notify_type = "mural"
  357 + pathname = reverse("mural:manage_general")
  358 +
  359 + #for user in users:
  360 + # Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "delete", "pathname": pathname, "post_id": self.object.id})})
  361 +
  362 + return reverse_lazy('mural:deleted_comment')
  363 +
290 def render_comment(request, comment, msg): 364 def render_comment(request, comment, msg):
291 comment = get_object_or_404(Comment, id = comment) 365 comment = get_object_or_404(Comment, id = comment)
292 366
@@ -304,6 +378,9 @@ def render_comment(request, comment, msg): @@ -304,6 +378,9 @@ def render_comment(request, comment, msg):
304 378
305 return JsonResponse({'message': msg, 'view': html, 'new_id': comment.id}) 379 return JsonResponse({'message': msg, 'view': html, 'new_id': comment.id})
306 380
  381 +def deleted_comment(request):
  382 + return JsonResponse({'msg': _('Comment deleted successfully!')})
  383 +
307 def suggest_users(request): 384 def suggest_users(request):
308 param = request.GET.get('param', '') 385 param = request.GET.get('param', '')
309 386
@@ -314,4 +391,39 @@ def suggest_users(request): @@ -314,4 +391,39 @@ def suggest_users(request):
314 391
315 response = render_to_string("mural/_user_suggestions_list.html", context, request) 392 response = render_to_string("mural/_user_suggestions_list.html", context, request)
316 393
317 - return JsonResponse({"search_result": response})  
318 \ No newline at end of file 394 \ No newline at end of file
  395 + return JsonResponse({"search_result": response})
  396 +
  397 +def load_comments(request, post, child_id):
  398 + context = {
  399 + 'request': request,
  400 + }
  401 +
  402 + showing = request.GET.get('showing', '')
  403 +
  404 + if showing == '':
  405 + comments = Comment.objects.filter(post__id = post).order_by('-last_update')
  406 + else:
  407 + showing = showing.split(',')
  408 + comments = Comment.objects.filter(post__id = post).exclude(id__in = showing).order_by('-last_update')
  409 +
  410 + paginator = Paginator(comments, 5)
  411 +
  412 + try:
  413 + page_number = int(request.GET.get('page', 1))
  414 + except ValueError:
  415 + raise Http404
  416 +
  417 + try:
  418 + page_obj = paginator.page(page_number)
  419 + except EmptyPage:
  420 + raise Http404
  421 +
  422 + context['paginator'] = paginator
  423 + context['page_obj'] = page_obj
  424 +
  425 + context['comments'] = page_obj.object_list
  426 + context['post_id'] = child_id
  427 +
  428 + response = render_to_string("mural/_list_view_comment.html", context, request)
  429 +
  430 + return JsonResponse({"loaded": response})
319 \ No newline at end of file 431 \ No newline at end of file