diff options
-rw-r--r-- | askbot/media/js/group_messaging.js | 186 | ||||
-rw-r--r-- | askbot/templates/group_messaging/home.html | 1 | ||||
-rw-r--r-- | askbot/templates/group_messaging/macros.html | 2 | ||||
-rw-r--r-- | askbot/templates/group_messaging/senders_list.html | 5 | ||||
-rw-r--r-- | askbot/templates/group_messaging/stored_message.html | 2 | ||||
-rw-r--r-- | askbot/templates/user_inbox/messages.html | 3 | ||||
-rw-r--r-- | group_messaging/urls.py | 5 | ||||
-rw-r--r-- | group_messaging/views.py | 13 |
8 files changed, 192 insertions, 25 deletions
diff --git a/askbot/media/js/group_messaging.js b/askbot/media/js/group_messaging.js index 1b0275e2..2ab677ff 100644 --- a/askbot/media/js/group_messaging.js +++ b/askbot/media/js/group_messaging.js @@ -37,9 +37,6 @@ var MessageComposer = function() { }; inherits(MessageComposer, HideableWidget); -MessageComposer.prototype.send = function() { -}; - MessageComposer.prototype.onAfterCancel = function(handler) { if (handler) { this._onAfterCancel = handler; @@ -172,6 +169,82 @@ MessageComposer.prototype.createDom = function() { }; +var ReplyMessageComposer = function() { + MessageComposer.call(this); +}; +inherits(ReplyMessageComposer, MessageComposer); + +ReplyMessageComposer.prototype.setParent = function(elem) { + this._parent = elem; +}; + +ReplyMessageComposer.prototype.onSendSuccessInternal = function(data) { + var message = new Message(); + message.decorate($(data['html'])); + this._parent.addMessage(message); +}; + +/** + * @constructor + * same as message composer, but initially + * hidden and presented by a "reply" link + */ +var ReplyComposer = function() { + HideableWidget.call(this); +}; +inherits(ReplyComposer, HideableWidget); + +ReplyComposer.prototype.open = function() { + this._opener.hide(); + this._editor.show(); +}; + +ReplyComposer.prototype.close = function() { + this._opener.show(); + this._editor.hide(); +} + +ReplyComposer.prototype.setSendUrl = function(url) { + this._sendUrl = url; +}; + +ReplyComposer.prototype.setPostData = function(data) { + this._editor.setPostData(data); +}; + +ReplyComposer.prototype.setThread = function(thread) { + this._thread = thread; +}; + +ReplyComposer.prototype.addMessage = function(message) { + this._thread.addMessage(message); +}; + +ReplyComposer.prototype.createDom = function() { + this._element = this.makeElement('div'); + this._element.addClass('reply-composer'); + var opener = this.makeElement('a'); + opener.html(gettext('Reply')); + this._opener = opener; + this._element.append(opener); + + var editor = new ReplyMessageComposer(); + editor.setSendUrl(this._sendUrl); + editor.setParent(this); + editor.onSendSuccess(function() { + editor.cancel(); + notify.show(gettext('message sent'), true); + }); + this._editor = editor; + this._element.append(editor.getElement()); + + var me = this; + setupButtonEventHandlers(opener, function() { me.open() }); + editor.onAfterCancel(function() { me.close() }); + this.hide(); +}; + + /** * @constructor */ @@ -318,6 +391,15 @@ var Message = function() { }; inherits(Message, Widget); +Message.prototype.getId = function() { + return this._id; +}; + +Message.prototype.decorate = function(element) { + this._element = element; + this._id = element.data('messageId'); +}; + /** * @constructor @@ -327,6 +409,52 @@ var ThreadContainer = function() { }; inherits(ThreadContainer, HideableWidget); +ThreadContainer.prototype.show = function() { + ThreadContainer.superClass_.show.call(this); + this._editor.close(); + this._editor.show(); +}; + +ThreadContainer.prototype.hide = function() { + ThreadContainer.superClass_.hide.call(this); + this._editor.close(); + this._editor.hide(); +}; + +/** + * sets html content part of the thread + * and re-decorates it + */ +ThreadContainer.prototype.setContent = function(html) { + if (this._thread) { + this._thread.dispose(); + } + var thread = new Thread(); + thread.decorate($(html)); + this._thread = thread; + this._contentElement.empty(); + this._contentElement.append(thread.getElement()); + var postData = {parent_id: thread.getLastMessageId()}; + this._editor.setPostData(postData); + this._editor.setThread(thread); +}; + +ThreadContainer.prototype.setReplyUrl = function(url) { + this._replyUrl = url; +}; + +ThreadContainer.prototype.createDom = function() { + this._element = this.makeElement('div'); + var content = this.makeElement('div'); + this._contentElement = content; + this._element.append(content); + + var editor = new ReplyComposer(); + editor.setSendUrl(this._replyUrl); + this._element.append(editor.getElement()); + this._editor = editor; +}; + /** * @constructor @@ -336,6 +464,34 @@ var Thread = function() { }; inherits(Thread, WrappedElement); +Thread.prototype.getLastMessageId = function() { + return this._messages.slice(-1)[0].getId(); +}; + +Thread.prototype.dispose = function() { + $.each(this._messages, function(idx, message) { + message.dispose() + }); + Thread.superClass_.dispose.call(this); +}; + +Thread.prototype.addMessage = function(message) { + var li = this.makeElement('li'); + this._element.append(li); + li.append(message.getElement()); +}; + +Thread.prototype.decorate = function(element) { + this._element = element; + var messages = []; + $.each(element.find('.message'), function(idx, item) { + var message = new Message(); + message.decorate($(item)); + messages.push(message); + }); + this._messages = messages; +}; + /** * @constructor @@ -430,23 +586,10 @@ MessageCenter.prototype.setState = function(state) { } }; -MessageCenter.prototype.clearThread = function() { - if (this._thread) { - this._thread.dispose(); - } - this._threadContainer.html(''); -}; - -MessageCenter.prototype.setThreadHTML = function(html) { - this._threadContainer.html(html); - var thread = new Thread(); - thread.decorate($(this._threadContainer.children()[0])); - this._thread = thread; -}; - MessageCenter.prototype.openThread = function(threadId) { var url = this._urls['getThreads'] + threadId + '/'; var me = this; + var threadContainer = this._threadContainer; $.ajax({ type: 'GET', dataType: 'json', @@ -454,8 +597,7 @@ MessageCenter.prototype.openThread = function(threadId) { cache: false, success: function(data) { if (data['success']) { - me.clearThread(); - me.setThreadHTML(data['html']); + threadContainer.setContent(data['html']); me.setState('show-thread'); } } @@ -488,7 +630,8 @@ MessageCenter.prototype.decorate = function(element) { this._urls = { getThreads: element.data('getThreadsUrl'), - getThreadDetails: element.data('getThreadDetailsUrl') + getThreadDetails: element.data('getThreadDetailsUrl'), + reply: element.data('replyUrl') }; //read sender list @@ -503,8 +646,9 @@ MessageCenter.prototype.decorate = function(element) { this._threadsList = threads; //add empty thread container var threadContainer = new ThreadContainer(); + this._threadContainer = threadContainer; + threadContainer.setReplyUrl(this._urls['reply']); this._secondCol.append(threadContainer.getElement()); - this._threadContainer = threadContainer.getElement(); var me = this; //create editor diff --git a/askbot/templates/group_messaging/home.html b/askbot/templates/group_messaging/home.html index 258ee6e8..d5d34a37 100644 --- a/askbot/templates/group_messaging/home.html +++ b/askbot/templates/group_messaging/home.html @@ -1,6 +1,7 @@ <div class="group-messaging" data-create-thread-url="{% url create_thread %}" data-get-threads-url="{% url get_threads %}" + data-reply-url="{% url post_reply %}" > <div class="first-col"> <button class="submit compose">{% trans %}compose{% endtrans %}</button> diff --git a/askbot/templates/group_messaging/macros.html b/askbot/templates/group_messaging/macros.html index 312fe1e2..7fbe4434 100644 --- a/askbot/templates/group_messaging/macros.html +++ b/askbot/templates/group_messaging/macros.html @@ -1,5 +1,5 @@ {%- macro message(post, visitor) -%} -<div class="message"> +<div class="message" data-message-id="{{ post.id }}"> <p class="header"> {% if post.sender == visitor %} {% trans date=post.sent_at %}You wrote on {{ date }}:{% endtrans %} diff --git a/askbot/templates/group_messaging/senders_list.html b/askbot/templates/group_messaging/senders_list.html index a2e4766f..687cacd6 100644 --- a/askbot/templates/group_messaging/senders_list.html +++ b/askbot/templates/group_messaging/senders_list.html @@ -1,3 +1,8 @@ +{#<ul class="mailboxes"> + <li><a class="inbox selected">{% trans %}Inbox{% endtrans %}</a></li> + <li><a class="sent">{% trans %}Sent{% endtrans %}</a></li> + <li><a class="trash">{% trans %}Trash{% endtrans %}</a></li> +</ul>#} {% if senders %} <ul class="senders-list"> <li>{% trans %}Messages by sender:{% endtrans %}</li> diff --git a/askbot/templates/group_messaging/stored_message.html b/askbot/templates/group_messaging/stored_message.html new file mode 100644 index 00000000..1bf31368 --- /dev/null +++ b/askbot/templates/group_messaging/stored_message.html @@ -0,0 +1,2 @@ +{% from "group_messaging/macros.html" import message %} +{{ message(post, user) }} diff --git a/askbot/templates/user_inbox/messages.html b/askbot/templates/user_inbox/messages.html index d42e5fb4..5108d15e 100644 --- a/askbot/templates/user_inbox/messages.html +++ b/askbot/templates/user_inbox/messages.html @@ -67,6 +67,9 @@ padding-bottom: 10px; margin-top: -25px; } + .reply-composer .message-composer { + margin-top: 0; + } .message-composer input.recipients, .message-composer textarea { width: 400px; diff --git a/group_messaging/urls.py b/group_messaging/urls.py index 618ae1d5..30002bf3 100644 --- a/group_messaging/urls.py +++ b/group_messaging/urls.py @@ -23,5 +23,10 @@ urlpatterns = patterns('', '^senders/$', views.SendersList().as_view(), name='get_senders' + ), + url( + '^post-reply/$', + views.PostReply().as_view(), + name='post_reply' ) ) diff --git a/group_messaging/views.py b/group_messaging/views.py index 0ea710db..289961ff 100644 --- a/group_messaging/views.py +++ b/group_messaging/views.py @@ -40,7 +40,7 @@ class InboxView(object): """ if template_name is None: template_name = self.template_name - template = get_template(self.template_name) + template = get_template(template_name) html = template.render(context) json = simplejson.dumps({'html': html, 'success': True}) return HttpResponse(json, mimetype='application/json') @@ -116,7 +116,7 @@ class NewThread(InboxView): return HttpResponse(simplejson.dumps(result), mimetype='application/json') -class NewResponse(InboxView): +class PostReply(InboxView): """view to create a new response""" http_method_list = ('POST',) @@ -128,8 +128,15 @@ class NewResponse(InboxView): text=request.POST['text'], parent=parent ) + last_visit = LastVisitTime.objects.get( + message=message.root, + user=request.user + ) + last_visit.at = datetime.datetime.now() + last_visit.save() return self.render_to_response( - {'message': message}, template_name='stored_message.htmtl' + {'post': message, 'user': request.user}, + template_name='group_messaging/stored_message.html' ) class ThreadsList(InboxView): |