diff --git a/apps/files/js/mainfileinfodetailview.js b/apps/files/js/mainfileinfodetailview.js index c586135b9c..30b2b531df 100644 --- a/apps/files/js/mainfileinfodetailview.js +++ b/apps/files/js/mainfileinfodetailview.js @@ -57,6 +57,11 @@ */ _fileActions: null, + /** + * @type {OCA.Files.SidebarPreviewManager} + */ + _previewManager: null, + events: { 'click a.action-favorite': '_onClickFavorite', 'click a.action-default': '_onClickDefaultAction', @@ -81,6 +86,7 @@ if (!this._fileActions) { throw 'Missing required parameter "fileActions"'; } + this._previewManager = new OCA.Files.SidebarPreviewManager(this._fileList); }, _onClickPermalink: function() { @@ -158,7 +164,7 @@ var $container = this.$el.find('.thumbnailContainer'); if (!this.model.isDirectory()) { $iconDiv.addClass('icon-loading icon-32'); - this.loadPreview(this.model.getFullPath(), this.model.get('mimetype'), this.model.get('etag'), $iconDiv, $container, this.model.isImage()); + this._previewManager.loadPreview(this.model, $iconDiv, $container); } else { var iconUrl = this.model.get('icon') || OC.MimeType.getIconUrl('dir'); $iconDiv.css('background-image', 'url("' + iconUrl + '")'); @@ -169,86 +175,6 @@ this.$el.empty(); } this.delegateEvents(); - }, - - loadPreview: function(path, mime, etag, $iconDiv, $container, isImage) { - var maxImageWidth = $container.parent().width() + 50; // 50px for negative margins - var maxImageHeight = maxImageWidth / (16/9); - var smallPreviewSize = 75; - - var isLandscape = function(img) { - return img.width > (img.height * 1.2); - }; - - var isSmall = function(img) { - return (img.width * 1.1) < (maxImageWidth * window.devicePixelRatio); - }; - - var getTargetHeight = function(img) { - if(isImage) { - var targetHeight = img.height / window.devicePixelRatio; - if (targetHeight <= smallPreviewSize) { - targetHeight = smallPreviewSize; - } - return targetHeight; - }else{ - return smallPreviewSize; - } - }; - - var getTargetRatio = function(img){ - var ratio = img.width / img.height; - if (ratio > 16/9) { - return ratio; - } else { - return 16/9; - } - }; - - this._fileList.lazyLoadPreview({ - path: path, - mime: mime, - etag: etag, - y: isImage ? maxImageHeight : smallPreviewSize, - x: isImage ? maxImageWidth : smallPreviewSize, - a: isImage ? 1 : null, - mode: isImage ? 'cover' : null, - callback: function (previewUrl, img) { - $iconDiv.previewImg = previewUrl; - - // as long as we only have the mimetype icon, we only save it in case there is no preview - if (!img) { - return; - } - $iconDiv.removeClass('icon-loading icon-32'); - var targetHeight = getTargetHeight(img); - if (this.model.isImage() && targetHeight > smallPreviewSize) { - $container.addClass((isLandscape(img) && !isSmall(img))? 'landscape': 'portrait'); - $container.addClass('image'); - } - - // only set background when we have an actual preview - // when we don't have a preview we show the mime icon in the error handler - $iconDiv.css({ - 'background-image': 'url("' + previewUrl + '")', - height: (targetHeight > smallPreviewSize)? 'auto': targetHeight, - 'max-height': isSmall(img)? targetHeight: null - }); - - var targetRatio = getTargetRatio(img); - $iconDiv.find('.stretcher').css({ - 'padding-bottom': (100 / targetRatio) + '%' - }); - }.bind(this), - error: function () { - $iconDiv.removeClass('icon-loading icon-32'); - this.$el.find('.thumbnailContainer').removeClass('image'); //fall back to regular view - $iconDiv.css({ - 'background-image': 'url("' + $iconDiv.previewImg + '")' - }); - OC.Util.scaleFixForIE8($iconDiv); - }.bind(this) - }); } }); diff --git a/apps/files/js/sidebarpreviewmanager.js b/apps/files/js/sidebarpreviewmanager.js new file mode 100644 index 0000000000..5b7906bbb9 --- /dev/null +++ b/apps/files/js/sidebarpreviewmanager.js @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +(function () { + SidebarPreviewManager = function (fileList) { + this._fileList = fileList; + }; + + SidebarPreviewManager.prototype = { + loadPreview: function (model, $thumbnailDiv, $thumbnailContainer) { + // todo allow plugins to register custom handlers by mimetype + this.fallbackPreview(model, $thumbnailDiv, $thumbnailContainer); + }, + + // previews for images and mimetype icons + fallbackPreview: function (model, $thumbnailDiv, $thumbnailContainer) { + var isImage = model.isImage(); + var maxImageWidth = $thumbnailContainer.parent().width() + 50; // 50px for negative margins + var maxImageHeight = maxImageWidth / (16 / 9); + var smallPreviewSize = 75; + + var isLandscape = function (img) { + return img.width > (img.height * 1.2); + }; + + var isSmall = function (img) { + return (img.width * 1.1) < (maxImageWidth * window.devicePixelRatio); + }; + + var getTargetHeight = function (img) { + if (isImage) { + var targetHeight = img.height / window.devicePixelRatio; + if (targetHeight <= smallPreviewSize) { + targetHeight = smallPreviewSize; + } + return targetHeight; + } else { + return smallPreviewSize; + } + }; + + var getTargetRatio = function (img) { + var ratio = img.width / img.height; + if (ratio > 16 / 9) { + return ratio; + } else { + return 16 / 9; + } + }; + + this._fileList.lazyLoadPreview({ + path: model.getFullPath(), + mime: model.get('mimetype'), + etag: model.get('etag'), + y: isImage ? maxImageHeight : smallPreviewSize, + x: isImage ? maxImageWidth : smallPreviewSize, + a: isImage ? 1 : null, + mode: isImage ? 'cover' : null, + callback: function (previewUrl, img) { + $thumbnailDiv.previewImg = previewUrl; + + // as long as we only have the mimetype icon, we only save it in case there is no preview + if (!img) { + return; + } + $thumbnailDiv.removeClass('icon-loading icon-32'); + var targetHeight = getTargetHeight(img); + if (isImage && targetHeight > smallPreviewSize) { + $thumbnailContainer.addClass((isLandscape(img) && !isSmall(img)) ? 'landscape' : 'portrait'); + $thumbnailContainer.addClass('image'); + } + + // only set background when we have an actual preview + // when we don't have a preview we show the mime icon in the error handler + $thumbnailDiv.css({ + 'background-image': 'url("' + previewUrl + '")', + height: (targetHeight > smallPreviewSize) ? 'auto' : targetHeight, + 'max-height': isSmall(img) ? targetHeight : null + }); + + var targetRatio = getTargetRatio(img); + $thumbnailDiv.find('.stretcher').css({ + 'padding-bottom': (100 / targetRatio) + '%' + }); + }, + error: function () { + $thumbnailDiv.removeClass('icon-loading icon-32'); + $thumbnailContainer.removeClass('image'); //fall back to regular view + $thumbnailDiv.css({ + 'background-image': 'url("' + $thumbnailDiv.previewImg + '")' + }); + } + }); + } + }; + + OCA.Files.SidebarPreviewManager = SidebarPreviewManager; +})(); diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php index 18b6cf719c..ffa566f4e9 100644 --- a/apps/files/lib/Controller/ViewController.php +++ b/apps/files/lib/Controller/ViewController.php @@ -174,6 +174,7 @@ class ViewController extends Controller { \OCP\Util::addScript('files', 'favoritesplugin'); \OCP\Util::addScript('files', 'detailfileinfoview'); + \OCP\Util::addScript('files', 'sidebarpreviewmanager'); \OCP\Util::addScript('files', 'detailtabview'); \OCP\Util::addScript('files', 'mainfileinfodetailview'); \OCP\Util::addScript('files', 'detailsview');