From: Matthias Schmidt Date: Fri, 31 Mar 2017 17:24:41 +0000 (+0200) Subject: Add media dialog pagination X-Git-Tag: 3.1.0_Alpha_1~523 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=e2a882dffe37cb2b26d88f609f5d7da749101951;p=GitHub%2FWoltLab%2FWCF.git Add media dialog pagination See #2224 --- diff --git a/com.woltlab.wcf/templates/mediaManager.tpl b/com.woltlab.wcf/templates/mediaManager.tpl index 4850e5571d..2dc7d4828c 100644 --- a/com.woltlab.wcf/templates/mediaManager.tpl +++ b/com.woltlab.wcf/templates/mediaManager.tpl @@ -41,3 +41,5 @@ {include file='mediaListItems'} + +
diff --git a/wcfsetup/install/files/acp/templates/mediaManager.tpl b/wcfsetup/install/files/acp/templates/mediaManager.tpl index 4850e5571d..2dc7d4828c 100644 --- a/wcfsetup/install/files/acp/templates/mediaManager.tpl +++ b/wcfsetup/install/files/acp/templates/mediaManager.tpl @@ -41,3 +41,5 @@ {include file='mediaListItems'} + +
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js index ae07ecd164..c0f95d6b19 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js @@ -11,13 +11,15 @@ define( 'Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse', 'Dom/Util', 'EventHandler', 'Language', 'List', 'Permission', 'Ui/Dialog', 'Ui/Notification', 'WoltLabSuite/Core/Controller/Clipboard', - 'WoltLabSuite/Core/Media/Editor', 'WoltLabSuite/Core/Media/Upload', 'WoltLabSuite/Core/Media/Manager/Search', 'StringUtil' + 'WoltLabSuite/Core/Media/Editor', 'WoltLabSuite/Core/Media/Upload', 'WoltLabSuite/Core/Media/Manager/Search', 'StringUtil', + 'WoltLabSuite/Core/Ui/Pagination' ], function( Core, Dictionary, DomChangeListener, DomTraverse, DomUtil, EventHandler, Language, List, Permission, UiDialog, UiNotification, Clipboard, - MediaEditor, MediaUpload, MediaManagerSearch, StringUtil + MediaEditor, MediaUpload, MediaManagerSearch, StringUtil, + UiPagination ) { "use strict"; @@ -37,12 +39,12 @@ define( this._id = 'mediaManager' + _mediaManagerCounter++; this._listItems = new Dictionary(); this._media = new Dictionary(); - this._mediaCache = null; this._mediaManagerMediaList = null; this._search = null; this._upload = null; this._forceClipboard = false; this._hadInitiallyMarkedItems = false; + this._pagination = null; if (Permission.get('admin.content.cms.canManageMedia')) { this._mediaEditor = new MediaEditor(this); @@ -131,6 +133,8 @@ define( } } + this._initPagination(~~data.returnValues.pageCount); + this._hadInitiallyMarkedItems = data.returnValues.hasMarkedItems; }, @@ -191,7 +195,7 @@ define( var deleteAction = new WCF.Action.Delete('wcf\\data\\media\\MediaAction', '.mediaFile'); deleteAction._didTriggerEffect = function(element) { - this.removeMedia(elData(element[0], 'object-id'), true); + this.removeMedia(elData(element[0], 'object-id')); }.bind(this); } @@ -278,6 +282,31 @@ define( } }, + /** + * Initializes the dialog pagination. + * + * @param {integer} pageCount + * @param {integer} pageNo + */ + _initPagination: function(pageCount, pageNo) { + if (pageNo === undefined) pageNo = 1; + + if (pageCount > 1) { + var newPagination = elCreate('div'); + newPagination.className = 'paginationBottom jsPagination'; + DomUtil.replaceElement(elBySel('.jsPagination', UiDialog.getDialog(this).content), newPagination); + + this._pagination = new UiPagination(newPagination, { + activePage: pageNo, + callbackSwitch: this._search.search.bind(this._search), + maxPage: pageCount + }); + } + else if (this._pagination) { + elHide(this._pagination.getElement()); + } + }, + /** * Removes all media clipboard checkboxes. */ @@ -407,9 +436,8 @@ define( * Removes a media file. * * @param {int} mediaId id of the removed media file - * @param {boolean|undefined} checkCache media file will also be removed from the local cache if true */ - removeMedia: function(mediaId, checkCache) { + removeMedia: function(mediaId) { if (this._listItems.has(mediaId)) { // remove list item try { @@ -422,26 +450,14 @@ define( this._listItems.delete(mediaId); this._media.delete(mediaId); } - - if (checkCache && this._mediaCache && this._mediaCache.has(mediaId)) { - this._mediaCache.delete(mediaId); - } }, /** * Changes the displayed media to the previously displayed media. */ resetMedia: function() { - if (this._mediaCache !== null) { - this._setMedia(this._mediaCache); - - this._mediaCache = null; - - this._search.resetSearch(); - if (this._mediaCategorySelect) { - this._mediaCategorySelect.value = 0; - } - } + // calling WoltLabSuite/Core/Media/Manager/Search.search() reloads the first page of the dialog + this._search.search(); }, /** @@ -449,12 +465,9 @@ define( * * @param {object} media media data * @param {string} template + * @param {object} additionalData */ - setMedia: function(media, template) { - if (!this._mediaCache) { - this._mediaCache = this._media; - } - + setMedia: function(media, template, additionalData) { var hasMedia = false; for (var mediaId in media) { if (objOwns(media, mediaId)) { @@ -478,6 +491,8 @@ define( } } + this._initPagination(additionalData.pageCount, additionalData.pageNo); + this._setMedia(media); }, diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Search.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Search.js index 94bfd63511..39b4ad5b26 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Search.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Search.js @@ -45,7 +45,12 @@ define(['Ajax', 'Core', 'Dom/Traverse', 'Dom/Util', 'EventKey', 'Language', 'Ui/ * @param {object} data response data */ _ajaxSuccess: function(data) { - this._mediaManager.setMedia(data.returnValues.media || { }, data.returnValues.template || ''); + this._mediaManager.setMedia(data.returnValues.media || { }, data.returnValues.template || '', { + pageCount: data.returnValues.pageCount || 0, + pageNo: data.returnValues.pageNo || 0 + }); + + elByClass('dialogContent', this._mediaManager.getDialog())[0].scrollTop = 0; }, /** @@ -55,8 +60,8 @@ define(['Ajax', 'Core', 'Dom/Traverse', 'Dom/Util', 'EventKey', 'Language', 'Ui/ if (this._searchMode) { this._searchMode = false; - this._mediaManager.resetMedia(); this.resetSearch(); + this._mediaManager.resetMedia(); } }, @@ -130,8 +135,14 @@ define(['Ajax', 'Core', 'Dom/Traverse', 'Dom/Util', 'EventKey', 'Language', 'Ui/ /** * Sends an AJAX request to fetch search results. + * + * @param {integer} pageNo */ - search: function() { + search: function(pageNo) { + if (typeof pageNo !== "number") { + pageNo = 1; + } + var searchString = this._input.value; if (searchString && this._input.value.length < this._mediaManager.getOption('minSearchLength')) { this._showStringThresholdError(); @@ -149,6 +160,7 @@ define(['Ajax', 'Core', 'Dom/Traverse', 'Dom/Util', 'EventKey', 'Language', 'Ui/ categoryID: this._mediaManager.getCategoryId(), imagesOnly: this._mediaManager.getOption('imagesOnly'), mode: this._mediaManager.getMode(), + pageNo: pageNo, searchString: searchString } }); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js index 10b24159f4..78052d13ea 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Upload.js @@ -87,10 +87,9 @@ define( imagesOnly: this._mediaManager.getOption('imagesOnly') }; - if (this._categoryId) { - parameters.categoryID = this._categoryId; - - this._categoryId = null; + var categoryId = this._mediaManager.getCategoryId(); + if (categoryId) { + parameters.categoryID = categoryId; } return Core.extend(MediaUpload._super.prototype._getParameters.call(this), parameters); @@ -178,12 +177,6 @@ define( * @see WoltLabSuite/Core/Upload#_uploadFiles */ _uploadFiles: function(files, blob) { - // reset media (search) before uploading - if (this._mediaManager) { - this._categoryId = this._mediaManager.getCategoryId(); - this._mediaManager.resetMedia(); - } - return MediaUpload._super.prototype._uploadFiles.call(this, files, blob); } }); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Pagination.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Pagination.js index acea0fa498..43e943d7eb 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Pagination.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Pagination.js @@ -203,6 +203,33 @@ define(['Core', 'Language', 'ObjectMap', 'StringUtil', 'WoltLabSuite/Core/Ui/Pag return listItem; }, + /** + * Returns the active page. + * + * @return {integer} + */ + getActivePage: function() { + return this._options.activePage; + }, + + /** + * Returns the pagination Ui element. + * + * @return {HTMLElement} + */ + getElement: function() { + return this._element; + }, + + /** + * Returns the maximum page. + * + * @return {integer} + */ + getMaxPage: function() { + return this._options.maxPage; + }, + /** * Switches to given page number. * diff --git a/wcfsetup/install/files/lib/data/media/MediaAction.class.php b/wcfsetup/install/files/lib/data/media/MediaAction.class.php index 46157d5451..c1be63eab5 100644 --- a/wcfsetup/install/files/lib/data/media/MediaAction.class.php +++ b/wcfsetup/install/files/lib/data/media/MediaAction.class.php @@ -33,6 +33,11 @@ use wcf\util\FileUtil; * @method MediaEditor getSingleObject() */ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction, IUploadAction { + /** + * number of media files per media manager dialog page + */ + const ITEMS_PER_MANAGER_DIALOG_PAGE = 50; + /** * @inheritDoc */ @@ -188,8 +193,8 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction, if ($this->parameters['imagesOnly']) { $mediaList->getConditionBuilder()->add('media.isImage = ?', [1]); } - $mediaList->sqlOrderBy = 'media.uploadTime DESC'; - $mediaList->sqlLimit = 50; + $mediaList->sqlOrderBy = 'media.uploadTime DESC, media.mediaID DESC'; + $mediaList->sqlLimit = static::ITEMS_PER_MANAGER_DIALOG_PAGE; $mediaList->readObjects(); $categoryList = (new CategoryNodeTree('com.woltlab.wcf.media.category'))->getIterator(); @@ -198,6 +203,7 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction, return [ 'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.media')), 'media' => $this->getI18nMediaData($mediaList), + 'pageCount' => ceil($mediaList->countObjects() / static::ITEMS_PER_MANAGER_DIALOG_PAGE), 'template' => WCF::getTPL()->fetch('mediaManager', 'wcf', [ 'categoryList' => $categoryList, 'mediaList' => $mediaList, @@ -440,6 +446,9 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction, if ($this->parameters['mode'] != 'editor' && $this->parameters['mode'] != 'select') { throw new UserInputException('mode'); } + + $this->readInteger('pageNo', true); + if (!$this->parameters['pageNo']) $this->parameters['pageNo'] = 1; } /** @@ -454,11 +463,22 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction, if ($this->parameters['categoryID']) { $mediaList->getConditionBuilder()->add('media.categoryID = ?', [$this->parameters['categoryID']]); } - $mediaList->sqlOrderBy = 'media.uploadTime DESC'; - $mediaList->sqlLimit = 50; + $mediaList->sqlOrderBy = 'media.uploadTime DESC, media.mediaID DESC'; + $mediaList->sqlLimit = static::ITEMS_PER_MANAGER_DIALOG_PAGE; + $mediaList->sqlOffset = ($this->parameters['pageNo'] - 1) * static::ITEMS_PER_MANAGER_DIALOG_PAGE; $mediaList->readObjectIDs(); if (empty($mediaList->getObjectIDs())) { + // check if page is requested that might have existed but does not exist anymore due to deleted + // media files + if ($this->parameters['pageNo'] > 1 && $this->parameters['searchString'] === '' && !$this->parameters['categoryID']) { + // request media dialog page with highest page number + $parameters = $this->parameters; + $parameters['pageNo'] = ceil($mediaList->countObjects() / static::ITEMS_PER_MANAGER_DIALOG_PAGE); + + return (new MediaAction($this->objects, 'getSearchResultList', $parameters))->executeAction()['returnValues']; + } + return [ 'template' => WCF::getLanguage()->getDynamicVariable('wcf.media.search.noResults') ]; @@ -470,6 +490,8 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction, return [ 'media' => $this->getI18nMediaData($viewableMediaList), + 'pageCount' => ceil($mediaList->countObjects() / static::ITEMS_PER_MANAGER_DIALOG_PAGE), + 'pageNo' => $this->parameters['pageNo'], 'template' => WCF::getTPL()->fetch('mediaListItems', 'wcf', [ 'mediaList' => $viewableMediaList, 'mode' => $this->parameters['mode']