sidebarpreviewmanager.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 isLandscape = function (img) {
  58. return img.width > (img.height * 1.2);
  59. };
  60. var isSmall = function (img) {
  61. return (img.width * 1.1) < (maxImageWidth * window.devicePixelRatio);
  62. };
  63. var getTargetHeight = function (img) {
  64. var targetHeight = img.height / window.devicePixelRatio;
  65. if (targetHeight <= maxImageHeight) {
  66. targetHeight = maxImageHeight;
  67. }
  68. return targetHeight;
  69. };
  70. var getTargetRatio = function (img) {
  71. var ratio = img.width / img.height;
  72. if (ratio > 16 / 9) {
  73. return ratio;
  74. } else {
  75. return 16 / 9;
  76. }
  77. };
  78. this._fileList.lazyLoadPreview({
  79. fileId: model.get('id'),
  80. path: model.getFullPath(),
  81. mime: model.get('mimetype'),
  82. etag: model.get('etag'),
  83. y: maxImageHeight,
  84. x: maxImageWidth,
  85. a: 1,
  86. mode: 'cover',
  87. callback: function (previewUrl, img) {
  88. $thumbnailDiv.previewImg = previewUrl;
  89. // as long as we only have the mimetype icon, we only save it in case there is no preview
  90. if (!img) {
  91. return;
  92. }
  93. $thumbnailDiv.removeClass('icon-loading icon-32');
  94. var targetHeight = getTargetHeight(img);
  95. $thumbnailContainer.addClass((isLandscape(img) && !isSmall(img)) ? 'landscape' : 'portrait');
  96. $thumbnailContainer.addClass('large');
  97. // only set background when we have an actual preview
  98. // when we don't have a preview we show the mime icon in the error handler
  99. $thumbnailDiv.css({
  100. 'background-image': 'url("' + previewUrl + '")',
  101. height: (targetHeight > maxImageHeight) ? 'auto' : targetHeight,
  102. 'max-height': isSmall(img) ? targetHeight : null
  103. });
  104. var targetRatio = getTargetRatio(img);
  105. $thumbnailDiv.find('.stretcher').css({
  106. 'padding-bottom': (100 / targetRatio) + '%'
  107. });
  108. },
  109. error: function () {
  110. $thumbnailDiv.removeClass('icon-loading icon-32');
  111. $thumbnailContainer.removeClass('image'); //fall back to regular view
  112. $thumbnailDiv.css({
  113. 'background-image': 'url("' + $thumbnailDiv.previewImg + '")'
  114. });
  115. }
  116. });
  117. }
  118. };
  119. OCA.Files.SidebarPreviewManager = SidebarPreviewManager;
  120. })();