Mark pages on watchlist as visited using JS without reload
authorGeoffrey Mon <geofbot@gmail.com>
Sat, 10 Dec 2016 03:06:18 +0000 (22:06 -0500)
committerSn1per <geofbot@gmail.com>
Mon, 12 Dec 2016 20:00:06 +0000 (20:00 +0000)
When the "mark pages as visited" is clicked, a dialog appears,
asking for confirmation. On confirmation, an API request is sent
to mark all pages as visited, and all unvisited watchlist entries
are changed to appear visited.

Based on a userscript by User:NQ (from English Wikipedia)
https://en.wikipedia.org/wiki/User:NQ/WatchlistResetConfirm.js

Bug: T150045
Change-Id: I45fb02a1edc1b0331925e9a244a2455f86ad3886

includes/specials/SpecialWatchlist.php
languages/i18n/en.json
languages/i18n/qqq.json
resources/Resources.php
resources/src/mediawiki.special/mediawiki.special.watchlist.js

index 000eb39..85ac2de 100644 (file)
@@ -604,7 +604,8 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        $form .= Xml::openElement( 'form', [ 'method' => 'post',
                                'action' => $this->getPageTitle()->getLocalURL(),
                                'id' => 'mw-watchlist-resetbutton' ] ) . "\n" .
-                       Xml::submitButton( $this->msg( 'enotif_reset' )->text(), [ 'name' => 'dummy' ] ) . "\n" .
+                       Xml::submitButton( $this->msg( 'enotif_reset' )->text(),
+                               [ 'name' => 'mw-watchlist-reset-submit' ] ) . "\n" .
                        Html::hidden( 'reset', 'all' ) . "\n";
                        foreach ( $nondefaults as $key => $value ) {
                                $form .= Html::hidden( $key, $value ) . "\n";
index 2004e0f..0774b0f 100644 (file)
        "wlshowhidemine": "my edits",
        "wlshowhidecategorization": "page categorization",
        "watchlist-options": "Watchlist options",
+       "watchlist-mark-all-visited": "Are you sure you want to reset unseen watchlist changes by marking all pages as visited?",
        "watching": "Watching...",
        "unwatching": "Unwatching...",
        "watcherrortext": "An error occurred while changing your watchlist settings for \"$1\".",
index d292c72..e4cfb10 100644 (file)
        "wlshowhidemine": "Option text in [[Special:Watchlist]]. Cf. {{msg-mw|rcshowhidemine}}.",
        "wlshowhidecategorization": "Option text in [[Special:Watchlist]]. Cf. {{msg-mw|rcshowhidecategorization}}.",
        "watchlist-options": "Legend of the fieldset of [[Special:Watchlist]]\n\nSee also:\n* {{msg-mw|Watchlist-details|watchlist header}}\n* {{msg-mw|Wlheader-enotif|watchlist header}}\n* {{msg-mw|enotif reset|Submit button text}}",
+       "watchlist-mark-all-visited": "Dialog text in [[Special:Watchlist]] displayed for confirming whether the user wants to reset unseen watchlist changes by marking all pages as visited.",
        "watching": "Text displayed when clicked on the watch tab: {{msg-mw|Watch}}. It means the wiki is adding that page to your watchlist.",
        "unwatching": "Text displayed when clicked on the unwatch tab: {{msg-mw|Unwatch}}. It means the wiki is removing that page from your watchlist.",
        "watcherrortext": "When a user clicked the watch/unwatch tab and the action did not succeed, this message is displayed.\n\nThis message is used raw and should not contain wikitext.\n\nParameters:\n* $1 - ...\nSee also:\n* {{msg-mw|Addedwatchtext}}",
index 5c74186..4932a29 100644 (file)
@@ -2033,7 +2033,11 @@ return [
        ],
        'mediawiki.special.watchlist' => [
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.watchlist.js',
+               'messages' => 'watchlist-mark-all-visited',
                'dependencies' => [
+                       'mediawiki.api',
+                       'mediawiki.jqueryMsg',
+                       'oojs-ui-windows',
                        'user.options',
                ]
        ],
index 0be13a6..bfe2c1c 100644 (file)
@@ -1,8 +1,54 @@
 /*!
  * JavaScript for Special:Watchlist
  */
-( function ( mw, $ ) {
+( function ( mw, $, OO ) {
        $( function () {
+               var $resetForm = $( '#mw-watchlist-resetbutton' ),
+                       $progressBar = new OO.ui.ProgressBarWidget( { progress: false } ).$element;
+
+               $progressBar.css( {
+                       visibility: 'hidden',
+                       position: 'absolute',
+                       width: '100%'
+               } );
+               $resetForm.append( $progressBar );
+
+               // If the user wants to reset their watchlist, use an API call to do so (no reload required)
+               // Adapted from a user script by User:NQ of English Wikipedia
+               // (User:NQ/WatchlistResetConfirm.js)
+               $resetForm.submit( function ( event ) {
+                       event.preventDefault();
+
+                       OO.ui.confirm( mw.msg( 'watchlist-mark-all-visited' ) ).done( function ( confirmed ) {
+                               var $button;
+
+                               if ( confirmed ) {
+                                       // Disable reset button to prevent multiple requests and show progress bar
+                                       $button = $resetForm.find( 'input[name=mw-watchlist-reset-submit]' ).prop( 'disabled', true );
+                                       $progressBar.css( 'visibility', 'visible' );
+
+                                       // Use action=setnotificationtimestamp to mark all as visited,
+                                       // then set all watchlist lines accordingly
+                                       new mw.Api().postWithToken( 'csrf', {
+                                               formatversion: 2,
+                                               action: 'setnotificationtimestamp',
+                                               entirewatchlist: true
+                                       } ).done( function () {
+                                               $button.css( 'visibility', 'hidden' );
+                                               $progressBar.css( 'visibility', 'hidden' );
+                                               $( '.mw-changeslist-line-watched' )
+                                                       .removeClass( 'mw-changeslist-line-watched' )
+                                                       .addClass( 'mw-changeslist-line-not-watched' );
+                                       } ).fail( function () {
+                                               // On error, fall back to server-side reset
+                                               // First remove this submit listener and then re-submit the form
+                                               $resetForm.off( 'submit' ).submit();
+                                       } );
+
+                               }
+                       } );
+               } );
+
                // if the user wishes to reload the watchlist whenever a filter changes
                if ( mw.user.options.get( 'watchlistreloadautomatically' ) ) {
                        // add a listener on all form elements in the header form
@@ -13,4 +59,4 @@
                }
        } );
 
-}( mediaWiki, jQuery ) );
+}( mediaWiki, jQuery, OO ) );