Commit c426f2edf5440a3c7bc746bfc702d3c8451632df

Authored by Zambom
1 parent fe7ba245

Adding mural post comment creation (Adjusts to be made)

amadeus/static/css/base/amadeus.css
... ... @@ -1009,16 +1009,17 @@ li.item .notify_badge {
1009 1009  
1010 1010 .post .post-body {
1011 1011 padding-right: 0;
  1012 + margin-bottom: 10px;
1012 1013 }
1013 1014  
1014   -.post .post-user {
  1015 +.post .post-user, .comment .comment-user {
1015 1016 margin-top: 0;
1016 1017 margin-bottom: 5px;
1017 1018 font-size: 18px;
1018 1019 font-weight: 700;
1019 1020 }
1020 1021  
1021   -.post .post-user .btn-group {
  1022 +.post .post-user .btn-group, .comment .comment-user .btn-group {
1022 1023 margin: 0;
1023 1024 }
1024 1025  
... ... @@ -1030,28 +1031,27 @@ li.item .notify_badge {
1030 1031 font-size: 18px;
1031 1032 }
1032 1033  
1033   -.post .post-user .user-action {
  1034 +.post .post-user .user-action, .comment .comment-user .user-action {
1034 1035 padding-left: 5px;
1035 1036 font-size: 16px;
1036 1037 font-weight: normal;
1037 1038 }
1038 1039  
1039   -.post .post-user .user-action i {
  1040 +.post .post-user .user-action i, .comment .comment-user .user-action i {
1040 1041 font-size: 22px;
1041 1042 }
1042 1043  
1043   -.post .time {
  1044 +.post .time, .comment-time {
1044 1045 font-size: 14px;
1045 1046 }
1046 1047  
1047 1048 .post .post-comment {
1048   - margin-top: 10px;
1049 1049 border-top-width: 1px;
1050 1050 border-top-style: solid;
1051 1051 padding: 10px 0px 8px 0px;
1052 1052 }
1053 1053  
1054   -.post .post-comment .user-img div {
  1054 +.post .post-comment .user-img div, .comment .comment-img div {
1055 1055 display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
1056 1056 display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
1057 1057 display: -ms-flexbox; /* TWEENER - IE 10 */
... ... @@ -1084,6 +1084,19 @@ li.item .notify_badge {
1084 1084 margin-bottom: 15px;
1085 1085 }
1086 1086  
  1087 +.comment-section {
  1088 + max-height: 700px;
  1089 + overflow-y: scroll;
  1090 +}
  1091 +
  1092 +.comment {
  1093 + padding: 10px 0px 8px 0px;
  1094 +}
  1095 +
  1096 +.comment .comment-user .btn-group .btn_menu i {
  1097 + font-size: 15px;
  1098 +}
  1099 +
1087 1100 .btn:focus, .btn:active:focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn.active.focus {
1088 1101 outline: none;
1089 1102 }
1090 1103 \ No newline at end of file
... ...
amadeus/static/css/themes/green.css
... ... @@ -496,7 +496,7 @@ a.add-row {
496 496 background: #FFFFFF;
497 497 }
498 498  
499   -.mural .post_make .user-img, .post .post-img, .post .post-comment .user-img div {
  499 +.mural .post_make .user-img, .post .post-img, .post .post-comment .user-img div, .comment .comment-img div {
500 500 background: #CCCCCC;
501 501 }
502 502  
... ... @@ -508,11 +508,11 @@ a.add-row {
508 508 color: #CCCCCC;
509 509 }
510 510  
511   -.post_action i, .post .post-user .user-action i {
  511 +.post_action i, .post .post-user .user-action i, .comment .comment-user .user-action i {
512 512 color: #1d8fe0;
513 513 }
514 514  
515   -.post .post-user {
  515 +.post .post-user, .comment .comment-user {
516 516 color: #4caf50;
517 517 }
518 518  
... ... @@ -534,6 +534,18 @@ a.add-row {
534 534 background: #FFFFFF;
535 535 }
536 536  
  537 +.comment-section {
  538 + background: #D5D5D5;
  539 +}
  540 +
  541 +.comment .comment-user .user-action {
  542 + color: #999999;
  543 +}
  544 +
  545 +.comment-time {
  546 + color: #9A9A9A;
  547 +}
  548 +
537 549 .btn_unfav {
538 550 color: #FF0000 !important;
539 551 }
... ...
mural/forms.py
... ... @@ -3,7 +3,7 @@ from django import forms
3 3 from django.utils.translation import ugettext_lazy as _
4 4 from django.utils.html import strip_tags
5 5  
6   -from .models import GeneralPost
  6 +from .models import GeneralPost, Comment
7 7  
8 8 class Validation(forms.ModelForm):
9 9 MAX_UPLOAD_SIZE = 5*1024*1024
... ... @@ -38,4 +38,34 @@ class GeneralPostForm(Validation):
38 38 widgets = {
39 39 'action': forms.RadioSelect,
40 40 'post': forms.Textarea
41   - }
42 41 \ No newline at end of file
  42 + }
  43 +
  44 +class CommentForm(forms.ModelForm):
  45 + MAX_UPLOAD_SIZE = 5*1024*1024
  46 +
  47 + def clean_comment(self):
  48 + comment = self.cleaned_data.get('comment', '')
  49 + cleaned_comment = strip_tags(comment)
  50 +
  51 + if cleaned_comment == '':
  52 + self._errors['comment'] = [_('This field is required.')]
  53 +
  54 + return ValueError
  55 +
  56 + return comment
  57 +
  58 + def clean_image(self):
  59 + image = self.cleaned_data.get('image', False)
  60 +
  61 + if image:
  62 + if hasattr(image, '_size'):
  63 + if image._size > self.MAX_UPLOAD_SIZE:
  64 + self._errors['image'] = [_("The image is too large. It should have less than 5MB.")]
  65 +
  66 + return ValueError
  67 +
  68 + return image
  69 +
  70 + class Meta:
  71 + model = Comment
  72 + fields = ['comment', 'image']
43 73 \ No newline at end of file
... ...
mural/models.py
... ... @@ -65,7 +65,7 @@ class SubjectPost(Mural):
65 65 class Comment(models.Model):
66 66 comment = models.TextField(_('Comment'), blank = True)
67 67 image = models.ImageField(verbose_name = _('Image'), null=True, blank = True, upload_to = 'posts/comments/', validators = [validate_img_extension])
68   - post = models.ForeignKey(Mural, verbose_name = _('Post'), related_name = 'comment_post')
  68 + post = models.ForeignKey(Mural, verbose_name = _('Post'), related_name = 'comment_post', null = True)
69 69 user = models.ForeignKey(User, verbose_name = _('User'), related_name = "comment_user", null = True)
70 70 create_date = models.DateTimeField(_('Create Date'), auto_now_add = True)
71 71 last_update = models.DateTimeField(_('Last Update'), auto_now = True)
... ...
mural/templates/mural/_form_comment.html 0 → 100644
... ... @@ -0,0 +1,121 @@
  1 +{% load static i18n %}
  2 +{% load widget_tweaks %}
  3 +
  4 +<div class="modal-dialog" role="document">
  5 + <div class="modal-content">
  6 + <div class="modal-body">
  7 + <form id="comment-form" method="post" action="{{ form_url }}" enctype="multipart/form-data">
  8 + {% csrf_token %}
  9 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  10 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }} <span>*</span></label>
  11 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  12 +
  13 + <span id="helpBlock" class="help-block">{{ form.post.help_text }}</span>
  14 +
  15 + {% if form.comment.errors %}
  16 + <div class="alert alert-danger alert-dismissible" role="alert">
  17 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  18 + <span aria-hidden="true">&times;</span>
  19 + </button>
  20 + <ul>
  21 + {% for error in form.comment.errors %}
  22 + <li>{{ error }}</li>
  23 + {% endfor %}
  24 + </ul>
  25 + </div>
  26 + {% endif %}
  27 + </div>
  28 +
  29 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  30 + {% render_field form.image %}
  31 +
  32 + <div class="input-group common-file-input">
  33 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">
  34 + <span class="input-group-btn input-group-sm">
  35 + <button type="button" class="btn btn-fab btn-fab-mini">
  36 + <i class="material-icons">attach_file</i>
  37 + </button>
  38 + </span>
  39 + </div>
  40 +
  41 + <div class="filedrag">
  42 + {% trans 'Click or drop the file here' %}<br />
  43 +
  44 + <small>{% trans 'The file could not exceed 5MB.' %}</small>
  45 + </div>
  46 +
  47 + <span id="helpBlock" class="help-block">{{ form.image.help_text }}</span>
  48 +
  49 + {% if form.image.errors %}
  50 + <div class="alert alert-danger alert-dismissible" role="alert">
  51 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  52 + <span aria-hidden="true">&times;</span>
  53 + </button>
  54 + <ul>
  55 + {% for error in form.image.errors %}
  56 + <li>{{ error }}</li>
  57 + {% endfor %}
  58 + </ul>
  59 + </div>
  60 + {% endif %}
  61 + </div>
  62 + </form>
  63 + </div>
  64 + <div class="modal-footer">
  65 + <div class="col-md-12">
  66 + <button type="submit" id="button" form="comment-form" class="btn btn-success btn-raised post-button pull-left">{% trans "Save" %}</button>
  67 + <button type="button" class="btn btn-raised btn-default pull-right" data-dismiss="modal">{% trans "Cancel" %}</button>
  68 + </div>
  69 + </div>
  70 + </div>
  71 +</div>
  72 +
  73 +<script type="text/javascript">
  74 + $(function () {
  75 + $('.text_simple_wysiwyg').summernote({
  76 + dialogsInBody: true,
  77 + height: 150,
  78 + toolbar: [
  79 + // [groupName, [list of button]]
  80 + ['style', ['bold', 'italic']],
  81 + ['insert', ['link']]
  82 + ]
  83 + });
  84 +
  85 + $.material.init();
  86 +
  87 + if (window.File && window.FileList && window.FileReader) {
  88 + Init();
  89 + }
  90 + });
  91 +
  92 + // initialize
  93 + function Init() {
  94 + var small = $("#id_image"),
  95 + filedrag = $(".filedrag"),
  96 + common = $(".common-file-input");
  97 +
  98 + // file select
  99 + small.on("change", FileSelectHandler);
  100 +
  101 + // is XHR2 available?
  102 + var xhr = new XMLHttpRequest();
  103 + if (xhr.upload) {
  104 + // file drop
  105 + filedrag.on("drop", FileSelectHandler);
  106 + filedrag.attr('style', 'display:block');
  107 + common.attr('style', 'display:none');
  108 + }
  109 + }
  110 +
  111 + // file selection
  112 + function FileSelectHandler(e) {
  113 + var files = e.target.files || e.dataTransfer.files,
  114 + parent = $(e.target.offsetParent);
  115 +
  116 + // process all File objects
  117 + for (var i = 0, f; f = files[i]; i++) {
  118 + parent.find('.filedrag').html(f.name);
  119 + }
  120 + }
  121 +</script>
... ...
mural/templates/mural/_view.html
... ... @@ -43,15 +43,20 @@
43 43 <img src="{{ post.image.url }}" class="img-responsive center-block" />
44 44 {% endif %}
45 45 </div>
  46 + <div class="col-md-12 comment-section">
  47 + {% for comment in post.comment_post.all %}
  48 + {% include 'mural/_view_comment.html' %}
  49 + {% endfor %}
  50 + </div>
46 51 <div class="col-md-12 post-comment">
47 52 <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 user-img">
48 53 <div>
49 54 <img src="{{ request.user.image_url }}" class="img-responsive" />
50 55 </div>
51 56 </div>
52   - <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 comment-field">
  57 + <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 comment-field" onclick="comment($(this))">
53 58 <div>
54   - <h4 data-url="{% url 'mural:create_general' %}">{% trans 'Make a comment...' %}</h4>
  59 + <h4 data-url="{% url 'mural:create_comment' post.mural_ptr_id %}">{% trans 'Make a comment...' %}</h4>
55 60 </div>
56 61 </div>
57 62 </div>
... ...
mural/templates/mural/_view_comment.html 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +{% load i18n %}
  2 +
  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">
  5 + <div>
  6 + <img src="{{ comment.user.image_url }}" class="img-responsive" />
  7 + </div>
  8 + </div>
  9 + <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 comment-body">
  10 + <h4 class="comment-user">
  11 + {{ comment.user }}
  12 + <span class="user-action">
  13 + <i class="fa fa-comments-o"></i>
  14 + {% trans 'Comment' %}
  15 + </span>
  16 + {% if request.user == comment.user or request.user.is_staff %}
  17 + <span class="btn-group pull-right">
  18 + <button class="btn btn-sm btn_menu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  19 + <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
  20 + </button>
  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>
  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>
  25 + </ul>
  26 + </span>
  27 + {% endif %}
  28 + </h4>
  29 + <p class="comment-time">
  30 + <i class="fa fa-clock-o"></i>
  31 + {% trans 'In' %} {{ comment.last_update }}
  32 + </p>
  33 +
  34 + {% autoescape off %}
  35 + {{ comment.comment }}
  36 + {% endautoescape %}
  37 +
  38 + {% if comment.image %}
  39 + <img src="{{ comment.image.url }}" class="img-responsive center-block" />
  40 + {% endif %}
  41 + </div>
  42 +</div>
0 43 \ No newline at end of file
... ...
mural/templates/mural/list.html
... ... @@ -268,5 +268,63 @@
268 268 return false;
269 269 });
270 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 + }
271 329 </script>
272 330 {% endblock %}
273 331 \ No newline at end of file
... ...
mural/urls.py
... ... @@ -6,7 +6,9 @@ urlpatterns = [
6 6 url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'),
7 7 url(r'^update_gen/(?P<pk>[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'),
8 8 url(r'^delete_gen/(?P<pk>[\w_-]+)/$', views.GeneralDelete.as_view(), name='delete_general'),
9   - url(r'^render_post/([\w_-]+)/([\w_-]+)/$', views.render_gen_post, name='render_post_general'),
10 9 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'),
11 10 url(r'^deleted/$', views.deleted_post, name='deleted_post'),
  11 + url(r'^comment/(?P<post>[\w_-]+)/$', views.CommentCreate.as_view(), name='create_comment'),
  12 + 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'),
12 14 ]
13 15 \ No newline at end of file
... ...
mural/views.py
... ... @@ -14,8 +14,8 @@ import json
14 14  
15 15 from users.models import User
16 16  
17   -from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites
18   -from .forms import GeneralPostForm
  17 +from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment
  18 +from .forms import GeneralPostForm, CommentForm
19 19  
20 20 class GeneralIndex(LoginRequiredMixin, generic.ListView):
21 21 login_url = reverse_lazy("users:login")
... ... @@ -232,4 +232,74 @@ def favorite(request, post):
232 232 else:
233 233 MuralFavorites.objects.filter(post = post, user = request.user).delete()
234 234  
235   - return JsonResponse({'label': _('Favorite')})
236 235 \ No newline at end of file
  236 + return JsonResponse({'label': _('Favorite')})
  237 +
  238 +class CommentCreate(LoginRequiredMixin, generic.edit.CreateView):
  239 + login_url = reverse_lazy("users:login")
  240 + redirect_field_name = 'next'
  241 +
  242 + template_name = 'mural/_form_comment.html'
  243 + form_class = CommentForm
  244 +
  245 + def form_invalid(self, form):
  246 + context = super(CommentCreate, self).form_invalid(form)
  247 + context.status_code = 400
  248 +
  249 + return context
  250 +
  251 + def form_valid(self, form):
  252 + self.object = form.save(commit = False)
  253 +
  254 + post_id = self.kwargs.get('post', '')
  255 + post = get_object_or_404(Mural, id = post_id)
  256 +
  257 + self.object.user = self.request.user
  258 + self.object.post = post
  259 +
  260 + self.object.save()
  261 +
  262 + users = User.objects.all().exclude(id = self.request.user.id)
  263 + entries = []
  264 +
  265 + notify_type = "mural"
  266 + user_icon = self.object.user.image_url
  267 + #_view = render_to_string("mural/_view.html", {"post": self.object}, self.request)
  268 + simple_notify = _("%s has made a post in General")%(str(self.object.user))
  269 + pathname = reverse("mural:manage_general")
  270 +
  271 + #for user in users:
  272 + # entries.append(MuralVisualizations(viewed = False, user = user, post = self.object))
  273 + # 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 +
  275 + #MuralVisualizations.objects.bulk_create(entries)
  276 +
  277 + return super(CommentCreate, self).form_valid(form)
  278 +
  279 + def get_context_data(self, *args, **kwargs):
  280 + context = super(CommentCreate, self).get_context_data(*args, **kwargs)
  281 +
  282 + post_id = self.kwargs.get('post', '')
  283 +
  284 + context['form_url'] = reverse_lazy("mural:create_comment", kwargs = {"post": post_id})
  285 +
  286 + return context
  287 +
  288 + def get_success_url(self):
  289 + return reverse_lazy('mural:render_comment', args = (self.object.id, 'create', ))
  290 +
  291 +def render_comment(request, comment, msg):
  292 + comment = get_object_or_404(Comment, id = comment)
  293 +
  294 + context = {}
  295 + context['comment'] = comment
  296 +
  297 + msg = ""
  298 +
  299 + if msg == 'create':
  300 + msg = _('Your comment was published successfully!')
  301 + else:
  302 + msg = _('Your comment was edited successfully!')
  303 +
  304 + html = render_to_string("mural/_view_comment.html", context, request)
  305 +
  306 + return JsonResponse({'message': msg, 'view': html, 'new_id': comment.id})
237 307 \ No newline at end of file
... ...