sidebarpreviewmanager.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. var 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. fileId: model.get('id'),
  85. path: model.getFullPath(),
  86. mime: model.get('mimetype'),
  87. etag: model.get('etag'),
  88. y: isImage ? maxImageHeight : smallPreviewSize,
  89. x: isImage ? maxImageWidth : smallPreviewSize,
  90. a: isImage ? 1 : null,
  91. mode: isImage ? 'cover' : null,
  92. callback: function (previewUrl, img) {
  93. $thumbnailDiv.previewImg = previewUrl;
  94. // as long as we only have the mimetype icon, we only save it in case there is no preview
  95. if (!img) {
  96. return;
  97. }
  98. $thumbnailDiv.removeClass('icon-loading icon-32');
  99. var targetHeight = getTargetHeight(img);
  100. if (isImage && targetHeight > smallPreviewSize) {
  101. $thumbnailContainer.addClass((isLandscape(img) && !isSmall(img)) ? 'landscape' : 'portrait');
  102. $thumbnailContainer.addClass('large');
  103. }
  104. // only set background when we have an actual preview
  105. // when we don't have a preview we show the mime icon in the error handler
  106. $thumbnailDiv.css({
  107. 'background-image': 'url("' + previewUrl + '")',
  108. height: (targetHeight > smallPreviewSize) ? 'auto' : targetHeight,
  109. 'max-height': isSmall(img) ? targetHeight : null
  110. });
  111. var targetRatio = getTargetRatio(img);
  112. $thumbnailDiv.find('.stretcher').css({
  113. 'padding-bottom': (100 / targetRatio) + '%'
  114. });
  115. },
  116. error: function () {
  117. $thumbnailDiv.removeClass('icon-loading icon-32');
  118. $thumbnailContainer.removeClass('image'); //fall back to regular view
  119. $thumbnailDiv.css({
  120. 'background-image': 'url("' + $thumbnailDiv.previewImg + '")'
  121. });
  122. }
  123. });
  124. }
  125. };
  126. OCA.Files.SidebarPreviewManager = SidebarPreviewManager;
  127. })();