uiFilter.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. $(() => {
  2. const INPUT_CONTAINER_CLASSES = "col-12 col-xl-3 col-md-4 col-sm-6";
  3. function makeDoubleSlider(minValue, maxValue, serialize) {
  4. if (!serialize)
  5. serialize = i => i;
  6. let resultContainer = document.createElement("div");
  7. resultContainer.className = `slider-container ${INPUT_CONTAINER_CLASSES}`;
  8. let sliderDiv = document.createElement("div");
  9. sliderDiv.className = "container";
  10. resultContainer.appendChild(sliderDiv);
  11. let labelRow = document.createElement("div");
  12. labelRow.className = "row justify-content-between";
  13. let minValueLabel = document.createElement("div");
  14. minValueLabel.className = "slider-value slider-min-value";
  15. minValueLabel.textContent = serialize(minValue);
  16. labelRow.appendChild(minValueLabel);
  17. let maxValueLabel = document.createElement("div");
  18. maxValueLabel.className = "slider-value slider-max-value";
  19. maxValueLabel.textContent = serialize(maxValue);
  20. labelRow.appendChild(maxValueLabel);
  21. sliderDiv.appendChild(labelRow);
  22. let inputContainer = document.createElement("div");
  23. inputContainer.className = "container";
  24. sliderDiv.appendChild(inputContainer);
  25. let sliderCol = document.createElement("div");
  26. sliderCol.className = "col slider-col";
  27. inputContainer.appendChild(sliderCol);
  28. let input = document.createElement("input");
  29. input.type = "text";
  30. input.className = "col";
  31. input.dataset.sliderMin = minValue ?? 0;
  32. input.dataset.sliderMax = maxValue ?? 100;
  33. input.dataset.sliderValue = `[${input.dataset.sliderMin},${input.dataset.sliderMax}]`;
  34. input.dataset.sliderTooltip = "hide";
  35. sliderCol.appendChild(input);
  36. let jQueryInput = $(input);
  37. jQueryInput.slider();
  38. let onChange = () => {};
  39. jQueryInput.on('slideStop', evt => onChange({ min: evt.value[0], max: evt.value[1] }));
  40. jQueryInput.on('slide', evt => {
  41. minValueLabel.textContent = serialize(evt.value[0]);
  42. maxValueLabel.textContent = serialize(evt.value[1]);
  43. });
  44. return {
  45. container: resultContainer,
  46. minValueLabel: minValueLabel,
  47. maxValueLabel: maxValueLabel,
  48. input: jQueryInput,
  49. getInputValue: () => { const val = jQueryInput.slider('getValue'); return { min: val[0], max: val[1] }; },
  50. onChange: (fnc) => { onChange = fnc; }
  51. };
  52. }
  53. window.ReloadFilters = function(mediaManager) {
  54. let buildFilterBar = (labelText, canBeEmpty, possibleValues) => {
  55. let result = document.createElement("div");
  56. result.className = INPUT_CONTAINER_CLASSES;
  57. let label = document.createElement('label');
  58. result.appendChild(label);
  59. label.textContent = labelText;
  60. label.className = "container";
  61. let select = document.createElement('select');
  62. select.multiple = 'multiple';
  63. label.appendChild(select);
  64. let allPossibleValues = [].concat(canBeEmpty ? [undefined] : [], possibleValues);
  65. for (let i of allPossibleValues) {
  66. let opt = document.createElement("option");
  67. opt.textContent = i ? i : "(Empty)";
  68. opt.value = i ?? "";
  69. select.appendChild(opt);
  70. }
  71. $(select).change(e => {
  72. let val = Array.from(select.children).filter(i => i.selected).map(i => i.value === '' ? undefined : i.value);
  73. Array.from(select.parentNode.querySelectorAll(".dropdown-menu li .form-check")).forEach((inputGroup, i) => {
  74. let input = inputGroup.querySelector("input");
  75. input.previousStatus = input.previousStatus || 0;
  76. if ((input.previousStatus == 0 && !input.checked && !input.indeterminate) ||
  77. (input.previousStatus == 1 && input.checked && !input.indeterminate) ||
  78. (input.previousStatus == 2 && input.checked && input.indeterminate))
  79. return;
  80. if (input.previousStatus == 0) {
  81. input.checked = true;
  82. input.indeterminate = false;
  83. input.previousStatus = 1;
  84. }
  85. else if (input.previousStatus == 1) {
  86. input.checked = true;
  87. input.indeterminate = true;
  88. input.previousStatus = 2;
  89. } else {
  90. input.checked = false;
  91. input.indeterminate = false;
  92. input.previousStatus = 0;
  93. }
  94. select.querySelectorAll("option")[i].selected = input.checked ? "selected" : "";
  95. console.log(select.querySelectorAll("option")[i]);
  96. $(select).bsMultiSelect("UpdateAppearance");
  97. });
  98. window.FilterManager.setFilterValue(labelText, val);
  99. });
  100. $(select).bsMultiSelect({cssPatch: {
  101. picks: { backgroundColor: 'inherit' },
  102. pick: { color: 'var(--bs-body-color)' },
  103. choiceContent: { color: 'var(--bs-body-color)' }
  104. }});
  105. return {
  106. content: result
  107. };
  108. };
  109. let container = document.getElementById('pch-filterbar');
  110. container.textContent = '';
  111. if (MediaStorage.Instance.isLoading())
  112. return;
  113. for (let i of Object.keys(mediaManager.allMetaTypes).filter(i => mediaManager.allMetaTypes[i].type === 'string' ||
  114. [].indexOf(i) >= 0)) {
  115. let filterUi = buildFilterBar(i, mediaManager.allMetaTypes[i].canBeEmpty, Array.from(mediaManager.allMeta[i]).sort());
  116. container.appendChild(filterUi.content);
  117. }
  118. let filterUi = buildFilterBar("Tags", true, Array.from(mediaManager.allTags).sort());
  119. container.appendChild(filterUi.content);
  120. if (window.chronology.isInitialized()) {
  121. let range = window.chronology.getRange();
  122. let timeSlider = makeDoubleSlider(range.min.getTime(), range.max.getTime(), i => (new Date(i)).toLocaleDateString());
  123. timeSlider.onChange(val => window.FilterManager.setChronologyRange(val.min, val.max));
  124. container.appendChild(timeSlider.container);
  125. }
  126. }
  127. document.getElementById('pch-navbar-filterToggle').addEventListener('click', e => {
  128. e.preventDefault();
  129. let filterBarDom = document.getElementById('pch-filterbarContainer');
  130. if (filterBarDom.style.display)
  131. filterBarDom.style.display = "";
  132. else
  133. filterBarDom.style.display = "flex"
  134. });
  135. document.onClosePopinRequested(() => {
  136. document.getElementById('pch-filterbarContainer').style.display = "";
  137. });
  138. });