Skip to content

Commit

Permalink
Adds diff to 'unreview' banner and Special:PendingReviews (#102)
Browse files Browse the repository at this point in the history
* add diff to unreview banner and "Special:PendingReviews"
  • Loading branch information
krisfield authored Mar 20, 2019
1 parent 924aa09 commit ecb9518
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 72 deletions.
4 changes: 3 additions & 1 deletion Hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,10 @@ public static function handleMagicWords( &$parser, &$text ) {
* @return bool
*/
public static function onPageViewUpdates( WikiPage $wikiPage, User $user ) {
global $wgRequest;
$title = $wikiPage->getTitle();
$reviewHandler = ReviewHandler::setup( $user, $title );
$isDiff = $wgRequest->getText( 'oldid' );
$reviewHandler = ReviewHandler::setup( $user, $title, $isDiff );

if ( $reviewHandler::pageIsBeingReviewed() ) {

Expand Down
3 changes: 3 additions & 0 deletions extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@
"config": {
"_prefix": "eg",
"WatchAnalyticsPageCounter": false,
"WatchAnalyticsShowUnreviewDiff": true,
"PendingReviewMaxDiffChar": 3500,
"PendingReviewMaxDiffRows": 15,
"PendingReviewsEmphasizeDays": 7,
"PendingReviewsRedPagesThreshold": 2,
"PendingReviewsOrangePagesThreshold": 4,
Expand Down
4 changes: 3 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"watchanalytics-watch-forcegraph-description": "Orange dots represent users. Blue dots represent pages. Lines between the dots represent the user being a watcher of the page. Lines are gray if the latest page revision has been reviewed. Lines are red if reviews are pending. Move your mouse over a dot to see the user or page name.",
"watchanalytics-pause-visualization": "Pause visualization",
"watchanalytics-unpause-visualization": "Unpause visualization",
"watchanalytics-pendingreviews-diff-revisions": "Display {{PLURAL:$1|1 change|$1 changes}} since last visit",
"watchanalytics-pendingreviews-diff-revisions": "View {{PLURAL:$1|change|$1 changes}} on page",
"watchanalytics-view-and-approve": "View/Approve changes",
"watchanalytics-pendingreviews-users-first-view": "New page - view latest",
"watchanalytics-pendingreviews-history-link": "view page history",
Expand Down Expand Up @@ -109,6 +109,7 @@
"watchanalytics-pagestats-chart-header": "Number of reviewers over time",

"watchanalytics-unreview-button": "Defer review",
"watchanalytics-accept-change-close-banner": "Close banner",
"watchanalytics-unreview-banner-text": "'''Page reviewed!''' By navigating to this page you have marked it reviewed. If you did not want to review the page you may un-review it to save it for another time.",
"watchanalytics-unreview-complete": "'''This page has been un-reviewed''' and is again in your [[Special:PendingReviews|Pending Reviews]].",

Expand All @@ -125,6 +126,7 @@
"pendingreviews-accept-deletion": "Accept deletion",
"pendingreviews-accept-move-without-redirect": "Accept move without redirect",
"pendingreviews-accept-redirect": "Accept redirect",
"pendingreviews-accept-change": "Mark reviewed",
"pendingreviews-clear-page-notification": "Page \"$1\" has been marked reviewed. Return to $2",
"pendingreviews-log-approved": "[[$1]] approved a revision",
"pendingreviews-log-unapproved": "[[$1]] removed all revision approvals",
Expand Down
107 changes: 87 additions & 20 deletions includes/PendingReview.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use MediaWiki\MediaWikiServices;

class PendingReview {

/**
Expand Down Expand Up @@ -73,13 +75,17 @@ public function __construct( $row, Title $title = null ) {

$dbr = wfGetDB( DB_REPLICA );

$revisionStore = MediaWikiServices::getInstance()->getRevisionStore();

$revQueryInfo = $revisionStore->getQueryInfo();

$revResults = $dbr->select(
[ 'r' => 'revision' ],
Revision::getQueryInfo()['fields'],
"r.rev_page=$pageID AND r.rev_timestamp>=$notificationTimestamp",
$revQueryInfo['tables'],
$revQueryInfo['fields'],
"rev_page=$pageID AND rev_timestamp>=$notificationTimestamp",
__METHOD__,
[ 'ORDER BY' => 'rev_timestamp ASC' ],
null
$revQueryInfo['joins']
);
$revsPending = [];
while ( $rev = $revResults->fetchObject() ) {
Expand Down Expand Up @@ -191,34 +197,95 @@ public static function getPendingReviewsList( User $user, $limit, $offset ) {
return $pending;
}

public function getDeletionLog( $title, $ns, $notificationTimestamp ) {
public static function getPendingReview( User $user, Title $title ) {
$tables = [
'w' => 'watchlist',
'p' => 'page',
'log' => 'logging',
];

$fields = [
'p.page_id AS page_id',
'log.log_action AS log_action',
'w.wl_namespace AS namespace',
'w.wl_title AS title',
'w.wl_notificationtimestamp AS notificationtimestamp',
'(SELECT COUNT(*) FROM watchlist AS subwatch
WHERE
subwatch.wl_namespace = w.wl_namespace
AND subwatch.wl_title = w.wl_title
AND subwatch.wl_notificationtimestamp IS NULL
) AS num_reviewed',
];

$conds = [ 'w.wl_user' => $user->getId() , 'p.page_id' => $title->getArticleID() , 'w.wl_notificationtimestamp IS NOT NULL' ];

$options = [];

$join_conds = [
'p' => [
'LEFT JOIN', 'p.page_namespace=w.wl_namespace AND p.page_title=w.wl_title'
],
'log' => [
'LEFT JOIN',
'log.log_namespace = w.wl_namespace '
. ' AND log.log_title = w.wl_title'
. ' AND p.page_namespace IS NULL'
. ' AND p.page_title IS NULL'
. ' AND log.log_action IN ("delete","move")'
],
];

$dbr = wfGetDB( DB_REPLICA );

$watchResult = $dbr->select(
$tables,
$fields,
$conds,
__METHOD__,
$options,
$join_conds
);

$pending = [];

while ( $row = $dbr->fetchRow( $watchResult ) ) {

$pending[] = new self( $row );

}
return $pending;
}

public function getDeletionLog( $title, $ns, $notificationTimestamp ) {
$dbr = wfGetDB( DB_REPLICA );
$title = $dbr->addQuotes( $title );

// pages are deleted when (a) they are explicitly deleted or (b) they
// are moved without leaving a redirect behind.
$logResults = $dbr->select(
[ 'l' => 'logging' ],
[ 'l' => 'logging', 'c' => 'comment' ],
[
'log_id',
'log_type',
'log_action',
'log_timestamp',
'log_user',
'log_user_text',
'log_namespace',
'log_title',
'log_page',
'log_comment',
'log_params',
'log_deleted',
'l.log_id',
'l.log_type',
'l.log_action',
'l.log_timestamp',
'l.log_user',
'l.log_user_text',
'l.log_namespace',
'l.log_title',
'l.log_page',
'l.log_comment_id',
'l.log_params',
'l.log_deleted',
'c.comment_id',
'c.comment_text AS log_comment'
],
"l.log_title=$title AND l.log_namespace=$ns AND l.log_timestamp>=$notificationTimestamp
AND l.log_type IN ('delete','move')",
__METHOD__,
[ 'ORDER BY' => 'log_timestamp ASC' ],
null
[ 'ORDER BY' => 'l.log_timestamp ASC' ],
[ 'c' => [ 'INNER JOIN', [ 'l.log_comment_id=c.comment_id' ] ] ]
);
$logDeletes = [];
while ( $log = $logResults->fetchObject() ) {
Expand Down
80 changes: 68 additions & 12 deletions includes/ReviewHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ class ReviewHandler {
*/
public $final = null;

public function __construct( User $user, Title $title ) {
public function __construct( User $user, Title $title, $isDiff ) {
$this->user = $user;
$this->title = $title;
$this->isDiff = $isDiff;
}

public static function setup( User $user, Title $title ) {
public static function setup( User $user, Title $title, $isDiff ) {
if ( ! $title->isWatchable() ) {
self::$isReviewable = false;
return false;
}
self::$pageLoadHandler = new self ( $user, $title );
self::$pageLoadHandler = new self ( $user, $title, $isDiff );
self::$pageLoadHandler->initial = self::$pageLoadHandler->getReviewStatus();
return self::$pageLoadHandler;
}
Expand Down Expand Up @@ -116,20 +117,75 @@ public static function pageIsBeingReviewed() {
public function getTemplate() {
// $msg = wfMessage( 'watch-analytics-page-score-tooltip' )->text();

$unReviewLink = SpecialPage::getTitleFor( 'PageStatistics' )->getInternalURL( [
'page' => $this->title->getPrefixedText(),
'unreview' => $this->initial
] );
$reviewLink = Xml::element(
'a',
[
'href' => null,
'id' => 'watch-analytics-unreview',
'class' => 'pendingreviews-green-button pendingreviews-accept-change',
],
wfMessage( 'watchanalytics-accept-change-close-banner' )->text()
);

$unReviewLink = Xml::element(
'a',
[
'href' => null,
'id' => 'watch-analytics-unreview',
'class' => 'watch-analytics-unreview',
'timestamp' => $this->initial,
'pending-title' => $this->title->getPrefixedText(),
'title' => wfMessage( 'watchanalytics-unreview-button' )->text(),
],
wfMessage( 'watchanalytics-unreview-button' )->text()
);

$linkText = wfMessage( 'watchanalytics-unreview-button' )->text();
$bannerText = wfMessage( 'watchanalytics-unreview-banner-text' )->parse();

// when MW 1.25 is released (very soon) replace this with a mustache template
$this->pendingReview = PendingReview::getPendingReview( $this->user, $this->title );

foreach ( $this->pendingReview as $item ) {
if ( count( $item->newRevisions ) > 0 ) {

// returns essentially the negative-oneth revision...the one before
// the wl_notificationtimestamp revision...or null/false if none exists?
$mostRecentReviewed = Revision::newFromRow( $item->newRevisions[0] )->getPrevious();
} else {
$mostRecentReviewed = false; // no previous revision, the user has not reviewed the first!
}

if ( $mostRecentReviewed ) {

$lastSeenId = $mostRecentReviewed->getId();

} else {

$latest = Revision::newFromTitle( $item->title );
$lastSeenId = $latest->getId();

}

}

$diff = new DifferenceEngine( null, $lastSeenId, 0 );

$template =
"<div id='watch-analytics-review-handler'>
<a id='watch-analytics-unreview' href='$unReviewLink'>$linkText</a>
<p>$bannerText</p>
</div>";
$unReviewLink $reviewLink
<p>$bannerText</p>";

global $egWatchAnalyticsShowUnreviewDiff;
if ( $egWatchAnalyticsShowUnreviewDiff ) {
// Don't show diff on in header while viewing diff page
if ( !( $this->isDiff ) ) {
$template .= "<div id='diff-box'>";
$template .= $diff->showDiffStyle();
$template .= $diff->getDiff( '<b>Last seen</b>', '<b>Current</b>' );
$template .= "</div>";
}
}

$template .= "</div>";

return "<script type='text/template' id='ext-watchanalytics-review-handler-template'>$template</script>";
}
Expand Down
16 changes: 13 additions & 3 deletions modules/base/ext.watchanalytics.base.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@
color: #fff;
}

tr.ext-watchanalytics-criticality-danger td:first-child {
tr.ext-watchanalytics-criticality-danger, td.ext-watchanalytics-criticality-danger{
border-left: solid #d33 5px;
}

.pending-review-diff{
padding: 8px 20px;
background-color: #fff;
border-radius: 4px;
margin: 0 0 20px 0;
border-style: solid;
border-width: 1px;
border-color: #eaecf0;
}

.ext-watchanalytics-criticality-plaid > div {
background:
repeating-linear-gradient(
Expand Down Expand Up @@ -62,7 +72,7 @@ tr.ext-watchanalytics-criticality-danger td:first-child {
color: #fff;
}

tr.ext-watchanalytics-criticality-okay td:first-child {
tr.ext-watchanalytics-criticality-okay, td.ext-watchanalytics-criticality-okay {
border-left: solid #fc3 5px;
}

Expand All @@ -72,7 +82,7 @@ tr.ext-watchanalytics-criticality-okay td:first-child {
color: #fff;
}

tr.ext-watchanalytics-criticality-excellent td:first-child {
tr.ext-watchanalytics-criticality-excellent, td.ext-watchanalytics-criticality-excellent {
border-left: solid #00af89 5px;
}

Expand Down
12 changes: 10 additions & 2 deletions modules/pendingreviews/ext.watchanalytics.pendingreviews.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,23 @@ td.pendingreviews-review-links a:hover {
}

.pendingreviews-green-button {
background-color: #00af89;
background-color: #14866d;
border-color: #00af89;
}

.pendingreviews-green-button:hover {
background-color: #14866d;
background-color: #116f5a;
border-color: #00af89;
}

.pendingreviews-green-button.pendingreviews-accept-change {
background-color: #00af89;
}

.pendingreviews-green-button.pendingreviews-accept-change:hover {
background-color: #14866d;
}

.pendingreviews-orange-button {
background-color: #fc3;
border-color: #fc3;
Expand Down
Loading

0 comments on commit ecb9518

Please sign in to comment.