Utente:Valcio/Script/WatchUsers.js

Questa pagina definisce alcuni parametri di aspetto e comportamento generale di tutte le pagine. Per personalizzarli vedi Aiuto:Stile utente.


Nota: dopo aver salvato è necessario pulire la cache del proprio browser per vedere i cambiamenti (per le pagine globali è comunque necessario attendere qualche minuto). Per Mozilla / Firefox / Safari: fare clic su Ricarica tenendo premuto il tasto delle maiuscole, oppure premere Ctrl-F5 o Ctrl-R (Command-R su Mac); per Chrome: premere Ctrl-Shift-R (Command-Shift-R su un Mac); per Konqueror: premere il pulsante Ricarica o il tasto F5; per Opera può essere necessario svuotare completamente la cache dal menù Strumenti → Preferenze; per Internet Explorer: mantenere premuto il tasto Ctrl mentre si preme il pulsante Aggiorna o premere Ctrl-F5.

 /**
 * Questo accessorio aggiunge alla lista degli osservati speciali
 * le modifiche effettuate dagli "Utenti osservati", assieme a 
 * relative interfacce per gestire tale lista.
 * 
 * @author https://it.wikipedia.org/wiki/Utente:Valcio and contributors
 * 
 * Molte funzioni sono state ispirate e riadattate da https://it.wikipedia.org/wiki/MediaWiki:Gadget-CatWatch.js
 * 
 */
 /* global mediaWiki, jQuery, OO */
