Merge lp:~jcsackett/launchpad/spam-button-ui into lp:launchpad
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | j.c.sackett | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 13004 | ||||
Proposed branch: | lp:~jcsackett/launchpad/spam-button-ui | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
498 lines (+337/-24) 8 files modified
lib/lp/answers/browser/question.py (+4/-0) lib/lp/answers/browser/tests/test_questionmessages.py (+49/-20) lib/lp/answers/javascript/question_spam.js (+73/-0) lib/lp/answers/javascript/tests/test_question_spam.html (+80/-0) lib/lp/answers/javascript/tests/test_question_spam.js (+93/-0) lib/lp/answers/templates/question-index.pt (+11/-3) lib/lp/answers/templates/questionmessage-display.pt (+17/-1) lib/lp/testing/factory.py (+10/-0) |
||||
To merge this branch: | bzr merge lp:~jcsackett/launchpad/spam-button-ui | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gavin Panella (community) | Approve | ||
Review via email: mp+60072@code.launchpad.net |
Commit message
[r=allenap][bug=220535] Adds ui to questions allowing the removal of spam.
Description of the change
Summary
=======
Wouldn't it be nice, when on maintenance rotation, if you could kill spam comments from the UI?
Yeah. This does that for questions.
Less glibly: Previous work added API methods to hide comments on bugs and questions. These could only be accessed via scripts or other means of posting against the API. This branch adds a control (visible to admins and registry experts only) to the footer of messages on questions that allows you to mark the given message as spam via AJAX.
A subsequent branch will add this capability to bugs; that branch, or yet another, will also clean up any duplication that may occur in so doing.
Preimplementation
=================
Curtis Hovey: Implementation and troubleshooting.
Aaron Bentley: Issues with setting up javascript tests.
Implementation
==============
lib/lp/
-------
Created "makeAdmin" function so you can grab an admin without using sampledata (you routinely end up with ~foo.bar or ~mark via sampledata, and they have super privs.
lib/lp/
-------
Created view check to determine whether or not to show the spam controls.
lib/lp/
lib/lp/
-------
Added spam controls and javascript hookup.
lib/lp/
-------
Added javascript function which toggles the control between "Mark as spam" and "Mark as not spam", as well as toggles the display as a hidden or not hidden comment and fires off the postback to the API to set the message to hidden.
lib/lp/
-------
Tests for view changes.
lib/lp/
lib/lp/
-------
Tests for javascript.
Tests
=====
bin/test -vvct test_questionme
firefox lib/lp/
QA
==
Open a question with comments while logged in as an admin or registry expert.
Mark a message as spam via the control.
The message will switch to the "hidden" display and the control will change to "Mark as not spam."
Reload the page; the message will still be thusly marked.
Open the same question as anonymous or a user without priveleges (easiest to do in another browser).
The message marked as spam will not display.
Open the question again logged in as admin or registry expert.
Mark the spam message as not spam.
The message will switch to the not hidden display and the control will change to "Mark as spam."
Reload the page; the message will still be marked as not spam.
Open the same question as anon or no privs user; the message will be displayed.
Screenshots
===========
http://
Lint
====
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
This is an awesome feature, but I think the implementation needs a
little more work.
[1]
+ def canSeeSpamContr ols(self) : n('launchpad. Moderate' , self.context. question)
+ return check_permissio
This is going to be checked for every comment so consider making this
a cached property, or use an instance variable set in initialize()
instead.
[2]
+ <a tal:attributes="id string: mark-spam- ${index} ;" "context/ visible" >
+ class="js-action sprite edit mark-spam" href="#">
+ <tal:not-spam condition="not: context/visible">
+ Mark as not spam
+ </tal:not-spam>
+ <tal:spam condition=
+ Mark as spam
+ </tal:spam>
+ </a>
The text here is repeated in the Javascript:
+var spam_text = "Mark as spam";
+var not_spam_text = "Mark as not spam";
I don't mind if you leave it, but another pattern for doing this could
be:
<a tal:attributes="id string: mark-spam- ${index} ;"
class=" js-action sprite edit mark-spam" href="#">
<tal: not-spam condition="not: context/visible">
<span> Mark as not spam</span>
</tal: not-spam> "context/ visible" >
<span> Mark as spam</span>
</tal: spam>
<span class="unseen">Mark as spam</span>
<tal:spam condition=
<span class="unseen">Mark as not spam</span>
</a>
Then instead of changing the text you could change which span has the
unseen class:
function update_text(link) {
link.all( "span") .toggleClass( "unseen" );
}
[3]
+ var config = {
+ on: {
+ success: function () {},
+ failure: function () {}
+ },
Fishy!
+function toggle_ spam_setting( link) { 'parentNode' ).get(' parentNode' ); hasClass( 'adminHiddenCom ment'); link.get( 'id').replace( 'mark-spam- ', '')); _update_ text(link) ; toggleClass( hidden_ class); _set_visibility (comment_ number, visible);
+ var comment = link.get(
+ var visible = comment.
+ var comment_number = parseInt(
+ comment_number = comment_number - 1;
+ namespace.
+ comment.
+ namespace.
+}
The call to _update_text() and comment. toggleClass( ) should be done in
the success handler passed to named_post(). Also, they should not
toggle but set the UI according to the actual state in case the link
is clicked more than once in quick succession (so my suggestion in [2]
is not quite suitable).
Additionally there should probably be a Y.lazr. anim.red_ flash() on
failure (as this is an admin tool it's probably safe to not worry
about a more sophisticated error handler for now), and a green_flash()
on success.
[4]
+namespace. _update_ text = update_text _set_visibility = set_visibility
...
+namespace.
These are private functions and are not called outside of the module,
even for testing. You're probably better off not adding them to the
namespace.
[5]
+}, "0.1", {"requires": ["dom", "event-custom", "node", "lazr.effects",
+ "lp.client"]});
Are event-custom or lazr.effects used?
[6]
+function setup_spam_links() { toggle_ spam_setting( that);
+ Y.on('click', function(e) {
+ e.halt()
+ var that = this;
+ namespace.
+ }, '.mark-spam');
+}
I couldn't find docs...