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("&#160;");
-           } 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 %}