From e32bcf4c332e08954da68fbfd0e5817b2f646215 Mon Sep 17 00:00:00 2001 From: Zambom Date: Tue, 14 Mar 2017 23:23:16 -0300 Subject: [PATCH] Adding general chat message sent (Adjusts to be made) --- amadeus/static/js/chat.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- chat/forms.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ chat/models.py | 8 ++++---- chat/templates/chat/_form.html | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chat/templates/chat/_message.html | 6 ++++++ chat/templates/chat/_profile.html | 2 +- chat/templates/chat/_view_participant.html | 4 ++-- chat/templates/chat/list_participants.html | 4 +++- chat/templates/chat/talk.html | 9 ++++++--- chat/urls.py | 2 ++ chat/views.py | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 11 files changed, 334 insertions(+), 23 deletions(-) create mode 100644 chat/forms.py create mode 100644 chat/templates/chat/_form.html create mode 100644 chat/templates/chat/_message.html diff --git a/amadeus/static/js/chat.js b/amadeus/static/js/chat.js index d141b36..98b86de 100644 --- a/amadeus/static/js/chat.js +++ b/amadeus/static/js/chat.js @@ -1,10 +1,10 @@ -function getModalInfo(btn, space) { +function getModalInfo(btn, space, space_type) { var url = btn.data('url'); $.ajax({ method: 'get', url: url, - data: {'space': space}, + data: {'space': space, 'space_type': space_type}, success: function (response) { $("#chat-modal-info").html(response); @@ -13,4 +13,51 @@ function getModalInfo(btn, space) { $.material.init(); } }); +} + +function getForm(field) { + var url = field.find('h4').data('url'); + + $.ajax({ + url: url, + success: function (data) { + $('#chat-modal-form').html(data); + + setChatFormSubmit(); + + $('#chat-modal-form').modal('show'); + } + }); +} + +function setChatFormSubmit() { + var frm = $('#chat-form'); + + frm.submit(function () { + var formData = new FormData($(this)[0]); + + $.ajax({ + type: frm.attr('method'), + url: frm.attr('action'), + data: formData, + dataType: "json", + async: false, + success: function (data) { + $('.messages-container').append(data.view); + + $('#chat-modal-form').modal('hide'); + + alertify.success(data.message); + }, + error: function(data) { + $("#chat-modal-form").html(data.responseText); + setChatFormSubmit(); + }, + cache: false, + contentType: false, + processData: false + }); + + return false; + }); } \ No newline at end of file diff --git a/chat/forms.py b/chat/forms.py new file mode 100644 index 0000000..d25a524 --- /dev/null +++ b/chat/forms.py @@ -0,0 +1,44 @@ +# coding=utf-8 +from django import forms +from django.utils.translation import ugettext_lazy as _ +from django.utils.html import strip_tags +from django.db.models import Q + +from resubmit.widgets import ResubmitFileWidget + +from .models import TalkMessages + +class Validation(forms.ModelForm): + MAX_UPLOAD_SIZE = 5*1024*1024 + + def clean_text(self): + text = self.cleaned_data.get('text', '') + cleaned_text = strip_tags(text) + + if cleaned_text == '': + self._errors['text'] = [_('This field is required.')] + + return ValueError + + return text + + def clean_image(self): + image = self.cleaned_data.get('image', False) + + if image: + if hasattr(image, '_size'): + if image._size > self.MAX_UPLOAD_SIZE: + self._errors['image'] = [_("The image is too large. It should have less than 5MB.")] + + return ValueError + + return image + +class ChatMessageForm(Validation): + class Meta: + model = TalkMessages + fields = ['text', 'image'] + widgets = { + 'text': forms.Textarea, + 'image': ResubmitFileWidget(attrs={'accept':'image/*'}), + } \ No newline at end of file diff --git a/chat/models.py b/chat/models.py index 4a9baeb..9eca8af 100644 --- a/chat/models.py +++ b/chat/models.py @@ -36,13 +36,13 @@ class CategoryTalk(Conversation): space = models.ForeignKey(Category, verbose_name = ('Category'), related_name = 'talk_category', null = True) class SubjectTalk(Conversation): - space = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name = 'talk_subject') + space = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name = 'talk_subject', null = True) class TalkMessages(models.Model): text = models.TextField(_('Comment'), blank = True) - image = models.ImageField(verbose_name = _('Image'), null=True, blank = True, upload_to = upload_filename, validators = [validate_img_extension]) - talk = models.ForeignKey(Conversation, verbose_name = _('Conversation'), related_name = 'message_talk') - user = models.ForeignKey(User, verbose_name = _('User'), related_name = 'message_user') + image = models.ImageField(verbose_name = _('Image'), null = True, blank = True, upload_to = upload_filename, validators = [validate_img_extension]) + talk = models.ForeignKey(Conversation, verbose_name = _('Conversation'), related_name = 'message_talk', null = True) + user = models.ForeignKey(User, verbose_name = _('User'), related_name = 'message_user', null = True) create_date = models.DateTimeField(_('Create Date'), auto_now_add = True) class ChatVisualizations(models.Model): diff --git a/chat/templates/chat/_form.html b/chat/templates/chat/_form.html new file mode 100644 index 0000000..b96e09b --- /dev/null +++ b/chat/templates/chat/_form.html @@ -0,0 +1,113 @@ +{% load static i18n %} +{% load widget_tweaks %} + + + + diff --git a/chat/templates/chat/_message.html b/chat/templates/chat/_message.html new file mode 100644 index 0000000..8cf3fd1 --- /dev/null +++ b/chat/templates/chat/_message.html @@ -0,0 +1,6 @@ +
+

{{ talk_msg.user }}

+ {% autoescape off %} + {{ talk_msg.text }} + {% endautoescape %} +
\ No newline at end of file diff --git a/chat/templates/chat/_profile.html b/chat/templates/chat/_profile.html index 622c997..33e9aaa 100644 --- a/chat/templates/chat/_profile.html +++ b/chat/templates/chat/_profile.html @@ -17,7 +17,7 @@ {{ participant }} - {% trans 'Send Message' %} + {% trans 'Send Message' %}
diff --git a/chat/templates/chat/_view_participant.html b/chat/templates/chat/_view_participant.html index e1102ae..5391df2 100644 --- a/chat/templates/chat/_view_participant.html +++ b/chat/templates/chat/_view_participant.html @@ -10,7 +10,7 @@

{{ participant }}

diff --git a/chat/templates/chat/list_participants.html b/chat/templates/chat/list_participants.html index 95582d8..89ce14e 100644 --- a/chat/templates/chat/list_participants.html +++ b/chat/templates/chat/list_participants.html @@ -53,7 +53,7 @@
{% for participant in participants %} - {% include 'chat/_view_participant.html' with space="0" %} + {% include 'chat/_view_participant.html' with space="0" space_type='general' %} {% endfor %}
@@ -71,5 +71,7 @@ + + {% endblock %} \ No newline at end of file diff --git a/chat/templates/chat/talk.html b/chat/templates/chat/talk.html index 2ec5211..e032cce 100644 --- a/chat/templates/chat/talk.html +++ b/chat/templates/chat/talk.html @@ -39,6 +39,9 @@
+ {% for talk_msg in messages %} + {% include 'chat/_message.html' %} + {% endfor %}
@@ -49,9 +52,9 @@ -
-
-

{% trans 'Type a new message to ' %}{{ participant }}

+
+
+

{% trans 'Type a new message to ' %}{{ participant }}

diff --git a/chat/urls.py b/chat/urls.py index a89b89b..be3a30b 100644 --- a/chat/urls.py +++ b/chat/urls.py @@ -4,6 +4,8 @@ from . import views urlpatterns = [ url(r'^$', views.GeneralIndex.as_view(), name='manage_general'), url(r'^participants/$', views.GeneralParticipants.as_view(), name='participants_general'), + url(r'^render_message/([\w_-]+)/$', views.render_message, name='render_message'), url(r'^talk/(?P[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.GetTalk.as_view(), name = 'talk'), + url(r'^send_message/(?P[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/(?P[\w_-]+)/(?P[\w_-]+)/(?P[\w_-]+)/$', views.SendMessage.as_view(), name = 'create'), url(r'^participant/profile/(?P[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.ParticipantProfile.as_view(), name = 'profile'), ] \ No newline at end of file diff --git a/chat/views.py b/chat/views.py index e86bfac..3d5f449 100644 --- a/chat/views.py +++ b/chat/views.py @@ -10,9 +10,12 @@ from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Q +from categories.models import Category +from subjects.models import Subject from users.models import User -from .models import Conversation, TalkMessages, ChatVisualizations +from .models import Conversation, GeneralTalk, CategoryTalk, SubjectTalk, TalkMessages, ChatVisualizations +from .forms import ChatMessageForm class GeneralIndex(LoginRequiredMixin, generic.ListView): login_url = reverse_lazy("users:login") @@ -75,6 +78,24 @@ class GeneralParticipants(LoginRequiredMixin, generic.ListView): return context +class ParticipantProfile(LoginRequiredMixin, generic.DetailView): + login_url = reverse_lazy("users:login") + redirect_field_name = 'next' + + model = User + slug_field = 'email' + slug_url_kwarg = 'email' + context_object_name = 'participant' + template_name = 'chat/_profile.html' + + def get_context_data(self, **kwargs): + context = super(ParticipantProfile, self).get_context_data(**kwargs) + + context['space'] = self.request.GET.get('space', '0') + context['space_type'] = self.request.GET.get('space_type', 'general') + + return context + class GetTalk(LoginRequiredMixin, generic.ListView): login_url = reverse_lazy("users:login") redirect_field_name = 'next' @@ -82,6 +103,7 @@ class GetTalk(LoginRequiredMixin, generic.ListView): context_object_name = 'messages' template_name = 'chat/talk.html' paginate_by = 20 + talk_id = "-1" def get_queryset(self): user = self.request.user @@ -93,6 +115,7 @@ class GetTalk(LoginRequiredMixin, generic.ListView): if talks.count() > 0: talk = talks[0] + self.talk_id = talk.id messages = TalkMessages.objects.filter(talk = talk).order_by('-create_date') @@ -104,22 +127,93 @@ class GetTalk(LoginRequiredMixin, generic.ListView): user_email = self.kwargs.get('email', '') context['participant'] = get_object_or_404(User, email = user_email) + context['talk_id'] = self.talk_id + context['space'] = self.request.GET.get('space', '0') + context['space_type'] = self.request.GET.get('space_type', 'general') return context -class ParticipantProfile(LoginRequiredMixin, generic.DetailView): +class SendMessage(LoginRequiredMixin, generic.edit.CreateView): login_url = reverse_lazy("users:login") redirect_field_name = 'next' - model = User - slug_field = 'email' - slug_url_kwarg = 'email' - context_object_name = 'participant' - template_name = 'chat/_profile.html' + form_class = ChatMessageForm + template_name = "chat/_form.html" + + def form_invalid(self, form): + context = super(SendMessage, self).form_invalid(form) + context.status_code = 400 + + return context + + def form_valid(self, form): + self.object = form.save(commit = False) + + self.object.user = self.request.user + + talk_id = self.kwargs.get('talk_id', '-1') + user = get_object_or_404(User, email = self.kwargs.get('email', '')) + space_type = self.kwargs.get('space_type', 'general') + space = self.kwargs.get('space', 0) + + if talk_id == "-1": + if space_type == 'general': + talk = GeneralTalk.objects.create(user_one = self.request.user, user_two = user, space = 0) + elif space_type == 'category': + cat = get_object_or_404(Category, id = space) + talk = CategoryTalk.objects.create(user_one = self.request.user, user_two = user, space = cat) + else: + sub = get_object_or_404(Subject, id = space) + talk = SubjectTalk.objects.create(user_one = self.request.user, user_two = user, space = sub) + else: + talk = get_object_or_404(Conversation, id = talk_id) + + self.object.talk = talk + + self.object.save() + + #entries = [] + + #paths = [reverse("mural:manage_general")] + + #notification = { + # "type": "mural", + # "subtype": "post", + # "paths": paths, + # "user_icon": self.object.user.image_url, + # "simple_notify": _("%s has made a post in General")%(str(self.object.user)), + # "complete": render_to_string("mural/_view.html", {"post": self.object}, self.request), + # "container": ".post", + # "accordion": False, + # "post_type": "general" + #} + + #notification = json.dumps(notification) + + #Group("user-%s" % user.id).send({'text': notification}) + + ChatVisualizations.objects.create(viewed = False, message = self.object, user = user) + + return super(SendMessage, self).form_valid(form) def get_context_data(self, **kwargs): - context = super(ParticipantProfile, self).get_context_data(**kwargs) + context = super(SendMessage, self).get_context_data(**kwargs) - context['space'] = self.request.GET.get('space', '0') + context['form_url'] = reverse_lazy('chat:create', args = (), kwargs = {'email': self.kwargs.get('email', ''), 'talk_id': self.kwargs.get('talk_id', None), 'space': self.kwargs.get('space', '0'), 'space_type': self.kwargs.get('space_type', 'general')}) - return context \ No newline at end of file + return context + + def get_success_url(self): + return reverse_lazy('chat:render_message', args = (self.object.id, )) + +def render_message(request, talk_msg): + msg = get_object_or_404(TalkMessages, id = talk_msg) + + context = {} + context['talk_msg'] = msg + + message = _('Message sent successfully!') + + html = render_to_string("chat/_message.html", context, request) + + return JsonResponse({'message': message, 'view': html, 'new_id': msg.id}) \ No newline at end of file -- libgit2 0.21.2