← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~gmb/launchpad/add-mute-button-204980-2 into lp:launchpad

 

Graham Binns has proposed merging lp:~gmb/launchpad/add-mute-button-204980-2 into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  #204980 bug contacts should be able to unsubscribe from implicit subscriptions
  https://bugs.launchpad.net/bugs/204980

For more details, see:
https://code.launchpad.net/~gmb/launchpad/add-mute-button-204980-2/+merge/52686

This branch adds the initial infrastructure for a "Mute subscription"
link on the bug page. This will allow people to mute all mail from a bug
(in real terms it adds a subscription with a BugNotificationLevel of
NOTHING, but we hide that from the user).

This branch adds a mute_subscription() method to the BugContextMenu,
which will be used to actually display the link. It also adds JS
handlers for the link's onClick event.

Because the mute link as it currently stands is a bit broken (it sort of
works, but if you're already subscribed it will actually unsubscribe you
rather than muting your subscription; that kind of thing) it's not
actually hooked up in this branch. If you want to test this in a
Launchpad dev instance you need to apply the following patch to the
branch: http://pastebin.ubuntu.com/577852/. You'll also need to enable
the advanced subscriptions for malone, by executing the following query
in psql: http://pastebin.ubuntu.com/577854/
-- 
https://code.launchpad.net/~gmb/launchpad/add-mute-button-204980-2/+merge/52686
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gmb/launchpad/add-mute-button-204980-2 into lp:launchpad.
=== modified file 'lib/canonical/launchpad/icing/style.css'
--- lib/canonical/launchpad/icing/style.css	2011-02-24 15:05:29 +0000
+++ lib/canonical/launchpad/icing/style.css	2011-03-09 14:18:16 +0000
@@ -513,7 +513,7 @@
 #affected-software tr.highlight {background-color: #ff9;}
 
 /* Bug report page subscribe/unsubscribe spinner */
-div#sub-unsub-spinner {
+div#sub-unsub-spinner, div#mute-unmute-spinner {
   background: url(/@@/spinner) center left no-repeat;
   color:#999;
   display:none;

=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py	2011-03-07 11:24:07 +0000
+++ lib/lp/bugs/browser/bug.py	2011-03-09 14:18:16 +0000
@@ -201,7 +201,8 @@
         'editdescription', 'markduplicate', 'visibility', 'addupstream',
         'adddistro', 'subscription', 'addsubscriber', 'addcomment',
         'nominate', 'addbranch', 'linktocve', 'unlinkcve',
-        'createquestion', 'removequestion', 'activitylog', 'affectsmetoo']
+        'createquestion', 'mute_subscription', 'removequestion',
+        'activitylog', 'affectsmetoo']
 
     def __init__(self, context):
         # Always force the context to be the current bugtask, so that we don't
@@ -272,6 +273,21 @@
                 'Launchpad will email that person whenever this bugs '
                 'changes'))
 
+    def mute_subscription(self):
+        """Return the 'Mute subscription' Link."""
+        user = getUtility(ILaunchBag).user
+        if self.context.bug.isMuted(user):
+            text = "Unmute bug mail"
+        else:
+            text = "Mute bug mail"
+
+        # We link to '#' here because we don't yet have a view to handle
+        # this link.
+        return Link(
+            '#', text, icon='remove', summary=(
+                "Mute this bug so that you will never receive emails "
+                "about it."))
+
     def nominate(self):
         """Return the 'Target/Nominate for series' Link."""
         launchbag = getUtility(ILaunchBag)

=== modified file 'lib/lp/bugs/browser/tests/test_bug_context_menu.py'
--- lib/lp/bugs/browser/tests/test_bug_context_menu.py	2011-03-07 11:24:07 +0000
+++ lib/lp/bugs/browser/tests/test_bug_context_menu.py	2011-03-09 14:18:16 +0000
@@ -47,3 +47,21 @@
                     person, person, level=BugNotificationLevel.NOTHING)
                 link = self.context_menu.subscription()
                 self.assertEqual('Subscribe', link.text)
+
+    def test_mute_subscription_link(self):
+        # The mute_subscription() method of BugContextMenu will return a
+        # Link whose text will alter depending on whether or not they
+        # have a mute on the bug.
+        person = self.factory.makePerson()
+        with feature_flags():
+            with person_logged_in(person):
+                # If the user hasn't muted the bug, the link text will
+                # reflect this.
+                link = self.context_menu.mute_subscription()
+                self.assertEqual("Mute bug mail", link.text)
+                # Once the user has muted the bug, the link text will
+                # change.
+                self.bug.subscribe(
+                    person, person, level=BugNotificationLevel.NOTHING)
+                link = self.context_menu.mute_subscription()
+                self.assertEqual("Unmute bug mail", link.text)

