summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/media/js/group_messaging.js186
-rw-r--r--askbot/templates/group_messaging/home.html1
-rw-r--r--askbot/templates/group_messaging/macros.html2
-rw-r--r--askbot/templates/group_messaging/senders_list.html5
-rw-r--r--askbot/templates/group_messaging/stored_message.html2
-rw-r--r--askbot/templates/user_inbox/messages.html3
-rw-r--r--group_messaging/urls.py5
-rw-r--r--group_messaging/views.py13
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):