X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=resources%2Fsrc%2Fmediawiki.rcfilters%2Fmw.rcfilters.Controller.js;h=a9283b9166be34a7c53f05c6ead74ee1ee84cbe1;hb=12b7a7ea555ff4bda637b60f28e069a3b22873f4;hp=ebf22014c8d2bedbb95dad6bc15a82ce6311f58a;hpb=9def51e9d63bf0031bb6ef94ee5ab8b8846bd1e4;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js index ebf22014c8..a9283b9166 100644 --- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js +++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js @@ -15,6 +15,8 @@ this.baseFilterState = {}; this.uriProcessor = null; this.initializing = false; + + this.prevLoggedItems = []; }; /* Initialization */ @@ -29,11 +31,62 @@ */ mw.rcfilters.Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList ) { var parsedSavedQueries, + views = {}, + items = [], uri = new mw.Uri(), $changesList = $( '.mw-changeslist' ).first().contents(); + // Prepare views + if ( namespaceStructure ) { + items = []; + $.each( namespaceStructure, function ( namespaceID, label ) { + // Build and clean up the individual namespace items definition + items.push( { + name: namespaceID, + label: label || mw.msg( 'blanknamespace' ), + description: '', + identifiers: [ + ( namespaceID < 0 || namespaceID % 2 === 0 ) ? + 'subject' : 'talk' + ], + cssClass: 'mw-changeslist-ns-' + namespaceID + } ); + } ); + + views.namespaces = { + title: mw.msg( 'namespaces' ), + trigger: ':', + groups: [ { + // Group definition (single group) + name: 'namespace', // parameter name is singular + type: 'string_options', + title: mw.msg( 'namespaces' ), + labelPrefixKey: { 'default': 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' }, + separator: ';', + fullCoverage: true, + filters: items + } ] + }; + } + if ( tagList ) { + views.tags = { + title: mw.msg( 'rcfilters-view-tags' ), + trigger: '#', + groups: [ { + // Group definition (single group) + name: 'tagfilter', // Parameter name + type: 'string_options', + title: 'rcfilters-view-tags', // Message key + labelPrefixKey: 'rcfilters-tag-prefix-tags', + separator: '|', + fullCoverage: false, + filters: tagList + } ] + }; + } + // Initialize the model - this.filtersModel.initializeFilters( filterStructure, namespaceStructure, tagList ); + this.filtersModel.initializeFilters( filterStructure, views ); this._buildBaseFilterState(); @@ -170,6 +223,9 @@ this.filtersModel.toggleFilterSelected( filterName, false ); this.updateChangesList(); this.filtersModel.reassessFilterInteractions( filterItem ); + + // Log filter grouping + this.trackFilterGroupings( 'removefilter' ); } if ( isHighlighted ) { @@ -220,6 +276,42 @@ this._trackHighlight( 'clear', filterName ); }; + /** + * Enable or disable live updates. + * @param {boolean} enable True to enable, false to disable + */ + mw.rcfilters.Controller.prototype.toggleLiveUpdate = function ( enable ) { + if ( enable && !this.liveUpdateTimeout ) { + this._scheduleLiveUpdate(); + } else if ( !enable && this.liveUpdateTimeout ) { + clearTimeout( this.liveUpdateTimeout ); + this.liveUpdateTimeout = null; + } + }; + + /** + * Set a timeout for the next live update. + * @private + */ + mw.rcfilters.Controller.prototype._scheduleLiveUpdate = function () { + this.liveUpdateTimeout = setTimeout( this._doLiveUpdate.bind( this ), 3000 ); + }; + + /** + * Perform a live update. + * @private + */ + mw.rcfilters.Controller.prototype._doLiveUpdate = function () { + var controller = this; + this.updateChangesList( {}, true ) + .always( function () { + if ( controller.liveUpdateTimeout ) { + // Live update was not disabled in the meantime + controller._scheduleLiveUpdate(); + } + } ); + }; + /** * Save the current model state as a saved query * @@ -325,6 +417,9 @@ this.filtersModel.reassessFilterInteractions(); this.updateChangesList(); + + // Log filter grouping + this.trackFilterGroupings( 'savedfilters' ); } }; @@ -504,11 +599,15 @@ * Update the list of changes and notify the model * * @param {Object} [params] Extra parameters to add to the API call + * @param {boolean} [isLiveUpdate] Don't update the URL or invalidate the changes list + * @return {jQuery.Promise} Promise that is resolved when the update is complete */ - mw.rcfilters.Controller.prototype.updateChangesList = function ( params ) { - this._updateURL( params ); - this.changesListModel.invalidate(); - this._fetchChangesList() + mw.rcfilters.Controller.prototype.updateChangesList = function ( params, isLiveUpdate ) { + if ( !isLiveUpdate ) { + this._updateURL( params ); + this.changesListModel.invalidate(); + } + return this._fetchChangesList() .then( // Success function ( pieces ) { @@ -711,4 +810,51 @@ ); }; + /** + * Track filter grouping usage + * + * @param {string} action Action taken + */ + mw.rcfilters.Controller.prototype.trackFilterGroupings = function ( action ) { + var controller = this, + rightNow = new Date().getTime(), + randomIdentifier = String( mw.user.sessionId() ) + String( rightNow ) + String( Math.random() ), + // Get all current filters + filters = this.filtersModel.getSelectedItems().map( function ( item ) { + return item.getName(); + } ); + + action = action || 'filtermenu'; + + // Check if these filters were the ones we just logged previously + // (Don't log the same grouping twice, in case the user opens/closes) + // the menu without action, or with the same result + if ( + // Only log if the two arrays are different in size + filters.length !== this.prevLoggedItems.length || + // Or if any filters are not the same as the cached filters + filters.some( function ( filterName ) { + return controller.prevLoggedItems.indexOf( filterName ) === -1; + } ) || + // Or if any cached filters are not the same as given filters + this.prevLoggedItems.some( function ( filterName ) { + return filters.indexOf( filterName ) === -1; + } ) + ) { + filters.forEach( function ( filterName ) { + mw.track( + 'event.ChangesListFilterGrouping', + { + action: action, + groupIdentifier: randomIdentifier, + filter: filterName, + userId: mw.user.getId() + } + ); + } ); + + // Cache the filter names + this.prevLoggedItems = filters; + } + }; }( mediaWiki, jQuery ) );