=== modified file 'lib/lp/bugs/javascript/bugtask_index_portlets.js'
--- lib/lp/bugs/javascript/bugtask_index_portlets.js	2011-02-28 16:09:54 +0000
+++ lib/lp/bugs/javascript/bugtask_index_portlets.js	2011-03-09 14:18:16 +0000
@@ -247,6 +247,44 @@
 }
 
 /*
+ * Set up the handlers for the mute / unmute link.
+ */
+function setup_mute_link_handlers() {
+    if (LP.links.me === undefined) {
+        return;
+    }
+
+    setup_client_and_bug();
+    var mute_link = Y.one('.menu-link-mute_subscription');
+    var parent_node = mute_link.get('parentNode');
+    var is_subscribed = !parent_node.hasClass('subscribed-false');
+    var mute_subscription = new Y.lp.bugs.subscriber.Subscription({
+        link: mute_link,
+        spinner: Y.one('#mute-unmute-spinner'),
+        subscriber: new Y.lp.bugs.subscriber.Subscriber({
+            uri: LP.links.me,
+            subscriber_ids: subscriber_ids
+        })
+    });
+    mute_subscription.set(
+        'person', mute_subscription.get('subscriber'));
+    mute_link.addClass('js-action');
+    mute_link.on('click', function(e) {
+        e.halt();
+        mute_subscription.enable_spinner('Muting...');
+        if (! is_subscribed) {
+            mute_subscription.set(
+                'bug_notification_level', "Nothing");
+            mute_current_user(mute_subscription);
+        } else {
+            unmute_current_user(mute_subscription);
+        }
+        mute_subscription.disable_spinner();
+    });
+}
+
+
+/*
  * Initialize callbacks for subscribe/unsubscribe links.
  *
  * @method setup_subscription_link_handlers
@@ -615,7 +653,8 @@
         },
 
         parameters: {
-            person: Y.lp.client.get_absolute_uri(subscriber.get('escaped_uri')),
+            person: Y.lp.client.get_absolute_uri(
+                subscriber.get('escaped_uri')),
             suppress_notify: false,
             level: bug_notification_level
         }
@@ -691,6 +730,82 @@
 }
 
 /*
+ * Mute the current user via the LP API.
+ *
+ * @method mute_current_user
+ * @param subscription {Object} A Y.lp.bugs.subscribe.Subscription object.
+ */
+function mute_current_user(subscription) {
+    subscription.enable_spinner('Muting...');
+    var subscription_link = subscription.get('link');
+    var subscriber = subscription.get('subscriber');
+    var bug_notification_level = subscription.get('bug_notification_level');
+
+    var error_handler = new Y.lp.client.ErrorHandler();
+    error_handler.clearProgressUI = function () {
+        subscription.disable_spinner();
+    };
+    error_handler.showError = function (error_msg) {
+        Y.lp.app.errors.display_error(subscription_link, error_msg);
+    };
+
+    var config = {
+        on: {
+            success: function(client) {
+                subscription.disable_spinner('Unmute bug mail');
+                var flash_node = subscription_link.get('parentNode');
+                var anim = Y.lazr.anim.green_flash({ node: flash_node });
+                anim.run();
+            },
+
+            failure: error_handler.getFailureHandler()
+        },
+
+        parameters: {
+            person: Y.lp.client.get_absolute_uri(
+                subscriber.get('escaped_uri')),
+            suppress_notify: false,
+            level: bug_notification_level
+        }
+    };
+    lp_client.named_post(bug_repr.self_link, 'subscribe', config);
+}
+
+/*
+ * Unmute the current user via the LP API.
+ *
+ * @method unmute_current_user
+ * @param subscription {Object} A Y.lp.bugs.subscriber.Subscription object.
+ */
+function unmute_current_user(subscription) {
+    subscription.enable_spinner('Unmuting...');
+    var subscription_link = subscription.get('link');
+    var subscriber = subscription.get('subscriber');
+
+    var error_handler = new Y.lp.client.ErrorHandler();
+    error_handler.clearProgressUI = function () {
+        subscription.disable_spinner();
+    };
+    error_handler.showError = function (error_msg) {
+        Y.lp.app.errors.display_error(subscription_link, error_msg);
+    };
+
+    var config = {
+        on: {
+            success: function(client) {
+                subscription.disable_spinner('Mute bug mail');
+                var flash_node = subscription_link.get('parentNode');
+                var anim = Y.lazr.anim.green_flash({ node: flash_node });
+                anim.run();
+            },
+
+            failure: error_handler.getFailureHandler()
+        }
+    };
+    lp_client.named_post(bug_repr.self_link, 'unsubscribe', config);
+}
+
+/*
  * Initialize click handler for the subscribe someone else link.
  *
  * @method setup_subscribe_someone_else_handler

=== modified file 'lib/lp/bugs/templates/bug-portlet-subscribers.pt'
--- lib/lp/bugs/templates/bug-portlet-subscribers.pt	2011-02-15 17:45:45 +0000
+++ lib/lp/bugs/templates/bug-portlet-subscribers.pt	2011-03-09 14:18:16 +0000
@@ -31,7 +31,8 @@
         var subscription_link = Y.one('.menu-link-subscription');
         var subscription_link_handler;
         if (subscription_link) {
-            subscription_link_handler = subscription_link.on('click', function(e) {
+            subscription_link_handler = subscription_link.on(
+                'click', function(e) {
                 e.preventDefault();
             });
         }