Mercurial > public > sg101
changeset 806:59e36169a814
Private messages refactor: add delete functionality.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Mon, 01 Sep 2014 15:53:35 -0500 |
parents | e966d5553955 |
children | 22cc8c1aec03 |
files | messages/static/js/messages.js messages/static/js/tabbed_messages.js messages/urls.py messages/views.py sg101/templates/messages/inbox.html sg101/templates/messages/outbox.html |
diffstat | 6 files changed, 66 insertions(+), 252 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messages/static/js/messages.js Mon Sep 01 15:53:35 2014 -0500 @@ -0,0 +1,11 @@ +function tabMasterCheckClick(box, name) { + var state = $(box).prop('checked'); + $('input[name="' + name + '"]').each(function() { + this.checked = state; + }); +} + +function bulkMsgAction(action) { + return confirm("Really " + action + " checked messages?"); + return false; +}
--- a/messages/static/js/tabbed_messages.js Sun Aug 31 16:01:00 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -$(document).ready(function() { - - // allow HTML in title for 1.10 - $.widget("ui.dialog", $.extend({}, $.ui.dialog.prototype, { - _title: function(title) { - if (!this.options.title ) { - title.html(" "); - } else { - title.html(this.options.title); - } - } - })); - - $tabs = $('#tabs').tabs({ - active: initialTab, - activate: function(event, ui) { - $(ui.panel).html(''); - }, - load: function(event, ui) { - selectedTab = ui; - - if (ui.tab.index() == 1 && receiver && !doReply) - { - $('#id_receiver').val(receiver); - receiver = ''; - } - else if (doReply && ui.tab.index() == 1) - { - doReply = false; - var msg = msgCache[$msgDialog.msgId]; - $('#id_receiver').val(msg.sender); - $('#id_subject').val(msg.re_subject); - $('#id_message').val(msg.re_content); - $('#msg_compose_form').append('<input type="hidden" name="reply_to" value="' + - $msgDialog.msgId + '" />'); - } - }, - beforeLoad: function(event, ui) { - ui.jqXHR.error(function(xhr, status, index, anchor) { - $(anchor.hash).html( - "Oops, we couldn't load this tab. We'll try to fix this as soon as possible."); - }); - } - }); - $msgDialog = $('#msgDialog').dialog({ - autoOpen: false, - width: 460, - height: 'auto', - maxHeight: false, - resizable: false, - buttons: [ - { - text: "Reply", - click: function() { - doReply = true; - $(this).dialog('close'); - $tabs.tabs("option", "active", 1); - } - }, - { - text: "Close", - click: function() { - $(this).dialog('close'); - } - } - ] - }); -}); - -var $tabs = 0; -var $msgDialog = 0; -var msgCache = {}; -var doReply = false; -var selectedTab = 0; - -function updateUnreadMsgText(n) -{ - var txt = ''; - if (n == 1) { - txt = "1 New Message"; - } - else if (n > 1) { - txt = n + " New Messages"; - } - else { - txt = "Private Messages"; - } - $('#unread_msg_text').html(txt); -} - -function showMsg(link, id) { - $msgDialog.msgId = id; // create a msgId attribute on the dialog - var msg = msgCache[id]; - - // mark as read if necessary - var $link = $(link); - - if (username == msg.receiver && $link.hasClass('unread')) { - $(link).removeClass('unread'); - - // decrement count of unread messages in base template - if (unreadMsgCount > 0) - { - updateUnreadMsgText(--unreadMsgCount); - } - } - - var s = '<div style="max-height:450px;overflow:auto">' + msg.content + '</div>'; - $msgDialog.html(s); - var title = 'PM From ' + msg.sender + ' To ' + msg.receiver + '<br />' + msg.subject; - $msgDialog.dialog('option', 'title', title); - $msgDialog.dialog('open'); -} - -function msgShow(link, id) { - if (msgCache[id]) { - showMsg(link, id); - return; - } - $.ajax({ - url: '/messages/message/', - type: 'POST', - data: { - msg_id : id - }, - dataType: 'json', - success: function (data, textStatus) { - msgCache[id] = data; - showMsg(link, id); - }, - error: function (xhr, textStatus, ex) { - alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + - xhr.responseText); - } - }); -} - -function submitOptions(form) { - $.ajax({ - url: '/messages/options-tab/', - type: 'POST', - data: $(form).serialize(), - dataType: 'html', - success: function (data, textStatus) { - $(selectedTab.panel).html(data); - }, - error: function (xhr, textStatus, ex) { - alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + - xhr.responseText); - } - }); - return false; -} - -function messageSubmit(form) { - $.ajax({ - url: '/messages/compose-tab/', - type: 'POST', - data: $(form).serialize(), - dataType: 'html', - success: function (data, textStatus) { - $(selectedTab.panel).html(data); - }, - error: function (xhr, textStatus, ex) { - alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + - xhr.responseText); - } - }); - return false; -} - -function tabMasterCheckClick(box, name) { - var state = $(box).prop('checked'); - $('input[name="' + name + '"]').each(function() { - this.checked = state; - }); -} - -function bulkMsgAction(form, action) { - if (confirm("Really " + action + " checked messages?")) { - $.ajax({ - url: '/messages/bulk/', - type: 'POST', - data: $(form).serialize(), - dataType: 'text', - success: function (data, textStatus) { - $tabs.tabs("load", selectedTab.tab.index()); - }, - error: function (xhr, textStatus, ex) { - alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + - xhr.responseText); - } - }); - } - return false; -} - -function ajaxPageFetch(link) { - $.ajax({ - url: link.href, - type: 'GET', - dataType: 'html', - success: function (data, textStatus) { - $(selectedTab.panel).html(data); - }, - error: function (xhr, textStatus, ex) { - alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + - xhr.responseText); - } - }); - return false; -}
--- a/messages/urls.py Sun Aug 31 16:01:00 2014 -0500 +++ b/messages/urls.py Mon Sep 01 15:53:35 2014 -0500 @@ -21,9 +21,9 @@ url(r'^options/$', 'messages.views.options', name='messages-options'), -# url(r'^delete/$', -# 'messages.views.delete', -# name='messages-delete'), + url(r'^delete/$', + 'messages.views.delete', + name='messages-delete'), # url(r'^undelete/$', # 'messages.views.undelete', # name='messages-undelete'),
--- a/messages/views.py Sun Aug 31 16:01:00 2014 -0500 +++ b/messages/views.py Mon Sep 01 15:53:35 2014 -0500 @@ -6,6 +6,7 @@ import json from django.contrib.auth.decorators import login_required +from django.views.decorators.http import require_POST from django.contrib.auth.models import User from django.contrib import messages as django_messages from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger @@ -203,54 +204,58 @@ }) -def _only_integers(slist): +def _delete_pms(user, pm_ids): """ - Accepts a list of strings. Returns a list of integers consisting of only - those elements from the original list that could be converted to integers + Process the request to delete the list of PM ids by user. """ - result = [] - for s in slist: - try: - n = int(s) - except ValueError: - pass - else: - result.append(n) - return result - - -def _delete_msgs(user, msg_ids): - """ - Deletes the messages given by the list of msg_ids. For this to succeed, the - user has to be either the sender or receiver on each message. - - """ - msg_ids = _only_integers(msg_ids) - msgs = Message.objects.filter(id__in=msg_ids) + msgs = Message.objects.filter(id__in=pm_ids) + now = datetime.datetime.now() for msg in msgs: if msg.sender == user: - if (msg.receiver_delete_date is not None or - msg.read_date is None): + if msg.receiver_delete_date is not None or msg.read_date is None: # Both parties deleted the message or receiver hasn't read it # yet, we can delete it now msg.delete() else: - # receiver still has it in inbox - msg.sender_delete_date = datetime.datetime.now() + # receiver still has PM in their inbox + msg.sender_delete_date = now msg.save() - elif msg.receiver == user: if msg.sender_delete_date is not None: # both parties deleted the message, we can delete it now msg.delete() else: - # sender still has it in the outbox - msg.receiver_delete_date = datetime.datetime.now() + # sender still has PM in their inbox + msg.receiver_delete_date = now msg.save() +@login_required +@require_POST +def delete(request): + """ + Deletes the requested PM's. The user must be either a sender or receiver for + this to work. + + """ + pm_ids = request.POST.getlist('pm_ids') + if pm_ids: + _delete_pms(request.user, pm_ids) + + # Figure out where to redirect to + src = request.POST.get('src', 'inbox') + try: + page = int(request.POST.get('page', '1')) + except ValueError: + page = 1 + + view_name = 'messages-inbox' if src == inbox else 'messages-outbox' + url = reverse(view_name) + '?page={}'.format(page) + return redirect(url) + + def _undelete_msgs(user, msg_ids): """ Attempts to "undelete" the messages given by the msg_ids list.
--- a/sg101/templates/messages/inbox.html Sun Aug 31 16:01:00 2014 -0500 +++ b/sg101/templates/messages/inbox.html Mon Sep 01 15:53:35 2014 -0500 @@ -1,19 +1,22 @@ {% extends 'messages/messages_base.html' %} +{% block custom_js %} +<script src="{{ STATIC_URL }}js/messages.js"></script> +{% endblock %} {% block messages_content %} <h3>Inbox <small>(Page {{ page.number }} of {{ page.paginator.num_pages }})</small></h3> <p> This is your inbox. It contains messages sent to you by others. Messages in <strong>bold</strong> are unread. -Messages in <em>italics</em> have been replied to. +Messages in <em>italics</em> indicate you have replied to the message. </p> {% if page.object_list %} {% include "messages/pagination.html" %} - <form action="." onsubmit="return bulkMsgAction(this, 'delete');"> + <form action="{% url 'messages-delete' %}" method="post" onsubmit="return bulkMsgAction('delete');">{% csrf_token %} <table class="messages"> <tr> <th>From</th> <th>Subject</th> <th>Date</th> - <th><input type="checkbox" onclick="tabMasterCheckClick(this, 'inbox_ids');" /></th> + <th><input type="checkbox" onclick="tabMasterCheckClick(this, 'pm_ids');" /></th> </tr> {% for msg in page.object_list %} <tr> @@ -24,11 +27,13 @@ class="{% if msg.unread %}unread {% endif %}{% if msg.replied_to %}replied_to{% endif %}">{{ msg.subject }}</a> </td> <td>{{ msg.send_date|date:"M j, Y g:i A" }}</td> - <td><input type="checkbox" name="inbox_ids" value="{{ msg.id }}" /></td> + <td><input type="checkbox" name="pm_ids" value="{{ msg.id }}" /></td> </tr> {% endfor %} <tr><td colspan="4"><input type="submit" value="Delete Checked Messages" /></td></tr> </table> + <input type="hidden" name="src" value="inbox" /> + <input type="hidden" name="page" value="{{ page.number }}" /> </form> {% include "messages/pagination.html" %} {% else %}
--- a/sg101/templates/messages/outbox.html Sun Aug 31 16:01:00 2014 -0500 +++ b/sg101/templates/messages/outbox.html Mon Sep 01 15:53:35 2014 -0500 @@ -1,20 +1,23 @@ {% extends 'messages/messages_base.html' %} +{% block custom_js %} +<script src="{{ STATIC_URL }}js/messages.js"></script> +{% endblock %} {% block messages_content %} <h3>Outbox <small>(Page {{ page.number }} of {{ page.paginator.num_pages }})</small></h3> <p> This is your outbox. It contains messages you have sent to other members. Messages in <strong>bold</strong> are unread -by the recipient. Messages in <em>italics</em> have been replied to. +by the recipient. Messages in <em>italics</em> have been replied to by the receiver. </p> {% if page.object_list %} {% include "messages/pagination.html" %} - <form action="." onsubmit="return bulkMsgAction(this, 'delete');"> + <form action="{% url 'messages-delete' %}" method="post" onsubmit="return bulkMsgAction('delete');">{% csrf_token %} <table class="messages"> <tr> <th>To</th> <th>Subject</th> <th>Sent</th> <th>Received</th> - <th><input type="checkbox" onclick="tabMasterCheckClick(this, 'outbox_ids');" /></th> + <th><input type="checkbox" onclick="tabMasterCheckClick(this, 'pm_ids');" /></th> </tr> {% for msg in page.object_list %} <tr> @@ -26,11 +29,13 @@ </td> <td>{{ msg.send_date|date:"M j, Y g:i A" }}</td> <td>{% if msg.unread %}<em>Unread</em>{% else %}{{ msg.read_date|date:"M j, Y g:i A" }}{% endif %}</td> - <td><input type="checkbox" name="outbox_ids" value="{{ msg.id }}" /></td> + <td><input type="checkbox" name="pm_ids" value="{{ msg.id }}" /></td> </tr> {% endfor %} <tr><td colspan="5"><input type="submit" value="Delete Checked Messages" /></td></tr> </table> + <input type="hidden" name="src" value="outbox" /> + <input type="hidden" name="page" value="{{ page.number }}" /> </form> {% include "messages/pagination.html" %} {% else %}