Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions apps/files/css/detailsView.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@
float: left;
}

#app-sidebar .thumbnailContainer.image {
#app-sidebar .thumbnailContainer.large {
margin-left: -15px;
margin-right: -35px; /* 15 + 20 for the close button */
margin-top: -15px;
}

#app-sidebar .thumbnailContainer.image.portrait {
#app-sidebar .thumbnailContainer.large.portrait {
margin: 0; /* if we don't fit the image anyway we give it back the margin */
}

#app-sidebar .image .thumbnail {
#app-sidebar .large .thumbnail {
width:100%;
display:block;
background-repeat: no-repeat;
Expand All @@ -53,20 +53,28 @@
height: auto;
}

#app-sidebar .image .thumbnail .stretcher {
#app-sidebar .large .thumbnail .stretcher {
content: '';
display: block;
padding-bottom: 56.25%; /* sets height of .thumbnail to 9/16 of the width */
}

#app-sidebar .image.portrait .thumbnail {
#app-sidebar .large.portrait .thumbnail {
background-position: 50% top;
}

#app-sidebar .image.portrait .thumbnail {
#app-sidebar .large.portrait .thumbnail {
background-size: contain;
}

#app-sidebar .large.text {
overflow-y: scroll;
overflow-x: hidden;
padding-top: 15px;
font-size: 80%;
margin-left: 0;
}

#app-sidebar .thumbnail {
width: 75px;
height: 75px;
Expand Down
88 changes: 7 additions & 81 deletions apps/files/js/mainfileinfodetailview.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
*/
_fileActions: null,

/**
* @type {OCA.Files.SidebarPreviewManager}
*/
_previewManager: null,

events: {
'click a.action-favorite': '_onClickFavorite',
'click a.action-default': '_onClickDefaultAction',
Expand All @@ -81,6 +86,7 @@
if (!this._fileActions) {
throw 'Missing required parameter "fileActions"';
}
this._previewManager = new OCA.Files.SidebarPreviewManager(this._fileList);
},

_onClickPermalink: function() {
Expand Down Expand Up @@ -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 + '")');
Expand All @@ -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)
});
}
});

Expand Down
123 changes: 123 additions & 0 deletions apps/files/js/sidebarpreviewmanager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2016
*
* 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;
this._previewHandlers = {};
OC.Plugins.attach('OCA.Files.SidebarPreviewManager', this);
};

SidebarPreviewManager.prototype = {
addPreviewHandler: function (mime, handler) {
this._previewHandlers[mime] = handler;
},

getPreviewHandler: function (mime) {
var mimePart = mime.split('/').shift();
if (this._previewHandlers[mime]) {
return this._previewHandlers[mime];
} else if(this._previewHandlers[mimePart]) {
return this._previewHandlers[mimePart];
} else {
return this.fallbackPreview.bind(this);
}
},

loadPreview: function (model, $thumbnailDiv, $thumbnailContainer) {
var handler = this.getPreviewHandler(model.get('mimetype'));
var fallback = this.fallbackPreview.bind(this, model, $thumbnailDiv, $thumbnailContainer);
handler(model, $thumbnailDiv, $thumbnailContainer, fallback);
},

// 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('large');
}

// 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;
})();
47 changes: 47 additions & 0 deletions apps/files/js/sidebarpreviewtext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2016
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

(function () {
var SidebarPreview = function () {
};

SidebarPreview.prototype = {
attach: function (manager) {
manager.addPreviewHandler('text', this.handlePreview.bind(this));
},

handlePreview: function (model, $thumbnailDiv, $thumbnailContainer, fallback) {
console.log(model);
var previewWidth = $thumbnailContainer.parent().width() + 50; // 50px for negative margins
var previewHeight = previewWidth / (16 / 9);

this.getFileContent(model.getFullPath()).then(function (content) {
$thumbnailDiv.removeClass('icon-loading icon-32');
$thumbnailContainer.addClass('large');
$thumbnailContainer.addClass('text');
var $textPreview = $('<pre/>').text(content);
$thumbnailDiv.children('.stretcher').remove();
$thumbnailDiv.append($textPreview);
$thumbnailContainer.css("max-height", previewHeight);
}, function () {
fallback();
});
},

getFileContent: function (path) {
console.log(path);
var url = OC.linkToRemoteBase('files' + path);
console.log(url);
return $.get(url);
}
};

OC.Plugins.register('OCA.Files.SidebarPreviewManager', new SidebarPreview());
})();
2 changes: 2 additions & 0 deletions apps/files/lib/Controller/ViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ public function index($dir = '', $view = '', $fileid = null) {
\OCP\Util::addScript('files', 'favoritesplugin');

\OCP\Util::addScript('files', 'detailfileinfoview');
\OCP\Util::addScript('files', 'sidebarpreviewmanager');
\OCP\Util::addScript('files', 'sidebarpreviewtext');
\OCP\Util::addScript('files', 'detailtabview');
\OCP\Util::addScript('files', 'mainfileinfodetailview');
\OCP\Util::addScript('files', 'detailsview');
Expand Down