2016-07-04 13:02:07 +03:00
|
|
|
/*
|
2016-07-04 13:54:12 +03:00
|
|
|
* Copyright (c) 2016
|
2016-07-04 13:02:07 +03:00
|
|
|
*
|
|
|
|
* 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;
|
2016-07-04 13:54:12 +03:00
|
|
|
this._previewHandlers = {};
|
|
|
|
OC.Plugins.attach('OCA.Files.SidebarPreviewManager', this);
|
2016-07-04 13:02:07 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
SidebarPreviewManager.prototype = {
|
2016-07-04 13:54:12 +03:00
|
|
|
addPreviewHandler: function (mime, handler) {
|
|
|
|
this._previewHandlers[mime] = handler;
|
|
|
|
},
|
|
|
|
|
2016-12-01 17:00:51 +03:00
|
|
|
getMimeTypePreviewHandler: function(mime) {
|
2016-07-04 13:54:12 +03:00
|
|
|
var mimePart = mime.split('/').shift();
|
|
|
|
if (this._previewHandlers[mime]) {
|
|
|
|
return this._previewHandlers[mime];
|
2016-12-01 17:00:51 +03:00
|
|
|
} else if (this._previewHandlers[mimePart]) {
|
2016-07-04 13:54:12 +03:00
|
|
|
return this._previewHandlers[mimePart];
|
2016-12-01 17:00:51 +03:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
getPreviewHandler: function (mime) {
|
|
|
|
var mimetypeHandler = this.getMimeTypePreviewHandler(mime);
|
|
|
|
if (mimetypeHandler) {
|
|
|
|
return mimetypeHandler;
|
2016-07-04 13:54:12 +03:00
|
|
|
} else {
|
|
|
|
return this.fallbackPreview.bind(this);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-07-04 13:02:07 +03:00
|
|
|
loadPreview: function (model, $thumbnailDiv, $thumbnailContainer) {
|
2016-12-01 17:00:51 +03:00
|
|
|
if (model.get('hasPreview') === false && this.getMimeTypePreviewHandler(model.get('mimetype')) === null) {
|
2016-07-26 14:51:18 +03:00
|
|
|
var mimeIcon = OC.MimeType.getIconUrl(model.get('mimetype'));
|
|
|
|
$thumbnailDiv.removeClass('icon-loading icon-32');
|
|
|
|
$thumbnailContainer.removeClass('image'); //fall back to regular view
|
|
|
|
$thumbnailDiv.css({
|
|
|
|
'background-image': 'url("' + mimeIcon + '")'
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
var handler = this.getPreviewHandler(model.get('mimetype'));
|
|
|
|
var fallback = this.fallbackPreview.bind(this, model, $thumbnailDiv, $thumbnailContainer);
|
|
|
|
handler(model, $thumbnailDiv, $thumbnailContainer, fallback);
|
|
|
|
}
|
2016-07-04 13:02:07 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// 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');
|
2016-07-04 13:54:12 +03:00
|
|
|
$thumbnailContainer.addClass('large');
|
2016-07-04 13:02:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
})();
|