jenkins-bot has submitted this change and it was merged.

Change subject: Add ability to remove/add new members to a collection via search
......................................................................


Add ability to remove/add new members to a collection via search

Bug: T90991
Change-Id: Ie262761519a29ad695695dcdf0f85f82e71d2dd0
---
M resources/Resources.php
M resources/ext.gather.page.search/CollectionPageList.js
M resources/ext.gather.page.search/CollectionSearchPanel.hogan
M resources/ext.gather.page.search/CollectionSearchPanel.js
M resources/ext.gather.page.search/item.hogan
5 files changed, 167 insertions(+), 17 deletions(-)

Approvals:
  Robmoen: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/resources/Resources.php b/resources/Resources.php
index b103deb..5a5319d 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -213,6 +213,7 @@
                'dependencies' => array(
                        'ext.gather.api',
                        'mobile.pagelist.scripts',
+                       'mobile.search',
                ),
                'messages' => array(
                        // FIXME: Duplicates messages in ext.gather.watchstar
diff --git a/resources/ext.gather.page.search/CollectionPageList.js 
b/resources/ext.gather.page.search/CollectionPageList.js
index a580afd..8c537a9 100644
--- a/resources/ext.gather.page.search/CollectionPageList.js
+++ b/resources/ext.gather.page.search/CollectionPageList.js
@@ -38,9 +38,11 @@
                events: $.extend( {}, PageList.prototype.events, {
                        'click li': 'onChangeMemberStatus'
                } ),
+               /** @inheritdoc */
                templatePartials: {
                        item: mw.template.get( 'ext.gather.page.search', 
'item.hogan' )
                },
+               /** @inheritdoc */
                initialize: function () {
                        // FIXME: PageList in MobileFrontend should be 
rewritten as PageListWatchstar.
                        View.prototype.initialize.apply( this, arguments );
@@ -54,29 +56,54 @@
                        // FIXME: PageList in MobileFrontend should be 
rewritten as PageListWatchstar.
                        View.prototype.postRender.apply( this, arguments );
                },
+               /**
+                * Event handler for when a member changes status in the 
collection
+                * @param {jQuery.Event} ev
+                */
                onChangeMemberStatus: function ( ev ) {
                        var $target = $( ev.currentTarget ),
                                collection = this.options.collection,
+                               $listThumb = $target.find( '.list-thumb' ),
                                self = this,
                                title = $target.data( 'title' ),
                                inCollection = $target.data( 'is-member' ),
-                               page = new Page( { title: title } );
+                               page = new Page( {
+                                       title: title
+                               } );
+
+                       // FIXME: So hacky. Move/use methods on Page
+                       page.heading =  title;
+                       page.pageimageClass = $listThumb.attr( 'class' );
+                       page.listThumbStyleAttribute = $listThumb.attr( 'style' 
);
 
                        if ( inCollection ) {
                                this.api.removePageFromCollection( 
collection.id, page ).done( function () {
                                        $target.find( '.status' ).replaceWith( 
self.options.iconDisabledButton );
                                        $target.data( 'is-member', false );
                                        toast.show( mw.msg( 
'gather-remove-toast', collection.title ), 'toast' );
+                                       /**
+                                        * @event member-removed
+                                        * @param {Page} page
+                                        * Fired when member is removed from 
collection
+                                        */
+                                       self.emit( 'member-removed', page );
                                } );
                        } else {
                                this.api.addPageToCollection( collection.id, 
page ).done( function () {
                                        $target.find( '.status' ).replaceWith( 
self.options.iconButton );
                                        $target.data( 'is-member', true );
                                        toast.show( mw.msg( 'gather-add-toast', 
collection.title ), 'toast' );
+                                       page.isMember = true;
+                                       /**
+                                        * @event member-added
+                                        * @param {Page} page
+                                        * Fired when member is removed from 
collection
+                                        */
+                                       self.emit( 'member-added', page );
                                } );
                        }
                        return false;
-               },
+               }
        } );
 
        M.define( 'ext.gather.page.search/CollectionPageList', 
CollectionPageList );
diff --git a/resources/ext.gather.page.search/CollectionSearchPanel.hogan 
b/resources/ext.gather.page.search/CollectionSearchPanel.hogan
index 40c7061..f43b407 100644
--- a/resources/ext.gather.page.search/CollectionSearchPanel.hogan
+++ b/resources/ext.gather.page.search/CollectionSearchPanel.hogan
@@ -1 +1,4 @@
+<div class="search">
+       {{{searchIcon}}}<input type="text">
+</div>
 <div class="results"></div>
