sidebarpreviewmanager.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c) 2016
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. (function () {
  11. SidebarPreviewManager = function (fileList) {
  12. this._fileList = fileList;
  13. this._previewHandlers = {};
  14. OC.Plugins.attach('OCA.Files.SidebarPreviewManager', this);
  15. };
  16. SidebarPreviewManager.prototype = {
  17. addPreviewHandler: function (mime, handler) {
  18. this._previewHandlers[mime] = handler;
  19. },
  20. getMimeTypePreviewHandler: function(mime) {
  21. var mimePart = mime.split('/').shift();
  22. if (this._previewHandlers[mime]) {
  23. return this._previewHandlers[mime];
  24. } else if (this._previewHandlers[mimePart]) {
  25. return this._previewHandlers[mimePart];
  26. } else {
  27. return null;
  28. }
  29. },
  30. getPreviewHandler: function (mime) {
  31. var mimetypeHandler = this.getMimeTypePreviewHandler(mime);
  32. if (mimetypeHandler) {
  33. return mimetypeHandler;
  34. } else {
  35. return this.fallbackPreview.bind(this);
  36. }
  37. },
  38. loadPreview: function (model, $thumbnailDiv, $thumbnailContainer) {
  39. if (model.get('hasPreview') === false && this.getMimeTypePreviewHandler(model.get('mimetype')) === null) {
  40. var mimeIcon = OC.MimeType.getIconUrl(model.get('mimetype'));
  41. $thumbnailDiv.removeClass('icon-loading icon-32');
  42. $thumbnailContainer.removeClass('image'); //fall back to regular view
  43. $thumbnailDiv.css({
  44. 'background-image': 'url("' + mimeIcon + '")'
  45. });
  46. } else {
  47. var handler = this.getPreviewHandler(model.get('mimetype'));
  48. var fallback = this.fallbackPreview.bind(this, model, $thumbnailDiv, $thumbnailContainer);
  49. handler(model, $thumbnailDiv, $thumbnailContainer, fallback);
  50. }
  51. },
  52. // previews for images and mimetype icons
  53. fallbackPreview: function (model, $thumbnailDiv, $thumbnailContainer) {
  54. var isImage = model.isImage();
  55. var maxImageWidth = $thumbnailContainer.parent().width() + 50; // 50px for negative margins
  56. var maxImageHeight = maxImageWidth / (16 / 9);
  57. var smallPreviewSize = 75;
  58. var isLandscape = function (img) {
  59. return img.width > (img.height * 1.2);
  60. };
  61. var isSmall = function (img) {
  62. return (img.width * 1.1) < (maxImageWidth * window.devicePixelRatio);
  63. };
  64. var getTargetHeight = function (img) {
  65. if (isImage) {
  66. var targetHeight = img.height / window.devicePixelRatio;
  67. if (targetHeight <= smallPreviewSize) {
  68. targetHeight = smallPreviewSize;
  69. }
  70. return targetHeight;
  71. } else {
  72. return smallPreviewSize;
  73. }
  74. };
  75. var getTargetRatio = function (img) {
  76. var ratio = img.width / img.height;
  77. if (ratio > 16 / 9) {
  78. return ratio;
  79. } else {
  80. return 16 / 9;
  81. }
  82. };
  83. this._fileList.lazyLoadPreview({
  84. path: model.getFullPath(),
  85. mime: model.get('mimetype'),
  86. etag: model.get('etag'),
  87. y: isImage ? maxImageHeight : smallPreviewSize,
  88. x: isImage ? maxImageWidth : smallPreviewSize,
  89. a: isImage ? 1 : null,
  90. mode: isImage ? 'cover' : null,
  91. callback: function (previewUrl, img) {
  92. $thumbnailDiv.previewImg = previewUrl;
  93. // as long as we only have the mimetype icon, we only save it in case there is no preview
  94. if (!img) {
  95. return;
  96. }
  97. $thumbnailDiv.removeClass('icon-loading icon-32');
  98. var targetHeight = getTargetHeight(img);
  99. if (isImage && targetHeight > smallPreviewSize) {
  100. $thumbnailContainer.addClass((isLandscape(img) && !isSmall(img)) ? 'landscape' : 'portrait');
  101. $thumbnailContainer.addClass('large');
  102. }
  103. // only set background when we have an actual preview
  104. // when we don't have a preview we show the mime icon in the error handler
  105. $thumbnailDiv.css({
  106. 'background-image': 'url("' + previewUrl + '")',
  107. height: (targetHeight > smallPreviewSize) ? 'auto' : targetHeight,
  108. 'max-height': isSmall(img) ? targetHeight : null
  109. });
  110. var targetRatio = getTargetRatio(img);
  111. $thumbnailDiv.find('.stretcher').css({
  112. 'padding-bottom': (100 / targetRatio) + '%'
  113. });
  114. },
  115. error: function () {
  116. $thumbnailDiv.removeClass('icon-loading icon-32');
  117. $thumbnailContainer.removeClass('image'); //fall back to regular view
  118. $thumbnailDiv.css({
  119. 'background-image': 'url("' + $thumbnailDiv.previewImg + '")'
  120. });
  121. }
  122. });
  123. }
  124. };
  125. OCA.Files.SidebarPreviewManager = SidebarPreviewManager;
  126. })();