src/mobile.special.watchlist.scripts/WatchList.js
const
mfExtend = require( '../mobile.startup/mfExtend' ),
PageList = require( '../mobile.startup/PageList' ),
WatchstarPageList = require( '../mobile.startup/watchstar/WatchstarPageList' ),
ScrollEndEventEmitter = require( './ScrollEndEventEmitter' ),
util = require( '../mobile.startup/util' ),
WatchListGateway = require( './WatchListGateway' );
/**
* An extension of the WatchstarPageList which preloads pages as all being
* watched.
*
* @extends WatchstarPageList
* @class WatchList
* @uses ScrollEndEventEmitter
*
* @fires watched
* @fires watch
* @param {Object} params Configuration options
* @param {OO.EventEmitter} params.eventBus Object used to listen for scroll:throttled events
* @private
*/
function WatchList( params ) {
let lastTitle;
const options = util.extend(
{},
{
isBorderBox: false
},
params
);
// Set up infinite scroll helper and listen to events
this.scrollEndEventEmitter = new ScrollEndEventEmitter( options.eventBus );
this.scrollEndEventEmitter.on( ScrollEndEventEmitter.EVENT_SCROLL_END,
this._loadPages.bind( this ) );
if ( options.el ) {
lastTitle = this.getLastTitle( options.el );
}
this.gateway = new WatchListGateway( options.api, lastTitle );
WatchstarPageList.call( this, options );
}
mfExtend( WatchList, WatchstarPageList, {
/**
* @inheritdoc
* @memberof WatchList
* @instance
*/
preRender: function () {
// The DOM will be modified. Prevent any false scroll end events from
// being emitted.
this.scrollEndEventEmitter.disable();
this.scrollEndEventEmitter.setElement( this.$el );
},
/**
* Also sets a watch uploads funnel.
*
* @inheritdoc
* @memberof WatchList
* @instance
*/
postRender: function () {
// Skip a level from WatchstarPageList directly to PageList.
PageList.prototype.postRender.apply( this );
const $items = this.queryUnitializedItems();
// WatchList requests list of watched pages. The list contains only
// watched pages so it's safe to transform the title map to a status map
// with each entry marked watched (true).
const statuses = Object.keys( this.parsePagesFromItems( $items ) )
.reduce( function ( arr, title ) {
arr[ title ] = true;
return arr;
}, {} );
this.renderItems( $items, statuses );
// The list has been extended. Re-enable scroll end events.
this.scrollEndEventEmitter.enable();
},
/**
* Loads pages from the api and triggers render.
* Infinite scroll is re-enabled in postRender.
*
* @memberof WatchList
* @instance
*/
_loadPages: function () {
this.gateway.loadWatchlist().then( function ( pages ) {
pages.forEach( function ( page ) {
this.appendPage( page );
}.bind( this ) );
this.render();
}.bind( this ) );
},
/**
* Appends a list item
*
* @memberof WatchList
* @instance
* @param {Page} page
*/
appendPage: function ( page ) {
// wikidata descriptions should not show in this view.
const templateOptions = util.extend( {}, page, {
wikidataDescription: undefined
} );
this.$el.append( this.templatePartials.item.render( templateOptions ) );
},
/**
* Get the last title from the rendered HTML.
* Used for initializing the API
*
* @memberof WatchList
* @instance
* @param {jQuery.Object} $el Dom element of the list
* @return {string}
*/
getLastTitle: function ( $el ) {
return $el.find( 'li' ).last().attr( 'title' );
}
} );
module.exports = WatchList;