diff --git a/resources/ext.gather.page.search/CollectionSearchPanel.js 
b/resources/ext.gather.page.search/CollectionSearchPanel.js
index 14aab5e..0052206 100644
--- a/resources/ext.gather.page.search/CollectionSearchPanel.js
+++ b/resources/ext.gather.page.search/CollectionSearchPanel.js
@@ -1,6 +1,9 @@
-( function ( M ) {
+( function ( M, $ ) {
 
        var Panel = M.require( 'Panel' ),
+               Icon = M.require( 'Icon' ),
+               SearchApi = M.require( 'modules/search/SearchApi' ),
+               SEARCH_DELAY = 500,
                CollectionPageList = M.require( 
'ext.gather.page.search/CollectionPageList' ),
                CollectionSearchPanel;
 
@@ -8,9 +11,15 @@
         * Class for a showing page search results in a panel
         * @class CollectionPageSearchPanel
         * @extends Panel
+        * @uses CollectionPageList
         */
        CollectionSearchPanel = Panel.extend( {
+               /** @inheritdoc */
                template: mw.template.get( 'ext.gather.page.search', 
'CollectionSearchPanel.hogan' ),
+               /** @inheritdoc */
+               events: $.extend( {}, Panel.prototype.events, {
+                       'input .search input': 'onSearchInput'
+               } ),
                /**
                 * @inheritdoc
                 * @cfg {Array} defaults.pages a list of pages in the collection
@@ -19,22 +28,132 @@
                className: 'panel visible collection-search-panel',
                defaults: {
                        pages: [],
-                       collection: undefined
+                       collection: undefined,
+                       searchIcon: new Icon( {
+                               name: 'search',
+                               // FIXME:
+                               label: mw.msg( 'search' ),
+                               additionalClassNames: 'indicator'
+                       } ).toHtmlString()
                },
-               postRender: function( options ) {
+               /** @inheritdoc */
+               initialize: function ( options ) {
+                       var self = this;
+                       // FIXME: In future we'll want to use CollectionApi for 
this
+                       this.api = new SearchApi();
+                       Panel.prototype.initialize.call( this, options );
+                       this._members = {};
+                       $.each( options.pages, function ( i, page ) {
+                               self._members[page.title] = true;
+                       } );
+               },
+               /** @inheritdoc */
+               postRender: function ( options ) {
                        Panel.prototype.postRender.apply( this, arguments );
                        this._renderResults( options.pages );
                },
+               /**
+                * Updates the members of the collection associated with the 
panel
+                * @param {Page} page
+                * @param {Boolean} isRemoved whether page has been removed 
from this collection
+                */
+               _updateCollectionMembers: function ( page, isRemoved ) {
+                       var newPages = [],
+                               options = this.options;
+
+                       if ( isRemoved ) {
+                               delete this._members[page.title];
+                       } else {
+                               this._members[page.title] = true;
+                       }
+                       if ( isRemoved ) {
+                               $.each( options.pages, function ( i, curPage ) {
+                                       if ( curPage.title !== page.title ) {
+                                               newPages.push( curPage );
+                                       }
+                               } );
+                               this.options.pages = newPages;
+                       } else {
+                               this.options.pages.push( page );
+                       }
+               },
+               /**
+                * Updates the rendering of the internal CollectionPageList
+                * @private
+                * @param {Page[]} pages
+                */
                _renderResults: function ( pages ) {
-                       var collectionPageList = new CollectionPageList( {
-                               pages: pages,
-                               collection: this.options.collection,
-                               el: this.$( '.results' )
-                       } );
-                       collectionPageList.renderPageImages();
+                       var self = this;
+                       if ( this.pageList ) {
+                               this.pageList.options.pages = pages;
+                               this.pageList.render();
+                       } else {
+                               this.pageList = new CollectionPageList( {
+                                       pages: pages,
+                                       collection: this.options.collection,
+                                       el: this.$( '.results' )
+                               } );
+                               this.pageList.on( 'member-removed', function ( 
page ) {
+                                       self._updateCollectionMembers( page, 
true );
+                               } );
+                               this.pageList.on( 'member-added', function ( 
page ) {
+                                       self._updateCollectionMembers( page );
+                               } );
+                       }
+                       this.pageList.renderPageImages();
+               },
+               /**
+                * Check whether a member is a known member of the current 
collection.
+                * @param {String} title
+                * @returns {Boolean}
+                */
+               hasMember: function ( title ) {
+                       return this._members[title] !== undefined;
+               },
+               /**
+                * Event handler for when search input changes
+                */
+               onSearchInput: function () {
+                       var self = this,
+                               $input = this.$( 'input' ),
+                               query = $input.val(),
+                               $results = this.$( '.results' );
+
+                       if ( query !== this.lastQuery ) {
+                               this.api.abort();
+                               clearTimeout( this.timer );
+                               $results.empty();
+
+                               if ( query.length ) {
+                                       this.$( '.spinner' ).show();
+
+                                       this.timer = setTimeout( function () {
+                                               self.api.search( query ).done( 
function ( data ) {
+                                                       var results;
+
+                                                       // check if we're 
getting the rights response in case of out of
+                                                       // order responses 
(need to get the current value of the input)
+                                                       if ( data.query === 
$input.val() ) {
+                                                               results = 
$.map( data.results, function ( page ) {
+                                                                       
page.isMember = self.hasMember( page.title );
+                                                                       return 
page;
+                                                               } );
+                                                               self.$( 
'.spinner' ).hide();
+                                                               
self._renderResults( results );
+                                                       }
+                                               } );
+                                       }, SEARCH_DELAY );
+                               } else {
+                                       // re-render the members of the 
collection
+                                       this._renderResults( this.options.pages 
);
+                               }
+
+                               // keep track of last query to take into 
account backspace usage
+                               this.lastQuery = query;
+                       }
                }
        } );
 
        M.define( 'ext.gather.page.search/CollectionSearchPanel', 
CollectionSearchPanel );
 
-}( mw.mobileFrontend ) );
+}( mw.mobileFrontend, jQuery ) );
diff --git a/resources/ext.gather.page.search/item.hogan 
b/resources/ext.gather.page.search/item.hogan
index e9d5ab4..85c9cfe 100644
--- a/resources/ext.gather.page.search/item.hogan
+++ b/resources/ext.gather.page.search/item.hogan
@@ -1,9 +1,9 @@
 <li class="page-summary" title="{{title}}" data-title="{{title}}"
        {{#isMember}}data-is-member="true"{{/isMember}}>
-  <a href="#" class="title">
-    <div class="list-thumb {{pageimageClass}}" 
style="{{listThumbStyleAttribute}}"></div>
-    <h3>{{{heading}}}</h3>
-    {{#isMember}}{{{iconButton}}}{{/isMember}}
+       <div class="title">
+               <div class="list-thumb {{pageimageClass}}" 
style="{{listThumbStyleAttribute}}"></div>
+               <h3>{{{heading}}}</h3>
+               {{#isMember}}{{{iconButton}}}{{/isMember}}
                {{^isMember}}{{{iconDisabledButton}}}{{/isMember}}
-  </a>
+       </div>
 </li>

-- 
To view, visit https://gerrit.wikimedia.org/r/202935
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie262761519a29ad695695dcdf0f85f82e71d2dd0
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/Gather
Gerrit-Branch: master
Gerrit-Owner: Jdlrobson <[email protected]>
Gerrit-Reviewer: Robmoen <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to