From e6663f0f3ec9830a22c6a6877b92c6f1bf4e1ff6 Mon Sep 17 00:00:00 2001 From: stoletniy Date: Thu, 29 Jun 2017 13:07:08 +0300 Subject: [PATCH 1/4] Hide a horizontal scrollbar in Posts widget listing [MAILPOET-971] --- assets/css/src/newsletter_editor/contentBlocks/posts.styl | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/css/src/newsletter_editor/contentBlocks/posts.styl b/assets/css/src/newsletter_editor/contentBlocks/posts.styl index 6040e7a9de..5137e52bca 100644 --- a/assets/css/src/newsletter_editor/contentBlocks/posts.styl +++ b/assets/css/src/newsletter_editor/contentBlocks/posts.styl @@ -18,6 +18,7 @@ .mailpoet_settings_posts_display_options .mailpoet_settings_posts_selection animation-slide-open-downwards() + overflow-x: hidden .mailpoet_settings_posts_show_display_options, .mailpoet_settings_posts_show_post_selection From eba482cc67827b1f933096f9389a0fb0a1b3cdc6 Mon Sep 17 00:00:00 2001 From: stoletniy Date: Thu, 29 Jun 2017 13:13:36 +0300 Subject: [PATCH 2/4] Add dynamic post loading in Posts widget settings [MAILPOET-971] --- .../contentBlocks/posts.styl | 10 +++- .../js/src/newsletter_editor/blocks/posts.js | 49 +++++++++++++++++++ lib/Newsletter/AutomatedLatestContent.php | 4 ++ views/newsletter/editor.html | 2 +- .../blocks/posts/settingsSelection.hbs | 3 ++ 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/assets/css/src/newsletter_editor/contentBlocks/posts.styl b/assets/css/src/newsletter_editor/contentBlocks/posts.styl index 5137e52bca..25094c90ba 100644 --- a/assets/css/src/newsletter_editor/contentBlocks/posts.styl +++ b/assets/css/src/newsletter_editor/contentBlocks/posts.styl @@ -27,7 +27,12 @@ .mailpoet_post_selection_container margin-top: 20px - margin-bottom: 20px + margin-bottom: 0 + +.mailpoet_post_scroll_container + overflow-y: scroll + overflow-x: hidden + max-height: 400px .mailpoet_settings_posts_single_post border-radius(1px) @@ -46,3 +51,6 @@ .mailpoet_select_post_checkbox margin-left: 10px margin-right: 8px + +.mailpoet_post_selection_loading + color: #999 diff --git a/assets/js/src/newsletter_editor/blocks/posts.js b/assets/js/src/newsletter_editor/blocks/posts.js index 64590b7fb5..2255af3dc2 100644 --- a/assets/js/src/newsletter_editor/blocks/posts.js +++ b/assets/js/src/newsletter_editor/blocks/posts.js @@ -48,6 +48,7 @@ define([ return this._getDefaults({ type: 'posts', amount: '10', + offset: 0, contentType: 'post', // 'post'|'page'|'mailpoet_page' postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future' terms: [], // List of category and tag objects @@ -98,6 +99,7 @@ define([ this.fetchAvailablePosts(); this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', refreshAvailablePosts); + this.on('loadMorePosts', this._loadMorePosts, this); this.listenTo(this.get('_selectedPosts'), 'add remove reset', refreshTransformedPosts); this.on('change:displayType change:titleFormat change:featuredImagePosition change:titleAlignment change:titleIsLink change:imageFullWidth change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:showDivider', refreshTransformedPosts); @@ -108,6 +110,7 @@ define([ }, fetchAvailablePosts: function() { var that = this; + this.set('offset', 0); CommunicationComponent.getPosts(this.toJSON()).done(function(posts) { that.get('_availablePosts').reset(posts); that.get('_selectedPosts').reset(); // Empty out the collection @@ -116,6 +119,27 @@ define([ MailPoet.Notice.error(MailPoet.I18n.t('failedToFetchAvailablePosts')); }); }, + _loadMorePosts: function() { + var that = this, + postCount = this.get('_availablePosts').length, + nextOffset = this.get('offset') + ~~this.get('amount'); + + if(postCount === 0 || postCount < nextOffset) { + // No more posts to load + return false; + } + this.set('offset', nextOffset); + this.trigger('loadingMorePosts'); + + CommunicationComponent.getPosts(this.toJSON()).done(function(posts) { + that.get('_availablePosts').add(posts); + that.trigger('change:_availablePosts'); + }).fail(function() { + MailPoet.Notice.error(MailPoet.I18n.t('failedToFetchAvailablePosts')); + }).always(function() { + that.trigger('morePostsLoaded'); + }); + }, _refreshTransformedPosts: function() { var that = this, data = this.toJSON(); @@ -260,6 +284,7 @@ define([ }); var PostsSelectionCollectionView = Marionette.CollectionView.extend({ + className: 'mailpoet_post_scroll_container', childView: function() { return SinglePostSelectionSettingsView; }, emptyView: function() { return EmptyPostSelectionSettingsView; }, childViewOptions: function() { @@ -270,6 +295,16 @@ define([ initialize: function(options) { this.blockModel = options.blockModel; }, + events: { + 'scroll': 'onPostsScroll', + }, + onPostsScroll: function(event) { + var $postsBox = jQuery(event.target); + if($postsBox.scrollTop() + $postsBox.innerHeight() >= $postsBox[0].scrollHeight){ + // Load more posts if scrolled to bottom + this.blockModel.trigger('loadMorePosts'); + } + }, }); var PostSelectionSettingsView = Marionette.View.extend({ @@ -284,6 +319,20 @@ define([ 'input .mailpoet_posts_search_term': _.partial(this.changeField, 'search'), }; }, + modelEvents: { + 'change:offset': function(model, value) { + // Scroll posts view to top if settings are changed + if (value === 0) { + this.$('.mailpoet_post_scroll_container').scrollTop(0); + } + }, + 'loadingMorePosts': function() { + this.$('.mailpoet_post_selection_loading').css('visibility', 'visible'); + }, + 'morePostsLoaded': function() { + this.$('.mailpoet_post_selection_loading').css('visibility', 'hidden'); + } + }, onRender: function() { // Dynamically update available post types CommunicationComponent.getPostTypes().done(_.bind(this._updateContentTypes, this)); diff --git a/lib/Newsletter/AutomatedLatestContent.php b/lib/Newsletter/AutomatedLatestContent.php index c9abb0549a..0e5d698ed2 100644 --- a/lib/Newsletter/AutomatedLatestContent.php +++ b/lib/Newsletter/AutomatedLatestContent.php @@ -39,11 +39,15 @@ class AutomatedLatestContent { 'orderby' => 'date', 'order' => ($args['sortBy'] === 'newest') ? 'DESC' : 'ASC', ); + if(!empty($args['offset']) && (int)$args['offset'] > 0) { + $parameters['offset'] = (int)$args['offset']; + } if(isset($args['search'])) { $parameters['s'] = $args['search']; } if(isset($args['posts']) && is_array($args['posts'])) { $parameters['post__in'] = $args['posts']; + $parameters['posts_per_page'] = -1; // Get all posts with matching IDs } if(!empty($posts_to_exclude)) { $parameters['post__not_in'] = $posts_to_exclude; diff --git a/views/newsletter/editor.html b/views/newsletter/editor.html index d08efc288f..455a0211da 100644 --- a/views/newsletter/editor.html +++ b/views/newsletter/editor.html @@ -1073,7 +1073,7 @@ }, }, posts: { - amount: '8', + amount: '10', contentType: 'post', // 'post'|'page'|'mailpoet_page' postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future' inclusionType: 'include', // 'include'|'exclude' diff --git a/views/newsletter/templates/blocks/posts/settingsSelection.hbs b/views/newsletter/templates/blocks/posts/settingsSelection.hbs index b91206f3ad..94c585b0e0 100644 --- a/views/newsletter/templates/blocks/posts/settingsSelection.hbs +++ b/views/newsletter/templates/blocks/posts/settingsSelection.hbs @@ -23,3 +23,6 @@
+ From 04e238634d268b1651af4a9c5b526121f442d6e8 Mon Sep 17 00:00:00 2001 From: stoletniy Date: Thu, 29 Jun 2017 15:34:26 +0300 Subject: [PATCH 3/4] Add unit tests [MAILPOET-971] --- .../newsletter_editor/blocks/posts.spec.js | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/javascript/newsletter_editor/blocks/posts.spec.js b/tests/javascript/newsletter_editor/blocks/posts.spec.js index 4065e66a38..c9d8cca05d 100644 --- a/tests/javascript/newsletter_editor/blocks/posts.spec.js +++ b/tests/javascript/newsletter_editor/blocks/posts.spec.js @@ -43,6 +43,10 @@ define([ expect(model.get('amount')).to.match(/^\d+$/); }); + it('has post offset initialized', function () { + expect(model.get('offset')).to.equal(0); + }); + it('has post type filter', function () { expect(model.get('contentType')).to.match(/^(post|page|mailpoet_page)$/); }); @@ -197,6 +201,55 @@ define([ expect(model.get('divider.styles.block.backgroundColor')).to.equal('#456789'); expect(model.get('divider.styles.block.padding')).to.equal('38px'); }); + + it('resets offset when fetching posts', function () { + model.set('offset', 10); + model.fetchAvailablePosts(); + expect(model.get('offset')).to.equal(0); + }); + + it('increases offset when loading more posts', function () { + model.set({ + amount: 2, + offset: 0 + }); + model.set('_availablePosts', new Backbone.Collection([{}, {}])); // 2 posts + model.trigger('loadMorePosts'); + expect(model.get('offset')).to.equal(2); + }); + + it('does not increase offset when there is no more posts to load', function () { + model.set({ + amount: 10, + offset: 0 + }); + model.set('_availablePosts', new Backbone.Collection([{}, {}])); // 2 posts + model.trigger('loadMorePosts'); + expect(model.get('offset')).to.equal(0); + }); + + it('triggers loading and loaded events for more posts', function () { + var stub = sinon.stub(CommunicationComponent, 'getPosts', function() { + var deferred = jQuery.Deferred(); + deferred.resolve([{}]); // 1 post + return deferred; + }); + var spy = sinon.spy(model, 'trigger'); + + model.set({ + amount: 2, + offset: 0 + }); + model.set('_availablePosts', new Backbone.Collection([{}, {}])); // 2 posts + model._loadMorePosts(); + + stub.restore(); + spy.restore(); + + expect(spy.withArgs('loadingMorePosts').calledOnce).to.be.true; + expect(spy.withArgs('morePostsLoaded').calledOnce).to.be.true; + expect(model.get('_availablePosts').length).to.equal(3); + }); }); describe('block view', function () { From b823991867d031743af8889ab7332b3221b4e65c Mon Sep 17 00:00:00 2001 From: stoletniy Date: Thu, 29 Jun 2017 16:45:12 +0300 Subject: [PATCH 4/4] Fix lint errors [MAILPOET-971] --- assets/js/src/newsletter_editor/blocks/posts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/src/newsletter_editor/blocks/posts.js b/assets/js/src/newsletter_editor/blocks/posts.js index 2255af3dc2..c4b94e7ee2 100644 --- a/assets/js/src/newsletter_editor/blocks/posts.js +++ b/assets/js/src/newsletter_editor/blocks/posts.js @@ -122,7 +122,7 @@ define([ _loadMorePosts: function() { var that = this, postCount = this.get('_availablePosts').length, - nextOffset = this.get('offset') + ~~this.get('amount'); + nextOffset = this.get('offset') + Number(this.get('amount')); if(postCount === 0 || postCount < nextOffset) { // No more posts to load