index.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import $ from 'jquery';
  2. import { config, uri_params } from 'grav-config';
  3. import request from '../utils/request';
  4. export default class Filter {
  5. constructor() {
  6. this.URI = `${config.base_url_relative}/media-manager/`;
  7. }
  8. filter(name, value) {
  9. let filtered = [];
  10. let keys = Object.keys(uri_params);
  11. if (!~keys.indexOf(name)) { keys.push(name); }
  12. keys.forEach((key) => {
  13. let filter = Filter.cleanValue(key === name ? value : uri_params[key]);
  14. if (filter !== '*') {
  15. filtered.push(`${key}${config.param_sep}${filter}`);
  16. }
  17. });
  18. global.location = this.URI + filtered.join('/');
  19. }
  20. static cleanValue(value) {
  21. return encodeURIComponent(value.replace('/', '\\'));
  22. }
  23. }
  24. export let Instance = new Filter();
  25. var isLoading = false;
  26. var filters = {};
  27. var global_index = 1;
  28. var files_ended = false;
  29. const MEDIA_PAGINATION_INTERVAL = 20;
  30. /* handle changing file type / date filter */
  31. $('body').on('change', '.thumbs-list-container select.filter', (event) => {
  32. let target = $(event.currentTarget);
  33. let filterName = target.data('name');
  34. let filterValue = target.val();
  35. if (filterValue) {
  36. filters[filterName] = filterValue;
  37. } else {
  38. delete filters[filterName];
  39. }
  40. filterFiles();
  41. });
  42. /* initialize media uploader */
  43. if ($('.thumbs-list-container .dropzone')[0]) {
  44. $('.thumbs-list-container .dropzone')[0].dropzone.on('queuecomplete', function() {
  45. let body = {};
  46. if (filters.page) { body.page = filters.page; }
  47. if (filters.date) { body.date = filters.date; }
  48. if (filters.type) { body.type = filters.type; }
  49. $('.dropzone')[0].dropzone.files.forEach(function(file) { file.previewElement.remove(); });
  50. $('.dropzone').first().removeClass('dz-started');
  51. request(config.base_url_relative + '/media-manager.json/task:clearMediaCache', { method: 'post', body }, () => {
  52. filterFiles();
  53. });
  54. });
  55. }
  56. /* handle loading media */
  57. var loadMedia = function loadMedia(filters, callback) {
  58. var url = config.base_url_relative + '/media.json/tmpl:media-list-content/index:' + global_index;
  59. if (filters.page) {
  60. url += '/page:' + (filters.page).split('/').join('%5C');
  61. }
  62. if (filters.type && filters.type !== '*') {
  63. url += '/type:' + filters.type;
  64. }
  65. if (filters.date && filters.date !== '*') {
  66. url += '/date:' + filters.date;
  67. }
  68. if (!isLoading) {
  69. isLoading = true;
  70. $('.spinning-wheel').show();
  71. $.get(url, function(content) {
  72. $('.js__files').append(content);
  73. $('.spinning-wheel').hide();
  74. $('.media-container .media-range').trigger('change');
  75. isLoading = false;
  76. global_index++;
  77. callback(content);
  78. });
  79. }
  80. };
  81. var cleanFilesList = function cleanFilesList() {
  82. $('.js__files .card-item').remove();
  83. };
  84. var resetActiveStateInSidebar = function resetActiveStateInSidebar() {
  85. $('.pages-list-container .row').removeClass('active'); // clear active state in sidebar
  86. };
  87. var showEmptyState = function showEmptyState() {
  88. $('.thumbs-list-container').append('<p class="card-item empty-space">No media found</p>');
  89. };
  90. var filterFiles = function filterFiles() {
  91. cleanFilesList();
  92. global_index = 0;
  93. files_ended = false;
  94. $('.empty-space').remove();
  95. loadMedia(filters, function(content) {
  96. if (!content.trim().length) {
  97. showEmptyState();
  98. } else {
  99. if (!filters.page && (!filters.date || filters.date === '*') && (!filters.type || filters.type === '*')) {
  100. $('.js__files').trigger('fillView');
  101. }
  102. }
  103. });
  104. };
  105. /* handle changing page */
  106. $('body').on('click', '.pages-list-container .js__page-link', (event) => {
  107. var page = $(event.target).data('page');
  108. filters['page'] = page;
  109. $('.media-list-title .page-indicator').html(page); // set indication
  110. $('.js__reset-pages-filter').removeClass('hidden'); // activate reset pages icon
  111. resetActiveStateInSidebar();
  112. $(event.target).parents('.row').addClass('active'); // set active state in sidebar
  113. $('.js__file-uploader').removeClass('hidden');
  114. // customize processing URL, as the page changes dynamically
  115. if ($('.dropzone')[0]) {
  116. $('.dropzone')[0].dropzone.on('processing', function(file) {
  117. this.options.url = `${config.base_url_relative}/media-manager${page}.json/task${config.param_sep}addmedia`;
  118. });
  119. }
  120. $('.js__button-clear-media-cache').addClass('hidden');
  121. filterFiles();
  122. disableInfiniteScrolling(); // only infinite scroll on main list, not inside single pages
  123. });
  124. /* handle clearing page filter */
  125. $('body').on('click', '.js__reset-pages-filter', (event) => {
  126. $('.media-list-title .page-indicator').html('All Pages'); // set indication
  127. cleanFilesList();
  128. resetActiveStateInSidebar();
  129. $('.js__reset-pages-filter').addClass('hidden'); // remove reset pages icon
  130. $('.js__file-uploader').addClass('hidden');
  131. $('.js__button-clear-media-cache').removeClass('hidden');
  132. delete filters['page'];
  133. filterFiles();
  134. });
  135. /* handle infinite loading */
  136. var enableInfiniteScrolling = function enableInfiniteScrolling() {
  137. $('.spinning-wheel').hide();
  138. var view = $('.mediapicker-scroll').last();
  139. var gemini = view.data('scrollbar');
  140. if (gemini) {
  141. gemini = gemini.getViewElement();
  142. }
  143. if (!gemini || !gemini.length && !view.length) { return; }
  144. $(gemini || view).on('scroll', function() {
  145. if (($(this).scrollTop() + $(this).innerHeight() + 100) >= $(this)[0].scrollHeight) {
  146. fillView();
  147. }
  148. });
  149. };
  150. var loadNextBatch = function loadNextBatch(callback) {
  151. if (files_ended) {
  152. return;
  153. }
  154. loadMedia({}, function(content) {
  155. if (!$(content).length || ((content.split('card-item').length - 1) < MEDIA_PAGINATION_INTERVAL)) {
  156. files_ended = true;
  157. } else {
  158. if (callback) {
  159. callback();
  160. }
  161. }
  162. $('.media-container .media-range').trigger('input');
  163. });
  164. };
  165. var fillView = function fillView() {
  166. if (!$('.js__files').find('.card-item').last().offset()) {
  167. setTimeout(function() {
  168. // retry later
  169. fillView();
  170. }, 300);
  171. return;
  172. }
  173. if ($('.js__files').find('.card-item').last().offset().top - 1 <= $('.media-container').height()) {
  174. loadNextBatch(function() {
  175. fillView();
  176. });
  177. }
  178. };
  179. /* disable infinite loading */
  180. var disableInfiniteScrolling = function disableInfiniteScrolling() {
  181. $('.spinning-wheel').hide();
  182. $('.content-wrapper').unbind('scroll');
  183. };
  184. $('.js__files').on('fillView', function(event) {
  185. // the first batch got the max number of media files, try loading more
  186. if (($('.js__files')[0].innerHTML.split('card-item').length - 1) === MEDIA_PAGINATION_INTERVAL) {
  187. fillView();
  188. enableInfiniteScrolling();
  189. }
  190. });