-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Media: Add a checkbox to toggle infinite scrolling in the media modal #12795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
adc6017
d72a6da
c763743
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ var View = wp.media.View, | |
| $ = jQuery, | ||
| AttachmentsBrowser, | ||
| infiniteScrolling = wp.media.view.settings.infiniteScrolling, | ||
| canToggleInfiniteScrolling = wp.media.view.settings.canToggleInfiniteScrolling, | ||
| __ = wp.i18n.__, | ||
| sprintf = wp.i18n.sprintf; | ||
|
|
||
|
|
@@ -43,6 +44,8 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
| AttachmentView: wp.media.view.Attachment.Library | ||
| }); | ||
|
|
||
| this.infiniteScrolling = !! infiniteScrolling; | ||
|
|
||
| this.controller.on( 'toggle:upload:attachment', this.toggleUploader, this ); | ||
| this.controller.on( 'edit:selection', this.editSelection ); | ||
|
|
||
|
|
@@ -77,7 +80,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
| // Create the attachments wrapper view. | ||
| this.createAttachmentsWrapperView(); | ||
|
|
||
| if ( ! infiniteScrolling ) { | ||
| if ( ! this.infiniteScrolling ) { | ||
| this.$el.addClass( 'has-load-more' ); | ||
| this.createLoadMoreView(); | ||
| } | ||
|
|
@@ -89,7 +92,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
|
|
||
| this.updateContent(); | ||
|
|
||
| if ( ! infiniteScrolling ) { | ||
| if ( ! this.infiniteScrolling ) { | ||
| this.updateLoadMoreView(); | ||
| } | ||
|
|
||
|
|
@@ -102,10 +105,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
| } | ||
|
|
||
| this.collection.on( 'add remove reset', this.updateContent, this ); | ||
|
|
||
| if ( ! infiniteScrolling ) { | ||
| this.collection.on( 'add remove reset', this.updateLoadMoreView, this ); | ||
| } | ||
| this.collection.on( 'add remove reset', this.updateLoadMoreView, this ); | ||
|
|
||
| // The non-cached or cached attachments query has completed. | ||
| this.collection.on( 'attachments:received', this.announceSearchResults, this ); | ||
|
|
@@ -125,7 +125,7 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
| /* translators: Accessibility text. %d: Number of attachments found in a search. */ | ||
| mediaFoundHasMoreResultsMessage = __( 'Number of media items displayed: %d. Click load more for more results.' ); | ||
|
|
||
| if ( infiniteScrolling ) { | ||
| if ( this.infiniteScrolling ) { | ||
| /* translators: Accessibility text. %d: Number of attachments found in a search. */ | ||
| mediaFoundHasMoreResultsMessage = __( 'Number of media items displayed: %d. Scroll the page for more results.' ); | ||
| } | ||
|
|
@@ -472,19 +472,142 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
| className: 'attachments-wrapper' | ||
| } ); | ||
|
|
||
| // Create the list of attachments. | ||
| this.views.add( this.attachmentsWrapper ); | ||
|
|
||
| /* | ||
| * Place the infinite scrolling toggle before the list of attachments. It | ||
| * saves the personal option, so it is only offered when wp_enqueue_media() | ||
| * reports that saving that option takes effect. | ||
| */ | ||
| if ( canToggleInfiniteScrolling ) { | ||
| this.createInfiniteScrollingToggle(); | ||
| } | ||
|
|
||
| // Create the list of attachments. | ||
| this.createAttachments(); | ||
| }, | ||
|
|
||
| /** | ||
| * Creates the checkbox that turns infinite scrolling on and off. | ||
| * | ||
| * @since 7.1.0 | ||
| * | ||
| * @return {void} | ||
| */ | ||
| createInfiniteScrollingToggle: function() { | ||
| var view = this, | ||
| id = _.uniqueId( 'media-infinite-scrolling-' ), | ||
| checkbox = $( '<input />', { | ||
| type: 'checkbox', | ||
| id: id, | ||
| checked: this.infiniteScrolling | ||
| } ), | ||
| label = $( '<label />', { | ||
| 'for': id, | ||
| text: __( 'Infinite scrolling' ) | ||
| } ); | ||
|
|
||
| // Not a live region: the same message is sent to `speak()` when it changes. | ||
| this.infiniteScrollingStatus = $( '<span />', { | ||
| 'class': 'media-infinite-scrolling-status' | ||
| } ); | ||
|
|
||
| checkbox.on( 'change', function() { | ||
| view.toggleInfiniteScrolling( this.checked ); | ||
| view.saveInfiniteScrolling( this.checked ); | ||
| } ); | ||
|
Comment on lines
+515
to
+518
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've noticed that quick changes can persist the opposite of the final checkbox state. Every change immediately launches an independent AJAX request. If an enable request and a subsequent disable request execute out of order, the old value can become the final value. |
||
|
|
||
| this.infiniteScrollingToggle = new View( { | ||
| controller: this.controller, | ||
| className: 'media-infinite-scrolling' | ||
| } ); | ||
|
|
||
| this.infiniteScrollingToggle.$el.append( checkbox, label, this.infiniteScrollingStatus ); | ||
|
|
||
| this.views.add( '.attachments-wrapper', this.infiniteScrollingToggle ); | ||
| }, | ||
|
|
||
| /** | ||
| * Saves the infinite scrolling preference for the current user. | ||
| * | ||
| * @since 7.1.0 | ||
| * | ||
| * @param {boolean} infiniteScrolling Whether the attachments list has infinite scrolling. | ||
| * | ||
| * @return {void} | ||
| */ | ||
| saveInfiniteScrolling: function( infiniteScrolling ) { | ||
| var view = this; | ||
|
|
||
| wp.ajax.post( 'save-media-infinite-scrolling', { | ||
| nonce: wp.media.view.settings.nonce.saveInfiniteScrolling, | ||
| infiniteScrolling: infiniteScrolling | ||
| } ).done( function() { | ||
| view.updateInfiniteScrollingStatus( | ||
| infiniteScrolling ? | ||
| __( 'Infinite scrolling enabled. Preference saved.' ) : | ||
| __( 'Infinite scrolling disabled. Load more button displayed. Preference saved.' ) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The success text always announces "Load more button displayed", but the button is kept hidden when the library is empty or |
||
| ); | ||
| } ).fail( function() { | ||
| view.updateInfiniteScrollingStatus( __( 'The infinite scrolling preference could not be saved.' ) ); | ||
| } ); | ||
| }, | ||
|
|
||
| /** | ||
| * Displays and announces the result of changing the infinite scrolling preference. | ||
| * | ||
| * The controls it affects are at the end of the list of attachments, so the | ||
| * result is usually out of view when the checkbox changes. | ||
| * | ||
| * @since 7.1.0 | ||
| * | ||
| * @param {string} message The message to display and announce. | ||
| * | ||
| * @return {void} | ||
| */ | ||
| updateInfiniteScrollingStatus: function( message ) { | ||
| this.infiniteScrollingStatus.text( message ); | ||
| wp.a11y.speak( message ); | ||
| }, | ||
|
|
||
| /** | ||
| * Turns infinite scrolling of the attachments list on and off. | ||
| * | ||
| * When infinite scrolling is off, the "Load more" button is used instead. | ||
| * | ||
| * @since 7.1.0 | ||
| * | ||
| * @param {boolean} infiniteScrolling Whether the attachments list has infinite scrolling. | ||
| * | ||
| * @return {void} | ||
| */ | ||
| toggleInfiniteScrolling: function( infiniteScrolling ) { | ||
| this.infiniteScrolling = infiniteScrolling; | ||
| this.attachments.options.infiniteScrolling = infiniteScrolling; | ||
| this.$el.toggleClass( 'has-load-more', ! infiniteScrolling ); | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it may be helpful to include some kind of visual affordance that confirms that something has happened, since all the control changes happen out of the viewport. I also think that the control needs to save this preference for the user, so one possibility would be a notice that appears/is spoken saying "Infinite scrolling preference saved" |
||
| if ( ! this.loadMoreWrapper ) { | ||
| this.createLoadMoreView(); | ||
| } | ||
|
|
||
| this.loadMoreWrapper.$el.toggleClass( 'hidden', infiniteScrolling ); | ||
|
|
||
| if ( infiniteScrolling ) { | ||
| this.attachments.scroll(); | ||
| } else { | ||
| this.updateLoadMoreView(); | ||
| } | ||
| }, | ||
|
|
||
| createAttachments: function() { | ||
| this.attachments = new wp.media.view.Attachments({ | ||
| controller: this.controller, | ||
| collection: this.collection, | ||
| selection: this.options.selection, | ||
| model: this.model, | ||
| sortable: this.options.sortable, | ||
| scrollElement: this.options.scrollElement, | ||
| infiniteScrolling: this.infiniteScrolling, | ||
| scrollElement: this.options.scrollElement || this.attachmentsWrapper.el, | ||
| idealColumnWidth: this.options.idealColumnWidth, | ||
|
|
||
| // The single `Attachment` view to be used in the `Attachments` view. | ||
|
|
@@ -565,10 +688,15 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro | |
| * We need it to run only once, after all attachments are added or removed. | ||
| * | ||
| * @since 5.8.0 | ||
| * @since 7.1.0 Bails out when infinite scrolling is enabled. | ||
| * | ||
| * @return {void} | ||
| */ | ||
| updateLoadMoreView: _.debounce( function() { | ||
| if ( this.infiniteScrolling ) { | ||
| return; | ||
| } | ||
|
|
||
| // Ensure the load more view elements are initially hidden at each update. | ||
| this.loadMoreButton.$el.addClass( 'hidden' ); | ||
| this.loadMoreCount.$el.addClass( 'hidden' ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3317,6 +3317,29 @@ function wp_ajax_save_attachment_order() { | |
| wp_send_json_success(); | ||
| } | ||
|
|
||
| /** | ||
| * Handles saving the current user's Media Library infinite scrolling preference via AJAX. | ||
| * | ||
| * Writes the same personal option as the "Infinite Scrolling" checkbox on the | ||
| * profile screen, so that the preference set from the attachments browser | ||
| * persists beyond the current view. | ||
| * | ||
| * @since 7.1.0 | ||
| */ | ||
| function wp_ajax_save_media_infinite_scrolling() { | ||
| check_ajax_referer( 'save-media-infinite-scrolling', 'nonce' ); | ||
|
|
||
| if ( ! isset( $_POST['infiniteScrolling'] ) ) { | ||
| wp_send_json_error(); | ||
| } | ||
|
|
||
| $infinite_scrolling = wp_validate_boolean( wp_unslash( $_POST['infiniteScrolling'] ) ); | ||
|
|
||
| update_user_meta( get_current_user_id(), 'infinite_scrolling', $infinite_scrolling ? 'true' : 'false' ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs multisite coverage. |
||
|
|
||
| wp_send_json_success(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It appears like the return value of |
||
| } | ||
|
|
||
| /** | ||
| * Handles sending an attachment to the editor via AJAX. | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to feedback that has been given previously, we should make sure to consider newly rendered media browsers, since they seem to discard the saved choice if it differs from the one during page-load.
To test this: