diff --git a/README.md b/README.md index cf4e6ec..5314aa6 100644 --- a/README.md +++ b/README.md @@ -6,59 +6,3 @@ MediaWiki-WatchAnalytics Extension:WatchAnalytics identifies under-reviewed content on a wiki, helping users target weak points and improve accountability. See https://www.mediawiki.org/wiki/Extension:WatchAnalytics for more information - -## Config - -### egWatchAnalyticsPageCounter - -Description: TBD - -Default: false - -### egPendingReviewsEmphasizeDays - -Description: TBD - -Default: 7 - -### egPendingReviewsRedPagesThreshold - -Description: TBD - -Default: 2 - -### egPendingReviewsOrangePagesThreshold - -Description: TBD - -Default: 4 - -### egPendingReviewsNumberWatchSuggestions - -Description: TBD - -Default: 20 - -### egPendingReviewsShowWatchSuggestionsIfReviewsUnder - -Description: TBD - -Default: 5 - -### egWatchAnalyticsPageScoreNamespaces - -Description: TBD - -Default: Main namespace (NS_MAIN) and Talk namespace (NS_TALK) - -### egWatchAnalyticsWatchQualityColors - -Description: TBD - -Default: [5, 1.5] - -### egWatchAnalyticsReviewStatusColors - -Description: TBD - -Default: [4, 2] diff --git a/extension.json b/extension.json index 60cb981..5048cc2 100644 --- a/extension.json +++ b/extension.json @@ -211,8 +211,17 @@ "PendingReviewsNumberWatchSuggestions": 20, "PendingReviewsShowWatchSuggestionsIfReviewsUnder": 5, "WatchAnalyticsPageScoreNamespaces": [0, 1], - "WatchAnalyticsWatchQualityColors": [5, 1.5], - "WatchAnalyticsReviewStatusColors": [4, 2] + "WatchAnalyticsWatchQualityColors": { + "50" : "plaid", + "5" : "excellent", + "1.5" : "okay", + "_merge_strategy": "array_plus" + }, + "WatchAnalyticsReviewStatusColors": { + "5" : "excellent", + "3" : "okay", + "_merge_strategy": "array_plus" + } }, "manifest_version": 1 } diff --git a/i18n/en.json b/i18n/en.json index f4d53e3..42d931f 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -86,9 +86,9 @@ "pendingreviews-timediff-just-now": "Changed just now", "pendingreviews-no-revisions": "No page content changes", "pendingreviews-num-reviews": "You have $1 pending {{PLURAL:$1|review|reviews}}.", - "pendingreviews-reviewer-criticality-red": "Pages reviewed by {{PLURAL:$1|1 person|$1 people}} or fewer", - "pendingreviews-reviewer-criticality-orange": "Pages reviewed by {{PLURAL:$1|1 person|$1 people}} or fewer", - "pendingreviews-reviewer-criticality-green": "Pages reviewed by more than {{PLURAL:$1|1 person|$1 people}}", + "pendingreviews-reviewer-criticality-danger": "Pages reviewed by 0 - {{PLURAL:$1|1 person|$1 people}}", + "pendingreviews-reviewer-criticality-danger-zero": "Pages reviewed by 0 people", + "pendingreviews-reviewer-criticality-generic": "Pages reviewed by $1 or more people", "watch-analytics-page-score-tooltip": "Scores indicate how well this page is being reviewed", "watch-analytics-page-score-scrutiny-label": "Scrutiny", @@ -98,8 +98,8 @@ "watchanalytics-pagestats-editors-list-title": "Page editors", "watchanalytics-pagestats-editors-list-item": "$1 - {{PLURAL:$2|1 revision|$2 revisions}}", "watchanalytics-pagestats-watchers-title": "Page watchers", - "watchanalytics-pagestats-watchers-list-item-reviewed": "$1 - reviewed latest", - "watchanalytics-pagestats-watchers-list-item-unreviewed": "$1 - review pending", + "watchanalytics-pagestats-watchers-list-item-reviewed": "$1 - reviewed latest", + "watchanalytics-pagestats-watchers-list-item-unreviewed": "$1 - review pending", "watchanalytics-pagestats-chart-header": "Number of reviewers over time", "watchanalytics-unreview-button": "Defer review", diff --git a/includes/PageScore.php b/includes/PageScore.php index 59503eb..0d77765 100644 --- a/includes/PageScore.php +++ b/includes/PageScore.php @@ -20,13 +20,6 @@ class PageScore { public function __construct( Title $title ) { $this->mTitle = $title; - $this->cssColorClasses = [ - 'excellent', - // 'good', - 'okay', - // 'warning', - 'danger', - ]; } public static function noPageScore() { @@ -70,14 +63,14 @@ public function getNumReviews() { public function getScoreColor( $score, $configVariable ) { $scoreArr = $GLOBALS[ $configVariable ]; + krsort( $scoreArr, SORT_NUMERIC ); - $scoreArrCount = count( $scoreArr ); - for ( $i = 0; $i < $scoreArrCount; $i++ ) { // ) as $index => $upperBound - if ( $score > $scoreArr[ $i ] ) { - return $this->cssColorClasses[ $i ]; + foreach ( $scoreArr as $scoreThreshold => $style ) { + if ( $score >= $scoreThreshold ) { + return $style; } } - return $this->cssColorClasses[ count( $scoreArr ) ]; + return 'danger'; } public function getPageScoreTemplate() { @@ -110,7 +103,7 @@ public function getBadge( $label, $score, $color, $showLabel = false ) { $rightStyle = ""; } - return "
+ return "
$label
diff --git a/modules/base/ext.watchanalytics.base.css b/modules/base/ext.watchanalytics.base.css index 5de9353..6f242d1 100644 --- a/modules/base/ext.watchanalytics.base.css +++ b/modules/base/ext.watchanalytics.base.css @@ -12,4 +12,66 @@ .watch-analytics-watchers-needed-link { font-weight: bold; -} \ No newline at end of file +} + +.ext-watchanalytics-criticality-danger > div { + background-color: #d33; + border-color: #d33; + color: #fff; +} + +tr.ext-watchanalytics-criticality-danger td:first-child { + border-left: solid #d33 5px; +} + +.ext-watchanalytics-criticality-plaid > div { + background: + repeating-linear-gradient( + -45deg, + transparent 0%, + transparent 20%, + #d33 0, + #d33 50% + ), + repeating-linear-gradient( + 45deg, + transparent 0, + transparent 20%, + #00af89 0, + #00af89 50% + ), + repeating-linear-gradient( + transparent 0%, + transparent 20%, + #fc3 0, + #fc3 50% + ), white; + background-blend-mode: multiply; + background-size: 10px 10px; + color: #000; + text-shadow: + -1px -1px 0 #fff, + 1px -1px 0 #fff, + -1px 1px 0 #fff, + 1px 1px 0 #fff; +} + +.ext-watchanalytics-criticality-okay > div { + background-color: #fc3; + border-color: #fc3; + color: #fff; +} + +tr.ext-watchanalytics-criticality-okay td:first-child { + border-left: solid #fc3 5px; +} + +.ext-watchanalytics-criticality-excellent > div { + background-color: #00af89; + border-color: #00af89; + color: #fff; +} + +tr.ext-watchanalytics-criticality-excellent td:first-child { + border-left: solid #00af89 5px; +} diff --git a/modules/pagescores/pagescores.css b/modules/pagescores/pagescores.css index dfdf3f6..f5704a8 100644 --- a/modules/pagescores/pagescores.css +++ b/modules/pagescores/pagescores.css @@ -29,35 +29,9 @@ margin: 0; float: left; border-radius: 4px; - border-width: 1px; border-style: solid; -} - -.ext-watchanalytics-pagescores-danger > div { - background-color: #d33; - border-color: #d33; - color: white; -} -.ext-watchanalytics-pagescores-warning > div { - background-color: #fc3; - border-color: #fc3; - color: white; -} -.ext-watchanalytics-pagescores-okay > div { - background-color: khaki; - border-color: khaki; - color: #333; -} -.ext-watchanalytics-pagescores-good > div { - background-color: greenyellow; - border-color: greenyellow; - color: #333; -} -.ext-watchanalytics-pagescores-excellent > div { - background-color: #00af89; - border-color: #00af89; - color: white; + font-weight: bold; } .ext-watchanalytics-pagescores-left { @@ -65,13 +39,3 @@ color: #333 !important; display: none; } - - -/*#ext-watchanalytics-pagescores:hover .ext-watchanalytics-pagescores-left { - border-radius: 4px 0 0 4px; - display: inherit; -} -#ext-watchanalytics-pagescores:hover .ext-watchanalytics-pagescores-right { - border-radius: 0 4px 4px 0; -} -*/ diff --git a/modules/pendingreviews/ext.watchanalytics.pendingreviews.css b/modules/pendingreviews/ext.watchanalytics.pendingreviews.css index a4b0f46..71b6941 100644 --- a/modules/pendingreviews/ext.watchanalytics.pendingreviews.css +++ b/modules/pendingreviews/ext.watchanalytics.pendingreviews.css @@ -37,7 +37,6 @@ table.pendingreviews-list td.pendingreviews-top-cell { } tr.pendingreviews-row td:first-child { - border-left: solid #ddd 5px; padding-left: 5px; } /*tr.pendingreviews-row-hover td:first-child { @@ -50,16 +49,6 @@ tr.pendingreviews-row-hover td { background-color: #f9f9f9; } -tr.pendingreviews-criticality-red td:first-child { - border-left: solid #d33 5px; -} -tr.pendingreviews-criticality-orange td:first-child { - border-left: solid #fc3 5px; -} -tr.pendingreviews-criticality-green td:first-child { - border-left: solid #00af89 5px; -} - .pendingreviews-legend { float:right; margin-bottom: 10px; @@ -117,16 +106,6 @@ td.pendingreviews-review-links a:hover { border-color: #00af89; } -.pendingreviews-light-blue-button { - background-color: #eaf3ff; - border-color: #36c; -} - -.pendingreviews-light-blue-button:hover { - background-color: #36c; - border-color: #36c; -} - .pendingreviews-orange-button { background-color: #fc3; border-color: #fc3; @@ -189,5 +168,3 @@ a.pendingreviews-nav-link-inactive { a.pendingreviews-nav-link-inactive:visited { color: #c8ccd1; } - - diff --git a/specials/SpecialPendingReviews.php b/specials/SpecialPendingReviews.php index 3ce0107..e8cdc0f 100644 --- a/specials/SpecialPendingReviews.php +++ b/specials/SpecialPendingReviews.php @@ -113,6 +113,7 @@ public function execute( $parser = null ) { // functions causes the CSS to load later, which makes the page styles // apply late. This looks bad. $wgOut->addModuleStyles( [ + 'ext.watchanalytics.base', 'ext.watchanalytics.specials', 'ext.watchanalytics.pendingreviews.styles', ] ); @@ -336,14 +337,16 @@ public function getRowHTML( PendingReview $item, $rowCount, $displayTitle, $butt // FIXME: wow this is ugly $rowClass = ( $rowCount % 2 === 0 ) ? 'pendingreviews-even-row' : 'pendingreviews-odd-row'; - if ( $item->numReviewers > $GLOBALS['egPendingReviewsOrangePagesThreshold'] ) { - $reviewCriticality = 'green'; // page is "green" because it has lots of reviewers - } elseif ( $item->numReviewers > $GLOBALS['egPendingReviewsRedPagesThreshold'] ) { - $reviewCriticality = 'orange'; - } else { - $reviewCriticality = 'red'; // page is red because it has very few reviewers + $scoreArr = $GLOBALS['egWatchAnalyticsReviewStatusColors']; + // making sure array is sorted from highest to lowest + krsort( $scoreArr, SORT_NUMERIC ); + foreach ( $scoreArr as $scoreThreshold => $style ) { + if ( $item->numReviewers >= $scoreThreshold ) { + $reviewCriticalityClass = 'ext-watchanalytics-criticality-' . $style; + } else { + $reviewCriticalityClass = 'ext-watchanalytics-criticality-danger'; + } } - $reviewCriticalityClass = 'pendingreviews-criticality-' . $reviewCriticality; $classAndAttr = "class='pendingreviews-row $rowClass " . "$reviewCriticalityClass pendingreviews-row-$rowCount' " . @@ -609,29 +612,36 @@ public function getPageHeader( User $user ) { * @return string HTML for legend (table) */ public function getPendingReviewsLegend() { - $redMaxReviewers = $GLOBALS['egPendingReviewsRedPagesThreshold'] - 1; - $orangeMaxReviewers = $GLOBALS['egPendingReviewsOrangePagesThreshold'] - 1; - - $redReviewersMsg = $this->msg( - 'pendingreviews-reviewer-criticality-red', - $redMaxReviewers - )->text(); - - $orangeReviewersMsg = $this->msg( - 'pendingreviews-reviewer-criticality-orange', - $orangeMaxReviewers - )->text(); - - $greenReviewersMsg = $this->msg( - 'pendingreviews-reviewer-criticality-green', - $orangeMaxReviewers - )->text(); - - return " - - - -
$redReviewersMsg
$orangeReviewersMsg
$greenReviewersMsg
"; + $scoreArr = $GLOBALS['egWatchAnalyticsReviewStatusColors']; + // making sure array is sorted from highest to lowest + krsort( $scoreArr, SORT_NUMERIC ); + + $html = ""; + foreach ( $scoreArr as $scoreThreshold => $style ) { + $msg = $this->msg( + "pendingreviews-reviewer-criticality-generic", + $scoreThreshold + )->text(); + + $html .= ""; + } + + // bottom threshold will always be "danger" class + // Get lowest value in array + end( $scoreArr ); + $smallestThreshold = key( $scoreArr ); + + if ( $smallestThreshold == 1 ) { + $msg = $this->msg( "pendingreviews-reviewer-criticality-danger-zero" )->text(); + } else { + $msg = $this->msg( "pendingreviews-reviewer-criticality-danger", $smallestThreshold - 1 )->text(); + } + + $html .= ""; + + $html .= '
$msg
$msg
'; + + return $html; } /**