summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/media/js/group_messaging.js53
-rw-r--r--askbot/templates/group_messaging/senders_list.html7
-rw-r--r--askbot/templates/group_messaging/threads_list.html5
-rw-r--r--askbot/templates/user_inbox/messages.html11
-rw-r--r--group_messaging/models.py22
-rw-r--r--group_messaging/urls.py5
-rw-r--r--group_messaging/views.py57
7 files changed, 130 insertions, 30 deletions
diff --git a/askbot/media/js/group_messaging.js b/askbot/media/js/group_messaging.js
index 2522f72e..08d9056e 100644
--- a/askbot/media/js/group_messaging.js
+++ b/askbot/media/js/group_messaging.js
@@ -331,6 +331,14 @@ var ThreadHeading = function() {
};
inherits(ThreadHeading, SimpleControl);
+ThreadHeading.prototype.setParent = function(elem) {
+ this._threadsList = elem;
+};
+
+ThreadHeading.prototype.getParent = function() {
+ return this._threadsList;
+};
+
ThreadHeading.prototype.getId = function() {
return this._id;
};
@@ -338,6 +346,12 @@ ThreadHeading.prototype.getId = function() {
ThreadHeading.prototype.decorate = function(element) {
this._element = element;
this._id = element.data('threadId');
+ var deleter = element.find('.delete-or-restore');
+ var me = this;
+ setupButtonEventHandlers($(deleter), function() {
+ me.getParent().deleteOrRestoreThread(me.getId());
+ return false;
+ });
};
/**
@@ -359,12 +373,9 @@ ThreadsList.prototype.getOpenThreadHandler = function(threadId) {
};
};
-ThreadsList.prototype.setHTML = function(html) {
- $.each(this._threads, function(idx, thread) {
- thread.dispose();
- });
- this._element.html(html);
- this.decorate(this._element);
+ThreadsList.prototype.deleteOrRestoreThread = function(threadId) {
+ var ctr = this._messageCenter;
+ ctr.deleteOrRestoreThread(threadId, this._senderId);
};
ThreadsList.prototype.decorate = function(element) {
@@ -374,12 +385,14 @@ ThreadsList.prototype.decorate = function(element) {
var threads = [];
$.each(headingElements, function(idx, headingElement) {
var heading = new ThreadHeading();
+ heading.setParent(me);
heading.decorate($(headingElement));
var threadId = heading.getId();
heading.setHandler(me.getOpenThreadHandler(threadId));
threads.push(heading);
});
this._threads = threads;
+ this._senderId = element.data('senderId');
}
@@ -604,25 +617,43 @@ MessageCenter.prototype.openThread = function(threadId) {
});
};
-MessageCenter.prototype.loadThreadsForSender = function(senderId) {
+MessageCenter.prototype.setThreadsList = function(list) {
+ this._threadsList = list;
+ this._secondCol.prepend(list.getElement());
+};
+
+MessageCenter.prototype.hitThreadsList = function(url, senderId, requestMethod) {
var threadsList = this._threadsList;
- var url = this._urls['getThreads'];
- me = this;
+ var me = this;
$.ajax({
- type: 'GET',
+ type: requestMethod,
dataType: 'json',
url: url,
cache: false,
data: {sender_id: senderId},
success: function(data) {
if (data['success']) {
- threadsList.setHTML(data['html']);
+ threadsList.dispose();
+ var threads = new ThreadsList();
+ threads.setMessageCenter(me);
+ threads.decorate($(data['html']));
+ me.setThreadsList(threads);
me.setState('show-list');
}
}
});
};
+MessageCenter.prototype.deleteOrRestoreThread = function(threadId, senderId) {
+ var url = this._urls['getThreads'] + threadId + '/delete-or-restore/';
+ this.hitThreadsList(url, senderId, 'POST');
+};
+
+MessageCenter.prototype.loadThreadsForSender = function(senderId) {
+ var url = this._urls['getThreads'];
+ this.hitThreadsList(url, senderId, 'GET');
+};
+
MessageCenter.prototype.decorate = function(element) {
this._element = element;
this._firstCol = element.find('.first-col');
diff --git a/askbot/templates/group_messaging/senders_list.html b/askbot/templates/group_messaging/senders_list.html
index 687cacd6..4bee2626 100644
--- a/askbot/templates/group_messaging/senders_list.html
+++ b/askbot/templates/group_messaging/senders_list.html
@@ -1,8 +1,3 @@
-{#<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>
@@ -10,5 +5,7 @@
{% for sender in senders %}
<li><a data-sender-id="{{ sender.id }}">{{ sender.username|escape }}</a></li>
{% endfor %}
+ {# -2 is deleted messages #}
+ <li><a class="trash" data-sender-id="-2">{% trans %}trash{% endtrans %}</a></li>
</ul>
{% endif %}
diff --git a/askbot/templates/group_messaging/threads_list.html b/askbot/templates/group_messaging/threads_list.html
index bc0af802..43492402 100644
--- a/askbot/templates/group_messaging/threads_list.html
+++ b/askbot/templates/group_messaging/threads_list.html
@@ -1,10 +1,13 @@
-<table class="threads-list">
+<table class="threads-list {% if sender_id == -2 %}trash{% endif %}"
+ data-sender-id="{{ sender_id }}"
+>
{% if threads %}
{% for thread in threads %}
{% set thread_data = threads_data[thread.id] %}
<tr class="thread-heading {{ thread_data['status'] }}"
data-thread-id="{{ thread.id }}"
>
+ <td class="delete-or-restore"></td>
<td class="senders">{{ thread_data['senders_info']|escape }}</td>
<td class="subject">{{ thread.headline|escape }}</td>
<td class="timestamp">{{ thread.last_active_at|timesince }}</td>
diff --git a/askbot/templates/user_inbox/messages.html b/askbot/templates/user_inbox/messages.html
index 5108d15e..8c731401 100644
--- a/askbot/templates/user_inbox/messages.html
+++ b/askbot/templates/user_inbox/messages.html
@@ -22,6 +22,7 @@
}
table.threads-list {
width: 100%;
+ border-spacing: 0px;
}
.threads-list tr {
height: 2em;
@@ -36,6 +37,16 @@
.threads-list tr:hover {
background-color: #eff5f6;
}
+ .threads-list td.delete-or-restore {
+ width: 15px;
+ background-image: none;
+ }
+ .threads-list tr:hover td.delete-or-restore {
+ background: url({{"/images/delete.png"|media}}) no-repeat center center;
+ }
+ .threads-list.trash tr:hover td.delete-or-restore {
+ background-image: url({{"/images/delete.png"|media}});
+ }
td.empty {
line-height: 30px;
vertical-align: middle;
diff --git a/group_messaging/models.py b/group_messaging/models.py
index 62f720cf..f78f2b87 100644
--- a/group_messaging/models.py
+++ b/group_messaging/models.py
@@ -87,7 +87,7 @@ class MessageMemo(models.Model):
(ARCHIVED, 'archived')
)
user = models.ForeignKey(User)
- message = models.ForeignKey('Message')
+ message = models.ForeignKey('Message', related_name='memos')
status = models.SmallIntegerField(
choices=STATUS_CHOICES, default=SEEN
)
@@ -99,13 +99,21 @@ class MessageMemo(models.Model):
class MessageManager(models.Manager):
"""model manager for the :class:`Message`"""
- def get_threads_for_user(self, user):
+ def get_threads_for_user(self, user, deleted=False):
user_groups = user.groups.all()
- return self.filter(
- root=None,
- message_type=Message.STORED,
- recipients__in=user_groups
- )
+ user_thread_filter = models.Q(
+ root=None,
+ message_type=Message.STORED,
+ recipients__in=user_groups
+ )
+ deleted_filter = models.Q(
+ memos__status=MessageMemo.ARCHIVED,
+ memos__user=user
+ )
+ if deleted:
+ return self.filter(user_thread_filter & deleted_filter)
+ else:
+ return self.filter(user_thread_filter & ~deleted_filter)
def create(self, **kwargs):
"""creates a message"""
diff --git a/group_messaging/urls.py b/group_messaging/urls.py
index 30002bf3..19ee35bb 100644
--- a/group_messaging/urls.py
+++ b/group_messaging/urls.py
@@ -15,6 +15,11 @@ urlpatterns = patterns('',
name='thread_details'
),
url(
+ '^threads/(?P<thread_id>\d+)/delete-or-restore/$',
+ views.DeleteOrRestoreThread().as_view(),
+ name='delete_or_restore_thread'
+ ),
+ url(
'^threads/create/$',
views.NewThread().as_view(),
name='create_thread'
diff --git a/group_messaging/views.py b/group_messaging/views.py
index 289961ff..ef95e1d5 100644
--- a/group_messaging/views.py
+++ b/group_messaging/views.py
@@ -18,6 +18,7 @@ from django.http import HttpResponseNotAllowed
from django.http import HttpResponseForbidden
from django.utils import simplejson
from group_messaging.models import Message
+from group_messaging.models import MessageMemo
from group_messaging.models import SenderList
from group_messaging.models import LastVisitTime
from group_messaging.models import get_personal_group_by_user_id
@@ -139,6 +140,7 @@ class PostReply(InboxView):
template_name='group_messaging/stored_message.html'
)
+
class ThreadsList(InboxView):
"""shows list of threads for a given user"""
template_name = 'group_messaging/threads_list.html'
@@ -147,11 +149,13 @@ class ThreadsList(InboxView):
def get_context(self, request):
"""returns thread list data"""
#get threads and the last visit time
- threads = Message.objects.get_threads_for_user(request.user)
-
- sender_id = IntegerField().clean(request.GET.get('sender_id', '-1'))
- if sender_id != -1:
- threads = threads.filter(sender__id=sender_id)
+ sender_id = IntegerField().clean(request.REQUEST.get('sender_id', '-1'))
+ if sender_id == -2:
+ threads = Message.objects.get_threads_for_user(request.user, deleted=True)
+ else:
+ threads = Message.objects.get_threads_for_user(request.user)
+ if sender_id != -1:
+ threads = threads.filter(sender__id=sender_id)
#for each thread we need to know if there is something
#unread for the user - to mark "new" threads as bold
@@ -179,7 +183,48 @@ class ThreadsList(InboxView):
#after we have all the data - update the last visit time
last_visit_times.update(at=datetime.datetime.now())
- return {'threads': threads, 'threads_data': threads_data}
+ return {
+ 'threads': threads,
+ 'threads_data': threads_data,
+ 'sender_id': sender_id
+ }
+
+
+class DeleteOrRestoreThread(ThreadsList):
+ """subclassing :class:`ThreadsList`, because deletion
+ or restoring of thread needs subsequent refreshing
+ of the threads list"""
+
+ http_method_list = ('POST',)
+
+ def post(self, request, thread_id=None):
+ """process the post request:
+ * delete or restore thread
+ * recalculate the threads list and return it for display
+ by reusing the threads list "get" function
+ """
+ #part of the threads list context
+ sender_id = IntegerField().clean(request.POST['sender_id'])
+
+ #a little cryptic, but works - sender_id==-2 means deleted post
+ if sender_id == -2:
+ action = 'restore'
+ else:
+ action = 'delete'
+
+ thread = Message.objects.get(id=thread_id)
+ memo, created = MessageMemo.objects.get_or_create(
+ user=request.user,
+ message=thread
+ )
+ if action == 'delete':
+ memo.status = MessageMemo.ARCHIVED
+ else:
+ memo.status = MessageMemo.SEEN
+ memo.save()
+
+ context = self.get_context(request)
+ return self.render_to_response(context)
class SendersList(InboxView):