( function ( mw, $ ) {
	'use strict';
	
	var windowManager;
	var oojs_dependencies = ["oojs-ui-widgets", "oojs-ui-core", "oojs-ui.styles.icons-interactions", "oojs-ui.styles.icons-user", "oojs-ui-windows"];

	var conf = mw.config.get( [
		'wgPageTitle', 'wgUserGroups', 'wgCanonicalSpecialPageName' 
	] );
	
	/**
	 * Definizione prompt impostazioni
	 */
		 
	function MenuDialog( config ) {
		MenuDialog.super.call( this, config );
	}
	if ( typeof OO === 'undefined' || typeof OO.ui === 'undefined' || typeof OO.ui.ProcessDialog === 'undefined' ) {
		mw.log.error('Missing dependency, perhaps?');
		return;
	}
	OO.inheritClass( MenuDialog, OO.ui.ProcessDialog );
	
	MenuDialog.static.name = 'menuDialog';
	
	//Actions
	MenuDialog.static.actions = [
		{ 
			flags: 'primary', 
			label: 'Salva', 
			action: 'save' 
		},
		{ 
			flags: 'safe', 
			label: 'Annulla' 
		 }
	];
	
	// Layout
	MenuDialog.prototype.initialize = function () {
		MenuDialog.super.prototype.initialize.call( this );
		this.panel = new OO.ui.PanelLayout( { 
			padded: true, 
			expanded: false 
		} );
		this.content = new OO.ui.FieldsetLayout();
	
		this.userInput = new OO.ui.TagMultiselectWidget( {
			placeholder: 'Aggiungi utenti da osservare',
			allowArbitrary: true,
			inputPosition: 'outline'
		} );
	
		this.field = new OO.ui.FieldLayout( this.userInput, { 
			label: 'Utenti osservati',
			help: "Tutte le modifiche degli utenti che inserisci in questa lista verranno mostarte nei tuoi Osservati Speciali. Per inserire un nuovo utente, digita il suo nome (senza 'Utente:') e premi 'invio'.",
			warnings:["Questa lista è privata, altri utenti non potranno visualizzarla", "Ricordati di premere il pulsante 'Salva'"],
			align: 'top' 
		} );
	
		this.content.addItems( [ this.field ] );
		this.panel.$element.append( this.content.$element );
		this.$body.append( this.panel.$element );
	};
	
	MenuDialog.prototype.getBodyHeight = function () {
		return this.panel.$element.outerHeight( true );
	};
	
	MenuDialog.prototype.getSetupProcess = function ( data ) {
		data = data || {};
		return MenuDialog.super.prototype.getSetupProcess.call( this, data )
		.next( function () {
			if ( mw.user.options.exists( 'userjs-gadget-watch-users' ) )
				this.userInput.setValue( mw.user.options.get( 'userjs-gadget-watch-users' ).split("|") );
		}, this );
	};
	
	//Handle actions
	MenuDialog.prototype.getActionProcess = function ( action ) {
		var dialog = this;
		if ( action === 'save' ) {
			return new OO.ui.Process( function () {
				new mw.Api().postWithToken( 'csrf', {
					action: 'options',
					optionname: 'userjs-gadget-watch-users',
					optionvalue: this.userInput.getValue()
				} ).done(function(){dialog.close(); location.reload();});
			}, this );
		}
		return MenuDialog.super.prototype.getActionProcess.call( this, action );
	};

	/**
	 * Funzione di utilità per parseWatchlistDOM, crea un timestamp
	 * a partire da una data nel formato di OsservatiSpeciali, es. 1 gen 2012.
	 */
	function makeTimestamp( text ) {
		var months, month, date = text.split( ' ' );
		months = msg( 'monthNames' );
		month = months.indexOf( date[ 1 ] );
		return month !== -1 ? ( date[ 2 ] + '-' + padleft0( month ) + '-' + padleft0( parseInt( date[ 0 ], 10 ) ) + 'T00:00:00Z' ) : null;
	}


	/**
	 * Parsifica l'elenco di pagine di OsservatiSpeciali in un object con
	 * - chiavi: le date presenti nella pagina
	 * - valori: un object contenente l'ora e l'elemento jQuery per quella riga
	 *
	 * @return {object} Object che contiene le pagine in OS, suddivise per data e ora
	 */
	function parseWatchlistDOM() {
		var date, ret = {};
		// ogni giorno è un <h4> 
		$( 'h4' ).each( function () {
			date = $( this ).text();
			ret[ date ] = [];
			// la pagina di ogni giorno è un <li> in un <ul class='special'>
			$( this ).next( 'ul.special' ).find( 'li.mw-changeslist-line' ).each( function () {
				ret[date].push( {
					time: $( this ).find( 'span.mw-changeslist-date' ).text(),
					el: $( this )
				} );
			} );
			// retrocompatibilità con il vecchio CatWatch: con la vista raggruppata
			// visualizzava le pagine del CatWatch al fondo del giorno
			if ( ret[ date ].length === 0 ) {
				ret[ date ].push( {
					time: '23:59',
					el: $( this ).next( 'div' ).find( 'table:last-child()' )
				} );
			}
		} );
		ret.oldestDate = date ? makeTimestamp( date ) : null;

		return ret;
	}

	/**
	 * Formatta un numero con uno zero iniziale se minore di 10.
	 *
	 * @param {string} num - Il numero da formattare
	 * @return {string} La stringa risultante
	 */
	function padleft0( num ) {
		return ( num < 10 ? '0' : '' ) + num;
	}
	
	var i18n = {
		en : {
			errorGet: 'Error retrieving',
			msgConfig: 'Category watchlist not found. Do you want to create a new one?',
			monthNames: [ "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
			category: 'Category'
		},
		it : {
			errorGet: 'Errore nel leggere',
			msgConfig: 'Non hai ancora una lista di categorie da controllare. Vuoi crearne una?',
			monthNames: ["","gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic"],
			category: 'Categoria' 
		}
	};

	/**
	 * Restituisce il messaggio con un certo identificativo, in una delle lingue supportate.
	 *
	 * @param {string} key - L'identificativo del messaggio
	 * @return {string} Il messaggio nella lingua configurata
	 */
	function msg( key ) {
		var msgs = i18n[ mw.config.get( 'wgUserLanguage' ) ] || i18n.en;
		return msgs[ key ];
	}

	/**
	 * Funzione di utilità per watchlistAdd, parsifica un timestamp in date (1 gen 2001) e time (01:23).
	 *
	 * @param {string} timestamp - Timestamp da parsificare
	 * @return {object} Oggetto con date e time parsificati separatamente
	 */
	function parseTimestamp( timestamp ) {
		var date, hours, minutes, months;

		date = new Date( timestamp );
		hours = date.getHours();
		minutes = date.getMinutes();
		months = msg( 'monthNames' );
		return {
			date: date.getDate() + ' ' + months[ date.getMonth() + 1 ] + ' ' +
				  date.getFullYear(),
			time: padleft0( hours ) + ':' + padleft0( minutes )
		};
	}

	/**
	 * Funzione di utilità per watchlistAdd, crea un nuovo elemento di OsservatiSpeciali.
	 */
	function createWatchlistEl( user, revid, title, time, comment, newpage, minor, size ) {
		var url, $cron, $diff, $page, $newpageindicator, $minoreditindicator, $byte, $user, $usertalk, $usercontribs, $comment, sizeClass;
		url = mw.config.get( 'wgScript' ) + '?title=' + title;
		if(size>0){
			size="+"+size.toString();
			sizeClass="pos";
		}else if (size<0)
			sizeClass="neg";
		else
			sizeClass="null";
		
		if (newpage) {
			$diff = $('<span>').attr("class", "mw-changeslist-diff").text('diff');
			$newpageindicator = $('<abbr>').attr("class", "newpage").text("N");
		} else {
			$diff = $( '<a>' ).attr( 'href', url + '&diff='+revid ).text( 'diff' );
		}
		
		if(minor)
			$minoreditindicator = $('<abbr>').attr("class", "minoredit").text("m");
		
		$cron = $( '<a>' ).attr( 'href', url + '&action=history' ).text( 'cron' );
		$page = $( '<a>' ).attr( 'href', '/wiki/'+title ).text( title );
		$byte = $("<span>").attr("dir", "ltr").attr("class", "mw-plusminus-"+sizeClass+" mw-diff-bytes").text(size);
		$user = $( '<a>' ).attr( 'href', '/wiki/User:'+user).text( user ).css('font-weight', 'bold');
		$usertalk = $( '<a>' ).attr( 'href', '/wiki/User talk:'+user).text( "discussione" );
		$usercontribs = $( '<a>' ).attr( 'href', '/wiki/Special:Contributions/'+user).text( "contributi" );
		$comment = $("<span>").attr("class", "comment").text("("+comment+")");
		return $( '<li>' ).append( '(', $diff ,' | ', $cron, ') . . ', $newpageindicator, $minoreditindicator,"&nbsp;", $page, '; ', time,
						 '  . . ', $byte, ' . . ', $user, "&nbsp;(", $usertalk, "&nbsp;|&nbsp;", $usercontribs, ")&nbsp;", $comment );
	}

	/**
	 * Aggiunge una pagina ad OsservatiSpeciali, se quel giorno è visualizzato.
	 */
	function watchlistAdd( watchlist, edit ) {
		var ts, el, daypages, prepended = false;

		ts = parseTimestamp( edit.timestamp );
		daypages = watchlist[ ts.date ];
		if ( daypages ) {
			el = createWatchlistEl( edit.user, edit.revid, edit.title, ts.time, edit.comment, edit.new, edit.minor, edit.sizediff );
			// per tutte le pagine di quel giorno cerca quella col time antecedente 
			$.each( daypages, function ( i, entry ) {
				if ( ts.time > entry.time ) {
					entry.el.before( el );
					daypages.splice( i, 0, { time: ts.time, el: el } );
					prepended = true;
					return false;
				}
			} );
			if ( !prepended ) {
				daypages[ daypages.length - 1 ].el.after( el );
				daypages.push( { time: ts.time, el: el } );
			}
		}
	}
	
	$( function () {
		if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Watchlist' ) {
			// Load watched edits
			mw.loader.using(["mediawiki.api", "mediawiki.util"]).done(function(){
				//Generate starting timestamp
				var d=new Date();
				d. setDate(d. getDate() - 3);
				var monthNumber=d.getMonth()+1;
				if (monthNumber<10)
					monthNumber="0"+monthNumber.toString();
				var dayNumber=d.getDate();
				if (dayNumber<10)
					dayNumber="0"+dayNumber.toString();
				var startTimestamp=d.getFullYear()+"-"+monthNumber+"-"+dayNumber+"T00:00:00.000Z";
				
				//Generate watchlist items
				if ( mw.user.options.exists( 'userjs-gadget-watch-users' ) ) {
					var params = {
						action: 'query',
						format: 'json',
						list: 'usercontribs',
						uclimit: "max",
						formatversion: "2",
						ucdir: "newer",
						ucstart: startTimestamp,
						ucprop: "sizediff|tags|timestamp|title|comment|ids|flags",
						ucuser: mw.user.options.get( 'userjs-gadget-watch-users' )
					},
					api = new mw.Api();
					
					api.get( params ).done( function ( data ) {
						var usercontrib = data.query.usercontribs;
						for ( var uc in usercontrib ) {
							watchlistAdd(parseWatchlistDOM(), usercontrib[uc]);
						}
					} );
				}
			});
			
			// Load settings interface
			mw.loader.using( oojs_dependencies ).done( function () {
				if ( !windowManager ) {
					windowManager = new OO.ui.WindowManager();
					$( document.body ).append( windowManager.$element );
					//var dialog = require( './WatchUsers-MenuDialog.js' );
					//windowManager.addWindows( [ new dialog() ] )
					windowManager.addWindows( [ new MenuDialog() ] );
				}

				// Create watched users button
				var editOptionsBtn = new OO.ui.ButtonWidget( {
					label: 'Utenti osservati',
					icon: 'userContributions'
				} );
				editOptionsBtn.$element.click(function(){
					windowManager.openWindow( "menuDialog" );
				});
				$(".mw-rcfilters-ui-watchlistTopSectionWidget-watchlistDetails").parent().parent().append(editOptionsBtn.$element);
			});
		}
	});
} )( mediaWiki, jQuery );